LCOV - code coverage report
Current view: top level - index/query - FieldBundle.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 14 15 93.3 %
Date: 2022-11-19 15:00:39 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2017 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.index.query;
      16             : 
      17             : import static com.google.common.base.Preconditions.checkArgument;
      18             : 
      19             : import com.google.common.collect.ImmutableList;
      20             : import com.google.common.collect.ImmutableListMultimap;
      21             : import com.google.common.collect.Iterables;
      22             : import com.google.common.collect.ListMultimap;
      23             : import com.google.gerrit.index.IndexedField;
      24             : import com.google.gerrit.index.IndexedField.SearchSpec;
      25             : import com.google.gerrit.index.SchemaFieldDefs.SchemaField;
      26             : 
      27             : /** FieldBundle is an abstraction that allows retrieval of raw values from different sources. */
      28             : public class FieldBundle {
      29             : 
      30             :   // Map String => List{Integer, Long, Timestamp, String, byte[]}
      31             :   private ImmutableListMultimap<String, Object> fields;
      32             : 
      33             :   /**
      34             :    * Depending on the index implementation 1) either {@link IndexedField} are stored once and
      35             :    * referenced by {@link com.google.gerrit.index.IndexedField.SearchSpec} on the queries, 2) or
      36             :    * each {@link com.google.gerrit.index.IndexedField.SearchSpec} is stored individually.
      37             :    *
      38             :    * <p>In case #1 {@link #storesIndexedFields} is set to {@code true} and the {@link #fields}
      39             :    * contain a map from {@link IndexedField#name()} to a stored value.
      40             :    *
      41             :    * <p>In case #2 {@link #storesIndexedFields} is set to {@code false} and the {@link #fields}
      42             :    * contain a map from {@link SearchSpec#name()} to a stored value.
      43             :    */
      44             :   private final boolean storesIndexedFields;
      45             : 
      46           8 :   public FieldBundle(ListMultimap<String, Object> fields, boolean storesIndexedFields) {
      47           8 :     this.fields = ImmutableListMultimap.copyOf(fields);
      48           8 :     this.storesIndexedFields = storesIndexedFields;
      49           8 :   }
      50             : 
      51             :   /**
      52             :    * Get a field's value based on the field definition.
      53             :    *
      54             :    * @param schemaField the definition of the field of which the value should be retrieved. The
      55             :    *     field must be stored and contained in the result set as specified by {@link
      56             :    *     com.google.gerrit.index.QueryOptions}.
      57             :    * @param <T> Data type of the returned object based on the field definition
      58             :    * @return Either a single element or an Iterable based on the field definition. An empty list is
      59             :    *     returned for repeated fields that are not contained in the result.
      60             :    * @throws IllegalArgumentException if the requested field is not stored or not present. This
      61             :    *     check is only enforced on non-repeatable fields.
      62             :    */
      63             :   @SuppressWarnings("unchecked")
      64             :   public <T> T getValue(SchemaField<?, T> schemaField) {
      65           8 :     checkArgument(schemaField.isStored(), "Field must be stored");
      66             :     String storedFieldName =
      67           8 :         storesIndexedFields && schemaField instanceof IndexedField<?, ?>.SearchSpec
      68           0 :             ? ((IndexedField<?, ?>.SearchSpec) schemaField).getField().name()
      69           8 :             : schemaField.getName();
      70           8 :     checkArgument(
      71           8 :         fields.containsKey(storedFieldName) || schemaField.isRepeatable(),
      72             :         "Field %s is not in result set %s",
      73             :         storedFieldName,
      74           8 :         fields.keySet());
      75             : 
      76           8 :     ImmutableList<Object> result = fields.get(storedFieldName);
      77           8 :     if (schemaField.isRepeatable()) {
      78           4 :       return (T) result;
      79             :     }
      80           6 :     return (T) Iterables.getOnlyElement(result);
      81             :   }
      82             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750