text:
package org.apache.pinot.core.query.aggregation.groupby;

import com.google.common.annotations.VisibleForTesting;
import it.unimi.dsi.fastutil.HashCommon;
import it.unimi.dsi.fastutil.longs.Long2IntMap;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.Arrays;
import java.util.Iterator;
import org.apache.pinot.core.common.BlockValSet;
import org.apache.pinot.core.operator.blocks.TransformBlock;
import org.apache.pinot.core.operator.transform.TransformOperator;
import org.apache.pinot.core.query.request.context.ExpressionContext;
import org.apache.pinot.core.segment.index.readers.Dictionary;

/**
 * Class for generating group keys (groupId-stringKey pair) for a given list of dictionary encoded group-by columns.
 *
The maximum number of possible group keys is the cardinality product of all the group-by columns.
 *
The raw key is generated from the dictionary ids of the group-by columns.
 *

 *

 *     If the maximum number of possible group keys is less than a threshold (10K), directly use the raw key as the
 *     group id. (ARRAY_BASED)
 *

 *

 *     If the maximum number of possible group keys is larger than the threshold, but still fit into integer, generate
 *     integer raw keys and map them onto contiguous group ids. (INT_MAP_BASED)
 *

 *

 *     If the maximum number of possible group keys cannot fit into than integer, but still fit into long, generate long
 *     raw keys and map them onto contiguous group ids. (LONG_MAP_BASED)
 *

 *

 *     If the maximum number of possible group keys cannot fit into long, use int arrays as the raw keys to store the
 *     dictionary ids of all the group-by columns and map them onto contiguous group ids. (ARRAY_MAP_BASED)
 *

 *

 *
All the logic is maintained internally, and to the outside world, the group ids are always int type, and are
 * bounded by the number of groups limit (globalGroupIdUpperBound is always smaller or equal to numGroupsLimit).
 */
public class DictionaryBasedGroupKeyGenerator implements GroupKeyGenerator {
  // NOTE: map size = map capacity (power of 2) * load factor
  private static final int INITIAL_MAP_SIZE = (int) ((1 << 9) * 0.75f);
  private static final int MAX_CACHING_MAP_SIZE = (int) ((1 << 20) * 0.75f);

  private static final ThreadLocal<IntGroupIdMap> THREAD_LOCAL_INT_MAP = ThreadLocal.withInitial(IntGroupIdMap::new);
  private static final ThreadLocal<Long2IntOpenHashMap> THREAD_LOCAL_LONG_MAP =
      ThreadLocal.withInitial(() -> new Long2IntOpenHashMap(INITIAL_MAP_SIZE));
  private static final ThreadLocal<Object2IntOpenHashMap<IntArray>> THREAD_LOCAL_INT_ARRAY_MAP =
      ThreadLocal.withInitial(() -> new Object2IntOpenHashMap<>(INITIAL_MAP_SIZE));

  private final ExpressionContext[] _groupByExpressions;
  private final int _numGroupByExpressions;
  private final int[] _cardinalities;
  private final boolean[] _isSingleValueColumn;
  private final Dictionary[] _dictionaries;

  // The first dimension is the index of group-by column
  // Reusable buffer for single-value column dictionary ids
  private final int[][] _singleValueDictIds;
  // Reusable buffer for multi-value column dictionary ids
  private final int[][][] _multiValueDictIds;

  private final int _globalGroupIdUpperBound;
  private final RawKeyHolder _rawKeyHolder;

  public DictionaryBasedGroupKeyGenerator(TransformOperator transformOperator, ExpressionContext[] groupByExpressions,
      int numGroupsLimit, int arrayBasedThreshold) {
    assert numGroupsLimit >= arrayBasedThreshold;

    _groupByExpressions = groupByExpressions;
    _numGroupByExpressions = groupByExpressions.length;

    _cardinalities = new int[_numGroupByExpressions];
    _isSingleValueColumn = new boolean[_numGroupByExpressions];
    _dictionaries = new Dictionary[_numGroupByExpressions];
    _singleValueDictIds = new int[_numGroupByExpressions][];
    _multiValueDictIds = new int[_numGroupByExpressions][][];

    long cardinalityProduct = 1L;
    boolean longOverflow = false;
    for (int i = 0; i < _numGroupByExpressions; i++) {
      ExpressionContext groupByExpression = groupByExpressions[i];
      _dictionaries[i] = transformOperator.getDictionary(groupByExpression);
      int cardinality = _dictionaries[i].length();
      _cardinalities[i] = cardinality;
      if (!longOverflow) {
        if (cardinalityProduct > Long.MAX_VALUE / cardinality) {
          longOverflow = true;
        } else {
          cardinalityProduct *= cardinality;
        }
      }

      _isSingleValueColumn[i] = transformOperator.getResultMetadata(groupByExpression).isSingleValue();
    }
    // TODO: Clear the holder after processing the query instead of before
    if (longOverflow) {
      // ArrayMapBasedHolder
      _globalGroupIdUpperBound = numGroupsLimit;
      Object2IntOpenHashMap<IntArray> groupIdMap = THREAD_LOCAL_INT_ARRAY_MAP.get();
      int size = groupIdMap.size();
      groupIdMap.clear();
      if (size > MAX_CACHING_MAP_SIZE) {
        groupIdMap.trim();
      }
      _rawKeyHolder = new ArrayMapBasedHolder(groupIdMap);
    } else {
      if (cardinalityProduct > Integer.MAX_VALUE) {
        // LongMapBasedHolder
        _globalGroupIdUpperBound = numGroupsLimit;
        Long2IntOpenHashMap groupIdMap = THREAD_LOCAL_LONG_MAP.get();
        int size = groupIdMap.size();
        groupIdMap.clear();
        if (size > MAX_CACHING_MAP_SIZE) {
          groupIdMap.trim();
        }
        _rawKeyHolder = new LongMapBasedHolder(groupIdMap);
      } else {
        _globalGroupIdUpperBound = Math.min((int) cardinalityProduct, numGroupsLimit);
        if (cardinalityProduct > arrayBasedThreshold) {
          // IntMapBasedHolder
          IntGroupIdMap groupIdMap = THREAD_LOCAL_INT_MAP.get();
          groupIdMap.clearAndTrim();
          _rawKeyHolder = new IntMapBasedHolder(groupIdMap);
        } else {
          _rawKeyHolder = new ArrayBasedHolder();
        }
      }
    }
  }

  @Override
  public int getGlobalGroupKeyUpperBound() {
    return _globalGroupIdUpperBound;
  }

  @Override
  public void generateKeysForBlock(TransformBlock transformBlock, int[] groupKeys) {
    // Fetch dictionary ids in the given block for all group-by columns
    for (int i = 0; i < _numGroupByExpressions; i++) {
      BlockValSet blockValueSet = transformBlock.getBlockValueSet(_groupByExpressions[i]);
      _singleValueDictIds[i] = blockValueSet.getDictionaryIdsSV();
    }

    _rawKeyHolder.processSingleValue(transformBlock.getNumDocs(), groupKeys);
  }

  @Override
  public void generateKeysForBlock(TransformBlock transformBlock, int[][] groupKeys) {
    // Fetch dictionary ids in the given block for all group-by columns
    for (int i = 0; i < _numGroupByExpressions; i++) {
      BlockValSet blockValueSet = transformBlock.getBlockValueSet(_groupByExpressions[i]);
      if (_isSingleValueColumn[i]) {
        _singleValueDictIds[i] = blockValueSet.getDictionaryIdsSV();
      } else {
        _multiValueDictIds[i] = blockValueSet.getDictionaryIdsMV();
      }
    }

    _rawKeyHolder.processMultiValue(transformBlock.getNumDocs(), groupKeys);
  }

  @Override
  public int getCurrentGroupKeyUpperBound() {
    return _rawKeyHolder.getGroupIdUpperBound();
  }

  @Override
  public Iterator<GroupKey> getGroupKeys() {
    return _rawKeyHolder.getGroupKeys();
  }

  @Override
  public Iterator<StringGroupKey> getStringGroupKeys() {
    return _rawKeyHolder.getStringGroupKeys();
  }

  private interface RawKeyHolder {

    /**
     * Process a block of documents for all single-valued group-by columns case.
     *
     * @param numDocs Number of documents inside the block
     * @param outGroupIds Buffer for group id results
     */
    void processSingleValue(int numDocs, int[] outGroupIds);

    /**
     * Process a block of documents for case with multi-valued group-by columns.
     *
     * @param numDocs Number of documents inside the block
     * @param outGroupIds Buffer for group id results
     */
    void processMultiValue(int numDocs, int[][] outGroupIds);

    /**
     * Get the upper bound of group id (exclusive) inside the holder.
     *
     * @return Upper bound of group id inside the holder
     */
    int getGroupIdUpperBound();

    /**
     * Returns an iterator of {@link GroupKey}. Use this interface to iterate through all the group keys.
     */
    Iterator<GroupKey> getGroupKeys();

    /**
     * Returns an iterator of {@link StringGroupKey}. Use this interface to iterate through all the group keys.
     */
    Iterator<StringGroupKey> getStringGroupKeys();
  }

  private class ArrayBasedHolder implements RawKeyHolder {
    // TODO: using bitmap might better
    private final boolean[] _flags = new boolean[_globalGroupIdUpperBound];

    @Override
    public void processSingleValue(int numDocs, int[] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        int groupId = 0;
        for (int j = _numGroupByExpressions - 1; j >= 0; j--) {
          groupId = groupId * _cardinalities[j] + _singleValueDictIds[j][i];
        }
        outGroupIds[i] = groupId;
        _flags[groupId] = true;
      }
    }

    @Override
    public void processMultiValue(int numDocs, int[][] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        int[] groupIds = getIntRawKeys(i);
        for (int groupId : groupIds) {
          _flags[groupId] = true;
        }
        outGroupIds[i] = groupIds;
      }
    }

    @Override
    public int getGroupIdUpperBound() {
      return _globalGroupIdUpperBound;
    }

    @Override
    public Iterator<GroupKey> getGroupKeys() {
      return new Iterator<GroupKey>() {
        private int _currentGroupId;
        private final GroupKey _groupKey = new GroupKey();

        @Override
        public boolean hasNext() {
          while (_currentGroupId < _globalGroupIdUpperBound && !_flags[_currentGroupId]) {
            _currentGroupId++;
          }
          return _currentGroupId < _globalGroupIdUpperBound;
        }

        @Override
        public GroupKey next() {
          _groupKey._groupId = _currentGroupId;
          _groupKey._keys = getKeys(_currentGroupId);
          _currentGroupId++;
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    @Override
    public Iterator<StringGroupKey> getStringGroupKeys() {
      return new Iterator<StringGroupKey>() {
        private int _currentGroupId;
        private final StringGroupKey _groupKey = new StringGroupKey();

        @Override
        public boolean hasNext() {
          while (_currentGroupId < _globalGroupIdUpperBound && !_flags[_currentGroupId]) {
            _currentGroupId++;
          }
          return _currentGroupId < _globalGroupIdUpperBound;
        }

        @Override
        public StringGroupKey next() {
          _groupKey._groupId = _currentGroupId;
          _groupKey._stringKey = getStringKey(_currentGroupId);
          _currentGroupId++;
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  }

  private class IntMapBasedHolder implements RawKeyHolder {
    private final IntGroupIdMap _groupIdMap;

    public IntMapBasedHolder(IntGroupIdMap groupIdMap) {
      _groupIdMap = groupIdMap;
    }

    @Override
    public void processSingleValue(int numDocs, int[] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        int rawKey = 0;
        for (int j = _numGroupByExpressions - 1; j >= 0; j--) {
          rawKey = rawKey * _cardinalities[j] + _singleValueDictIds[j][i];
        }
        outGroupIds[i] = _groupIdMap.getGroupId(rawKey, _globalGroupIdUpperBound);
      }
    }

    @Override
    public void processMultiValue(int numDocs, int[][] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        int[] groupIds = getIntRawKeys(i);
        int length = groupIds.length;
        for (int j = 0; j < length; j++) {
          groupIds[j] = _groupIdMap.getGroupId(groupIds[j], _globalGroupIdUpperBound);
        }
        outGroupIds[i] = groupIds;
      }
    }

    @Override
    public int getGroupIdUpperBound() {
      return _groupIdMap.size();
    }

    @Override
    public Iterator<GroupKey> getGroupKeys() {
      return new Iterator<GroupKey>() {
        private final Iterator<IntGroupIdMap.Entry> _iterator = _groupIdMap.iterator();
        private final GroupKey _groupKey = new GroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public GroupKey next() {
          IntGroupIdMap.Entry entry = _iterator.next();
          _groupKey._groupId = entry._groupId;
          _groupKey._keys = getKeys(entry._rawKey);
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    @Override
    public Iterator<StringGroupKey> getStringGroupKeys() {
      return new Iterator<StringGroupKey>() {
        private final Iterator<IntGroupIdMap.Entry> _iterator = _groupIdMap.iterator();
        private final StringGroupKey _groupKey = new StringGroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public StringGroupKey next() {
          IntGroupIdMap.Entry entry = _iterator.next();
          _groupKey._groupId = entry._groupId;
          _groupKey._stringKey = getStringKey(entry._rawKey);
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  }

  /**
   * Helper method to calculate raw keys that can fit into integer for the given index.
   *
   * @param index Index in block
   * @return Array of integer raw keys
   */
  @SuppressWarnings("Duplicates")
  private int[] getIntRawKeys(int index) {
    int[] rawKeys = null;

    // Specialize single multi-value group-by column case
    if (_numGroupByExpressions == 1) {
      rawKeys = _multiValueDictIds[0][index];
    } else {
      // Before having to transform to array, use single value raw key for better performance
      int rawKey = 0;

      for (int i = _numGroupByExpressions - 1; i >= 0; i--) {
        int cardinality = _cardinalities[i];
        if (_isSingleValueColumn[i]) {
          int dictId = _singleValueDictIds[i][index];
          if (rawKeys == null) {
            rawKey = rawKey * cardinality + dictId;
          } else {
            int length = rawKeys.length;
            for (int j = 0; j < length; j++) {
              rawKeys[j] = rawKeys[j] * cardinality + dictId;
            }
          }
        } else {
          int[] multiValueDictIds = _multiValueDictIds[i][index];
          int numValues = multiValueDictIds.length;

          // Specialize multi-value column with only one value inside
          if (numValues == 1) {
            int dictId = multiValueDictIds[0];
            if (rawKeys == null) {
              rawKey = rawKey * cardinality + dictId;
            } else {
              int length = rawKeys.length;
              for (int j = 0; j < length; j++) {
                rawKeys[j] = rawKeys[j] * cardinality + dictId;
              }
            }
          } else {
            if (rawKeys == null) {
              rawKeys = new int[numValues];
              for (int j = 0; j < numValues; j++) {
                int dictId = multiValueDictIds[j];
                rawKeys[j] = rawKey * cardinality + dictId;
              }
            } else {
              int currentLength = rawKeys.length;
              int newLength = currentLength * numValues;
              int[] newRawKeys = new int[newLength];
              for (int j = 0; j < numValues; j++) {
                int startOffset = j * currentLength;
                System.arraycopy(rawKeys, 0, newRawKeys, startOffset, currentLength);
                int dictId = multiValueDictIds[j];
                int endOffset = startOffset + currentLength;
                for (int k = startOffset; k < endOffset; k++) {
                  newRawKeys[k] = newRawKeys[k] * cardinality + dictId;
                }
              }
              rawKeys = newRawKeys;
            }
          }
        }
      }

      if (rawKeys == null) {
        rawKeys = new int[]{rawKey};
      }
    }

    return rawKeys;
  }

  /**
   * Helper method to get the keys from the raw key.
   */
  private Object[] getKeys(int rawKey) {
    // Specialize single group-by column case
    if (_numGroupByExpressions == 1) {
      return new Object[]{_dictionaries[0].getInternal(rawKey)};
    } else {
      Object[] groupKeys = new Object[_numGroupByExpressions];
      for (int i = 0; i < _numGroupByExpressions; i++) {
        int cardinality = _cardinalities[i];
        groupKeys[i] = _dictionaries[i].getInternal(rawKey % cardinality);
        rawKey /= cardinality;
      }
      return groupKeys;
    }
  }

  /**
   * Helper method to get the string key from the raw key.
   */
  private String getStringKey(int rawKey) {
    // Specialize single group-by column case
    if (_numGroupByExpressions == 1) {
      return _dictionaries[0].getStringValue(rawKey);
    } else {
      int cardinality = _cardinalities[0];
      StringBuilder groupKeyBuilder = new StringBuilder(_dictionaries[0].getStringValue(rawKey % cardinality));
      rawKey /= cardinality;
      for (int i = 1; i < _numGroupByExpressions; i++) {
        groupKeyBuilder.append(GroupKeyGenerator.DELIMITER);
        cardinality = _cardinalities[i];
        groupKeyBuilder.append(_dictionaries[i].getStringValue(rawKey % cardinality));
        rawKey /= cardinality;
      }
      return groupKeyBuilder.toString();
    }
  }

  private class LongMapBasedHolder implements RawKeyHolder {
    private final Long2IntOpenHashMap _groupIdMap;

    public LongMapBasedHolder(Long2IntOpenHashMap groupIdMap) {
      _groupIdMap = groupIdMap;
    }

    @Override
    public void processSingleValue(int numDocs, int[] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        long rawKey = 0L;
        for (int j = _numGroupByExpressions - 1; j >= 0; j--) {
          rawKey = rawKey * _cardinalities[j] + _singleValueDictIds[j][i];
        }
        outGroupIds[i] = getGroupId(rawKey);
      }
    }

    @Override
    public void processMultiValue(int numDocs, int[][] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        long[] rawKeys = getLongRawKeys(i);
        int length = rawKeys.length;
        int[] groupIds = new int[length];
        for (int j = 0; j < length; j++) {
          groupIds[j] = getGroupId(rawKeys[j]);
        }
        outGroupIds[i] = groupIds;
      }
    }

    private int getGroupId(long rawKey) {
      int numGroups = _groupIdMap.size();
      if (numGroups < _globalGroupIdUpperBound) {
        return _groupIdMap.computeIfAbsent(rawKey, k -> numGroups);
      } else {
        return _groupIdMap.get(rawKey);
      }
    }

    @Override
    public int getGroupIdUpperBound() {
      return _groupIdMap.size();
    }

    @Override
    public Iterator<GroupKey> getGroupKeys() {
      return new Iterator<GroupKey>() {
        private final ObjectIterator<Long2IntMap.Entry> _iterator = _groupIdMap.long2IntEntrySet().fastIterator();
        private final GroupKey _groupKey = new GroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public GroupKey next() {
          Long2IntMap.Entry entry = _iterator.next();
          _groupKey._groupId = entry.getIntValue();
          _groupKey._keys = getKeys(entry.getLongKey());
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    @Override
    public Iterator<StringGroupKey> getStringGroupKeys() {
      return new Iterator<StringGroupKey>() {
        private final ObjectIterator<Long2IntMap.Entry> _iterator = _groupIdMap.long2IntEntrySet().fastIterator();
        private final StringGroupKey _groupKey = new StringGroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public StringGroupKey next() {
          Long2IntMap.Entry entry = _iterator.next();
          _groupKey._groupId = entry.getIntValue();
          _groupKey._stringKey = getStringKey(entry.getLongKey());
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  }

  /**
   * Helper method to calculate raw keys that can fit into integer for the given index.
   *
   * @param index Index in block
   * @return Array of long raw keys
   */
  @SuppressWarnings("Duplicates")
  private long[] getLongRawKeys(int index) {
    long[] rawKeys = null;

    // Before having to transform to array, use single value raw key for better performance
    long rawKey = 0;

    for (int i = _numGroupByExpressions - 1; i >= 0; i--) {
      int cardinality = _cardinalities[i];
      if (_isSingleValueColumn[i]) {
        int dictId = _singleValueDictIds[i][index];
        if (rawKeys == null) {
          rawKey = rawKey * cardinality + dictId;
        } else {
          int length = rawKeys.length;
          for (int j = 0; j < length; j++) {
            rawKeys[j] = rawKeys[j] * cardinality + dictId;
          }
        }
      } else {
        int[] multiValueDictIds = _multiValueDictIds[i][index];
        int numValues = multiValueDictIds.length;

        // Specialize multi-value column with only one value inside
        if (numValues == 1) {
          int dictId = multiValueDictIds[0];
          if (rawKeys == null) {
            rawKey = rawKey * cardinality + dictId;
          } else {
            int length = rawKeys.length;
            for (int j = 0; j < length; j++) {
              rawKeys[j] = rawKeys[j] * cardinality + dictId;
            }
          }
        } else {
          if (rawKeys == null) {
            rawKeys = new long[numValues];
            for (int j = 0; j < numValues; j++) {
              int dictId = multiValueDictIds[j];
              rawKeys[j] = rawKey * cardinality + dictId;
            }
          } else {
            int currentLength = rawKeys.length;
            int newLength = currentLength * numValues;
            long[] newRawKeys = new long[newLength];
            for (int j = 0; j < numValues; j++) {
              int startOffset = j * currentLength;
              System.arraycopy(rawKeys, 0, newRawKeys, startOffset, currentLength);
              int dictId = multiValueDictIds[j];
              int endOffset = startOffset + currentLength;
              for (int k = startOffset; k < endOffset; k++) {
                newRawKeys[k] = newRawKeys[k] * cardinality + dictId;
              }
            }
            rawKeys = newRawKeys;
          }
        }
      }
    }

    if (rawKeys == null) {
      return new long[]{rawKey};
    } else {
      return rawKeys;
    }
  }

  /**
   * Helper method to get the keys from the raw key.
   */
  private Object[] getKeys(long rawKey) {
    Object[] groupKeys = new Object[_numGroupByExpressions];
    for (int i = 0; i < _numGroupByExpressions; i++) {
      int cardinality = _cardinalities[i];
      groupKeys[i] = _dictionaries[i].getInternal((int) (rawKey % cardinality));
      rawKey /= cardinality;
    }
    return groupKeys;
  }

  /**
   * Helper method to get the string key from the raw key.
   */
  private String getStringKey(long rawKey) {
    int cardinality = _cardinalities[0];
    StringBuilder groupKeyBuilder = new StringBuilder(_dictionaries[0].getStringValue((int) (rawKey % cardinality)));
    rawKey /= cardinality;
    for (int i = 1; i < _numGroupByExpressions; i++) {
      groupKeyBuilder.append(GroupKeyGenerator.DELIMITER);
      cardinality = _cardinalities[i];
      groupKeyBuilder.append(_dictionaries[i].getStringValue((int) (rawKey % cardinality)));
      rawKey /= cardinality;
    }
    return groupKeyBuilder.toString();
  }

  private class ArrayMapBasedHolder implements RawKeyHolder {
    private final Object2IntOpenHashMap<IntArray> _groupIdMap;

    public ArrayMapBasedHolder(Object2IntOpenHashMap<IntArray> groupIdMap) {
      _groupIdMap = groupIdMap;
    }

    @Override
    public void processSingleValue(int numDocs, int[] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        int[] dictIds = new int[_numGroupByExpressions];
        for (int j = 0; j < _numGroupByExpressions; j++) {
          dictIds[j] = _singleValueDictIds[j][i];
        }
        outGroupIds[i] = getGroupId(new IntArray(dictIds));
      }
    }

    @Override
    public void processMultiValue(int numDocs, int[][] outGroupIds) {
      for (int i = 0; i < numDocs; i++) {
        IntArray[] rawKeys = getIntArrayRawKeys(i);
        int length = rawKeys.length;
        int[] groupIds = new int[length];
        for (int j = 0; j < length; j++) {
          groupIds[j] = getGroupId(rawKeys[j]);
        }
        outGroupIds[i] = groupIds;
      }
    }

    private int getGroupId(IntArray rawKey) {
      int numGroups = _groupIdMap.size();
      if (numGroups < _globalGroupIdUpperBound) {
        return _groupIdMap.computeIntIfAbsent(rawKey, k -> numGroups);
      } else {
        return _groupIdMap.getInt(rawKey);
      }
    }

    @Override
    public int getGroupIdUpperBound() {
      return _groupIdMap.size();
    }

    @Override
    public Iterator<GroupKey> getGroupKeys() {
      return new Iterator<GroupKey>() {
        private final ObjectIterator<Object2IntMap.Entry<IntArray>> _iterator =
            _groupIdMap.object2IntEntrySet().fastIterator();
        private final GroupKey _groupKey = new GroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public GroupKey next() {
          Object2IntMap.Entry<IntArray> entry = _iterator.next();
          _groupKey._groupId = entry.getIntValue();
          _groupKey._keys = getKeys(entry.getKey());
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    @Override
    public Iterator<StringGroupKey> getStringGroupKeys() {
      return new Iterator<StringGroupKey>() {
        private final ObjectIterator<Object2IntMap.Entry<IntArray>> _iterator =
            _groupIdMap.object2IntEntrySet().fastIterator();
        private final StringGroupKey _groupKey = new StringGroupKey();

        @Override
        public boolean hasNext() {
          return _iterator.hasNext();
        }

        @Override
        public StringGroupKey next() {
          Object2IntMap.Entry<IntArray> entry = _iterator.next();
          _groupKey._groupId = entry.getIntValue();
          _groupKey._stringKey = getStringKey(entry.getKey());
          return _groupKey;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  }

  /**
   * Helper method to calculate raw keys that can fit into integer for the given index.
   *
   * @param index Index in block
   * @return Array of IntArray raw keys
   */
  @SuppressWarnings("Duplicates")
  private IntArray[] getIntArrayRawKeys(int index) {
    IntArray[] rawKeys = null;

    // Before having to transform to array, use single value raw key for better performance
    int[] dictIds = new int[_numGroupByExpressions];

    for (int i = 0; i < _numGroupByExpressions; i++) {
      if (_isSingleValueColumn[i]) {
        int dictId = _singleValueDictIds[i][index];
        if (rawKeys == null) {
          dictIds[i] = dictId;
        } else {
          for (IntArray rawKey : rawKeys) {
            rawKey._elements[i] = dictId;
          }
        }
      } else {
        int[] multiValueDictIds = _multiValueDictIds[i][index];
        int numValues = multiValueDictIds.length;

        // Specialize multi-value column with only one value inside
        if (numValues == 1) {
          int dictId = multiValueDictIds[0];
          if (rawKeys == null) {
            dictIds[i] = dictId;
          } else {
            for (IntArray rawKey : rawKeys) {
              rawKey._elements[i] = dictId;
            }
          }
        } else {
          if (rawKeys == null) {
            rawKeys = new IntArray[numValues];
            for (int j = 0; j < numValues; j++) {
              int dictId = multiValueDictIds[j];
              rawKeys[j] = new IntArray(dictIds.clone());
              rawKeys[j]._elements[i] = dictId;
            }
          } else {
            int currentLength = rawKeys.length;
            int newLength = currentLength * numValues;
            IntArray[] newRawKeys = new IntArray[newLength];
            System.arraycopy(rawKeys, 0, newRawKeys, 0, currentLength);
            for (int j = 1; j < numValues; j++) {
              int offset = j * currentLength;
              for (int k = 0; k < currentLength; k++) {
                newRawKeys[offset + k] = new IntArray(rawKeys[k]._elements.clone());
              }
            }
            for (int j = 0; j < numValues; j++) {
              int startOffset = j * currentLength;
              int dictId = multiValueDictIds[j];
              int endOffset = startOffset + currentLength;
              for (int k = startOffset; k < endOffset; k++) {
                newRawKeys[k]._elements[i] = dictId;
              }
            }
            rawKeys = newRawKeys;
          }
        }
      }
    }

    if (rawKeys == null) {
      return new IntArray[]{new IntArray(dictIds)};
    } else {
      return rawKeys;
    }
  }

  /**
   * Helper method to get the keys from the raw key.
   */
  private Object[] getKeys(IntArray rawKey) {
    Object[] groupKeys = new Object[_numGroupByExpressions];
    for (int i = 0; i < _numGroupByExpressions; i++) {
      groupKeys[i] = _dictionaries[i].getInternal(rawKey._elements[i]);
    }
    return groupKeys;
  }

  /**
   * Helper method to get the string key from the raw key.
   */
  private String getStringKey(IntArray rawKey) {
    StringBuilder groupKeyBuilder = new StringBuilder(_dictionaries[0].getStringValue(rawKey._elements[0]));
    for (int i = 1; i < _numGroupByExpressions; i++) {
      groupKeyBuilder.append(GroupKeyGenerator.DELIMITER);
      groupKeyBuilder.append(_dictionaries[i].getStringValue(rawKey._elements[i]));
    }
    return groupKeyBuilder.toString();
  }

  /**
   * Fast int-to-int hashmap with {@link #INVALID_ID} as the default return value.
   *
Different from {@link it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap}, this map uses one single array to store
   * keys and values to reduce the cache miss.
   */
  @VisibleForTesting
  public static class IntGroupIdMap {
    private static final float LOAD_FACTOR = 0.75f;

    private int[] _keyValueHolder;
    private int _capacity;
    private int _mask;
    private int _maxNumEntries;
    private int _size;

    public IntGroupIdMap() {
      init();
    }

    private void init() {
      // Initialize the map with capacity 512 so that the _keyValueHolder can fit into a single memory page
      _capacity = 1 << 9;
      int holderSize = _capacity << 1;
      _keyValueHolder = new int[holderSize];
      _mask = holderSize - 1;
      _maxNumEntries = (int) (_capacity * LOAD_FACTOR);
    }

    public int size() {
      return _size;
    }

    /**
     * Returns the group id for the given raw key. Create a new group id if the raw key does not exist and the group id
     * upper bound is not reached.
     */
    public int getGroupId(int rawKey, int groupIdUpperBound) {
      // NOTE: Key 0 is reserved as the null key. Use (rawKey + 1) as the internal key because rawKey can never be -1.
      int internalKey = rawKey + 1;
      int index = (HashCommon.mix(internalKey) << 1) & _mask;
      int key = _keyValueHolder[index];

      // Handle hash hit separately for better performance
      if (key == internalKey) {
        return _keyValueHolder[index + 1];
      }
      if (key == 0) {
        return _size < groupIdUpperBound ? addNewGroup(internalKey, index) : INVALID_ID;
      }

      // Hash collision
      while (true) {
        index = (index + 2) & _mask;
        key = _keyValueHolder[index];
        if (key == internalKey) {
          return _keyValueHolder[index + 1];
        }
        if (key == 0) {
          return _size < groupIdUpperBound ? addNewGroup(internalKey, index) : INVALID_ID;
        }
      }
    }

    private int addNewGroup(int internalKey, int index) {
      int groupId = _size++;
      _keyValueHolder[index] = internalKey;
      _keyValueHolder[index + 1] = groupId;
      if (_size > _maxNumEntries) {
        expand();
      }
      return groupId;
    }

    private void expand() {
      _capacity <<= 1;
      int holderSize = _capacity << 1;
      int[] oldKeyValueHolder = _keyValueHolder;
      _keyValueHolder = new int[holderSize];
      _mask = holderSize - 1;
      _maxNumEntries <<= 1;
      int oldIndex = 0;
      for (int i = 0; i < _size; i++) {
        while (oldKeyValueHolder[oldIndex] == 0) {
          oldIndex += 2;
        }
        int key = oldKeyValueHolder[oldIndex];
        int value = oldKeyValueHolder[oldIndex + 1];
        int newIndex = (HashCommon.mix(key) << 1) & _mask;
        if (_keyValueHolder[newIndex] != 0) {
          do {
            newIndex = (newIndex + 2) & _mask;
          } while (_keyValueHolder[newIndex] != 0);
        }
        _keyValueHolder[newIndex] = key;
        _keyValueHolder[newIndex + 1] = value;
        oldIndex += 2;
      }
    }

    public Iterator<Entry> iterator() {
      return new Iterator<Entry>() {
        private final Entry _entry = new Entry();
        private int _index;
        private int _numRemainingEntries = _size;

        @Override
        public boolean hasNext() {
          return _numRemainingEntries > 0;
        }

        @Override
        public Entry next() {
          int key;
          while ((key = _keyValueHolder[_index]) == 0) {
            _index += 2;
          }
          _entry._rawKey = key - 1;
          _entry._groupId = _keyValueHolder[_index + 1];
          _index += 2;
          _numRemainingEntries--;
          return _entry;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    /**
     * Clears the map and trims the map if the size is larger than the {@link #MAX_CACHING_MAP_SIZE}.
     */
    public void clearAndTrim() {
      if (_size == 0) {
        return;
      }
      if (_size <= MAX_CACHING_MAP_SIZE) {
        // Clear the map
        Arrays.fill(_keyValueHolder, 0);
      } else {
        // Init the map (clear and trim)
        init();
      }
      _size = 0;
    }

    public static class Entry {
      public int _rawKey;
      public int _groupId;
    }
  }

  /**
   * Drop un-necessary checks for highest performance.
   */
  @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
  private static class IntArray {
    public int[] _elements;

    public IntArray(int[] elements) {
      _elements = elements;
    }

    @Override
    public int hashCode() {
      int result = 1;
      for (int element : _elements) {
        result = 31 * result + element;
      }
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      int[] that = ((IntArray) obj)._elements;
      int length = _elements.length;
      if (length != that.length) {
        return false;
      }
      for (int i = 0; i < length; i++) {
        if (_elements[i] != that[i]) {
          return false;
        }
      }
      return true;
    }
  }
}


text:
Timothy McAllister Website - Version 4

- Framework: Gatsby
- CMS: Contentful
- CDN: Netlify

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:Runtime>
    <edmx:ConceptualModels>
      <Schema Namespace="WebStack.QA.Test.OData.ComplexTypeInheritance" xmlns="http://docs.oasis-open.org/odata/ns/edm">
        <EntityType Name="Window">
          <Key>
            <PropertyRef Name="Id" />
          </Key>
          <Property Name="Id" Type="Edm.Int32" Nullable="false" />
          <Property Name="Name" Type="Edm.String" />
          <Property Name="CurrentShape" Type="WebStack.QA.Test.OData.ComplexTypeInheritance.Shape" />
          <Property Name="OptionalShapes" Type="Collection(WebStack.QA.Test.OData.ComplexTypeInheritance.Shape)" />
          <NavigationProperty Name="Parent" Type="WebStack.QA.Test.OData.ComplexTypeInheritance.Window" />
        </EntityType>
        <ComplexType Name="Shape" Abstract="true">
          <Property Name="HasBorder" Type="Edm.Boolean" Nullable="false" />
        </ComplexType>
        <ComplexType Name="Polygon" BaseType="WebStack.QA.Test.OData.ComplexTypeInheritance.Shape">
          <Property Name="Vertexes" Type="Collection(WebStack.QA.Test.OData.ComplexTypeInheritance.Point)" />
        </ComplexType>
        <ComplexType Name="Rectangle" BaseType="WebStack.QA.Test.OData.ComplexTypeInheritance.Polygon">
          <Property Name="TopLeft" Type="WebStack.QA.Test.OData.ComplexTypeInheritance.Point" />
          <Property Name="Width" Type="Edm.Int32" Nullable="false" />
          <Property Name="Height" Type="Edm.Int32" Nullable="false" />
        </ComplexType>
        <ComplexType Name="Point">
          <Property Name="X" Type="Edm.Int32" Nullable="false" />
          <Property Name="Y" Type="Edm.Int32" Nullable="false" />
        </ComplexType>
        <ComplexType Name="Circle" BaseType="WebStack.QA.Test.OData.ComplexTypeInheritance.Shape">
          <Property Name="Center" Type="WebStack.QA.Test.OData.ComplexTypeInheritance.Point" />
          <Property Name="Radius" Type="Edm.Int32" Nullable="false" />
        </ComplexType>
        <EntityContainer Name="Container">
          <EntitySet Name="Windows" EntityType="WebStack.QA.Test.OData.ComplexTypeInheritance.Window">
            <NavigationPropertyBinding Path="Parent" Target="Windows" />
          </EntitySet>
        </EntityContainer>
      </Schema>
    </edmx:ConceptualModels>
  </edmx:Runtime>
</edmx:Edmx>


text:
Models and rights
=================

The SSO has three main models:

.. glossary::

  user profile
    Basically users that log in.

  organisation
    Only used to have a name and ID for organisations. It has nothing to do
    with users and portals whatsoever.

  portal
    A portal that's using the SSO. You need SSO admin access to add one. Used
    to protect the traffic between portal and SSO.

User profile
------------

Users can be created via the API by a portal. They then get an email
with an activation link to set their password.


text:
package org.apache.hadoop.hbase.util;

import org.apache.commons.logging.LogFactory;
import java.io.PrintWriter;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hbase.VersionAnnotation;
import org.apache.commons.logging.Log;

/**
 * This class finds the package info for hbase and the VersionAnnotation
 * information.  Taken from hadoop.  Only name of annotation is different.
 */
@InterfaceAudience.Public
@InterfaceStability.Evolving
public class VersionInfo {
  private static final Log LOG = LogFactory.getLog(VersionInfo.class.getName());
  private static Package myPackage;
  private static VersionAnnotation version;

  static {
    myPackage = VersionAnnotation.class.getPackage();
    version = myPackage.getAnnotation(VersionAnnotation.class);
  }

  /**
   * Get the meta-data for the hbase package.
   * @return package
   */
  static Package getPackage() {
    return myPackage;
  }

  /**
   * Get the hbase version.
   * @return the hbase version string, eg. "0.6.3-dev"
   */
  public static String getVersion() {
    return version != null ? version.version() : "Unknown";
  }

  /**
   * Get the subversion revision number for the root directory
   * @return the revision number, eg. "451451"
   */
  public static String getRevision() {
    return version != null ? version.revision() : "Unknown";
  }

  /**
   * The date that hbase was compiled.
   * @return the compilation date in unix date format
   */
  public static String getDate() {
    return version != null ? version.date() : "Unknown";
  }

  /**
   * The user that compiled hbase.
   * @return the username of the user
   */
  public static String getUser() {
    return version != null ? version.user() : "Unknown";
  }

  /**
   * Get the subversion URL for the root hbase directory.
   * @return the url
   */
  public static String getUrl() {
    return version != null ? version.url() : "Unknown";
  }

  static String[] versionReport() {
    return new String[] {
      "HBase " + getVersion(),
      "Subversion " + getUrl() + " -r " + getRevision(),
      "Compiled by " + getUser() + " on " + getDate()
      };
  }

  public static void writeTo(PrintWriter out) {
    for (String line : versionReport()) {
      out.println(line);
    }
  }

  public static void logVersion() {
    for (String line : versionReport()) {
      LOG.info(line);
    }
  }

  public static void main(String[] args) {
    logVersion();
  }
}


text:
[instagram-private-api](../../README.md) / [responses](../../modules/responses.md) / MediaRepositoryCommentResponseUser

# Interface: MediaRepositoryCommentResponseUser

[responses](../../modules/responses.md).MediaRepositoryCommentResponseUser

## Table of contents

### Properties

- [allowed\_commenter\_type](MediaRepositoryCommentResponseUser.md#allowed_commenter_type)
- [full\_name](MediaRepositoryCommentResponseUser.md#full_name)
- [has\_anonymous\_profile\_picture](MediaRepositoryCommentResponseUser.md#has_anonymous_profile_picture)
- [is\_private](MediaRepositoryCommentResponseUser.md#is_private)
- [is\_verified](MediaRepositoryCommentResponseUser.md#is_verified)
- [pk](MediaRepositoryCommentResponseUser.md#pk)
- [profile\_pic\_id](MediaRepositoryCommentResponseUser.md#profile_pic_id)
- [profile\_pic\_url](MediaRepositoryCommentResponseUser.md#profile_pic_url)
- [reel\_auto\_archive](MediaRepositoryCommentResponseUser.md#reel_auto_archive)
- [username](MediaRepositoryCommentResponseUser.md#username)

## Properties

### allowed\_commenter\_type

• **allowed\_commenter\_type**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:27](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L27)

___

### full\_name

• **full\_name**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:20](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L20)

___

### has\_anonymous\_profile\_picture

• **has\_anonymous\_profile\_picture**: `boolean`

#### Defined in

[src/responses/media.repository.comment.response.ts:25](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L25)

___

### is\_private

• **is\_private**: `boolean`

#### Defined in

[src/responses/media.repository.comment.response.ts:21](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L21)

___

### is\_verified

• **is\_verified**: `boolean`

#### Defined in

[src/responses/media.repository.comment.response.ts:24](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L24)

___

### pk

• **pk**: `number`

#### Defined in

[src/responses/media.repository.comment.response.ts:18](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L18)

___

### profile\_pic\_id

• **profile\_pic\_id**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:23](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L23)

___

### profile\_pic\_url

• **profile\_pic\_url**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:22](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L22)

___

### reel\_auto\_archive

• **reel\_auto\_archive**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:26](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L26)

___

### username

• **username**: `string`

#### Defined in

[src/responses/media.repository.comment.response.ts:19](https://github.com/Nerixyz/instagram-private-api/blob/b3351b9/src/responses/media.repository.comment.response.ts#L19)


text:
<?php

namespace Rx7\BookBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Author
 *
 * @ORM\Table(name="author")
 * @ORM\Entity(repositoryClass="Rx7\BookBundle\Entity\AuthorRepository")
 */
class Author
{
	/**
	 * @ORM\OneToMany(targetEntity="Rx7\BookBundle\Entity\Book", mappedBy="author")
	 */
	private $books;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="firstName", type="string", length=255)
     */
    private $firstName;

    /**
     * @var string
     *
     * @ORM\Column(name="LastName", type="string", length=255)
     */
    private $lastName;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     * @return Author
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     * @return Author
     */
    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->books = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add books
     *
     * @param \Rx7\BookBundle\Entity\Book $book
     * @return Author
     */
    public function addBook(\Rx7\BookBundle\Entity\Book $book)
    {
        $this->books[] = $book;
		$book->setAuthor($this);
        return $this;
    }

    /**
     * Remove books
     *
     * @param \Rx7\BookBundle\Entity\Book $book
     */
    public function removeBook(\Rx7\BookBundle\Entity\Book $book)
    {
            	$this->books->removeElement($book);
    }

    /**
     * Get books
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBooks()
    {
        return $this->books;
    }

    public function  getFullName(){
    	return $this->firstName .' '.$this->lastName;
    }

}


text:
package org.apache.druid.query.aggregation;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import org.apache.druid.math.expr.Expr;
import org.apache.druid.math.expr.ExprMacroTable;
import org.apache.druid.math.expr.Parser;
import org.apache.druid.segment.BaseDoubleColumnValueSelector;
import org.apache.druid.segment.ColumnInspector;
import org.apache.druid.segment.ColumnSelectorFactory;
import org.apache.druid.segment.ColumnValueSelector;
import org.apache.druid.segment.column.ColumnCapabilities;
import org.apache.druid.segment.column.ColumnHolder;
import org.apache.druid.segment.column.ValueType;
import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
import org.apache.druid.segment.vector.VectorValueSelector;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * This is an abstract class inherited by various {@link AggregatorFactory} implementations that consume double input
 * and produce double output on aggregation.
 * It extends "NullableAggregatorFactory<ColumnValueSelector>" instead of "NullableAggregatorFactory<BaseDoubleColumnValueSelector>"
 * to additionally support aggregation on single/multi value string column types.
 */
public abstract class SimpleDoubleAggregatorFactory extends NullableNumericAggregatorFactory<ColumnValueSelector>
{
  protected final String name;
  @Nullable
  protected final String fieldName;
  @Nullable
  protected final String expression;
  protected final ExprMacroTable macroTable;
  protected final boolean storeDoubleAsFloat;
  protected final Supplier<Expr> fieldExpression;

  public SimpleDoubleAggregatorFactory(
      ExprMacroTable macroTable,
      String name,
      @Nullable final String fieldName,
      @Nullable String expression
  )
  {
    this.macroTable = macroTable;
    this.name = name;
    this.fieldName = fieldName;
    this.expression = expression;
    this.storeDoubleAsFloat = ColumnHolder.storeDoubleAsFloat();
    this.fieldExpression = Parser.lazyParse(expression, macroTable);
    Preconditions.checkNotNull(name, "Must have a valid, non-null aggregator name");
    Preconditions.checkArgument(
        fieldName == null ^ expression == null,
        "Must have a valid, non-null fieldName or expression"
    );
  }

  @Override
  protected Aggregator factorize(ColumnSelectorFactory metricFactory, ColumnValueSelector selector)
  {
    if (shouldUseStringColumnAggregatorWrapper(metricFactory)) {
      return new StringColumnDoubleAggregatorWrapper(
          selector,
          SimpleDoubleAggregatorFactory.this::buildAggregator,
          nullValue()
      );
    } else {
      return buildAggregator(selector);
    }
  }

  @Override
  protected BufferAggregator factorizeBuffered(
      ColumnSelectorFactory metricFactory,
      ColumnValueSelector selector
  )
  {
    if (shouldUseStringColumnAggregatorWrapper(metricFactory)) {
      return new StringColumnDoubleBufferAggregatorWrapper(
          selector,
          SimpleDoubleAggregatorFactory.this::buildBufferAggregator,
          nullValue()
      );
    } else {
      return buildBufferAggregator(selector);
    }
  }

  @Override
  protected ColumnValueSelector selector(ColumnSelectorFactory metricFactory)
  {
    return AggregatorUtil.makeColumnValueSelectorWithDoubleDefault(
        metricFactory,
        fieldName,
        fieldExpression.get(),
        nullValue()
    );
  }

  @Override
  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
  {
    return AggregatorUtil.makeVectorValueSelector(columnSelectorFactory, fieldName, expression, fieldExpression);
  }

  private boolean shouldUseStringColumnAggregatorWrapper(ColumnSelectorFactory columnSelectorFactory)
  {
    if (fieldName != null) {
      ColumnCapabilities capabilities = columnSelectorFactory.getColumnCapabilities(fieldName);
      return capabilities != null && capabilities.getType() == ValueType.STRING;
    }
    return false;
  }

  @Override
  public Object deserialize(Object object)
  {
    // handle "NaN" / "Infinity" values serialized as strings in JSON
    if (object instanceof String) {
      return Double.parseDouble((String) object);
    }
    return object;
  }

  @Override
  public ValueType getType()
  {
    if (storeDoubleAsFloat) {
      return ValueType.FLOAT;
    }
    return ValueType.DOUBLE;
  }

  @Override
  public int getMaxIntermediateSize()
  {
    return Double.BYTES;
  }

  @Override
  public Comparator getComparator()
  {
    return DoubleSumAggregator.COMPARATOR;
  }

  @Override
  @Nullable
  public Object finalizeComputation(@Nullable Object object)
  {
    return object;
  }

  @Override
  public List<String> requiredFields()
  {
    return fieldName != null
           ? Collections.singletonList(fieldName)
           : fieldExpression.get().analyzeInputs().getRequiredBindingsList();
  }

  @Override
  public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException
  {
    if (other.getName().equals(this.getName()) && this.getClass() == other.getClass()) {
      return getCombiningFactory();
    } else {
      throw new AggregatorFactoryNotMergeableException(this, other);
    }
  }

  @Override
  public int hashCode()
  {
    return Objects.hash(fieldName, expression, name);
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    SimpleDoubleAggregatorFactory that = (SimpleDoubleAggregatorFactory) o;

    if (!Objects.equals(fieldName, that.fieldName)) {
      return false;
    }
    if (!Objects.equals(expression, that.expression)) {
      return false;
    }
    if (!Objects.equals(name, that.name)) {
      return false;
    }
    return true;
  }

  @Override
  @JsonProperty
  public String getName()
  {
    return name;
  }

  @Nullable
  @JsonProperty
  public String getFieldName()
  {
    return fieldName;
  }

  @Nullable
  @JsonProperty
  public String getExpression()
  {
    return expression;
  }

  @Override
  public boolean canVectorize(ColumnInspector columnInspector)
  {
    return AggregatorUtil.canVectorize(columnInspector, fieldName, expression, fieldExpression);
  }

  protected abstract double nullValue();

  protected abstract Aggregator buildAggregator(BaseDoubleColumnValueSelector selector);

  protected abstract BufferAggregator buildBufferAggregator(BaseDoubleColumnValueSelector selector);
}


text:
package Jan2021Leetcode;

public class _0404SumOfLeftLeaves {

	static public class TreeNode {
		int val;
		TreeNode left;
		TreeNode right;

		TreeNode() {
		}

		TreeNode(int val) {
			this.val = val;
		}

		TreeNode(int val, TreeNode left, TreeNode right) {
			this.val = val;
			this.left = left;
			this.right = right;
		}
	}

	public static void main(String[] args) {
		TreeNode tn = new TreeNode(3);
		tn.left = new TreeNode(9);
		tn.right = new TreeNode(20);
		tn.right.left = new TreeNode(15);
		tn.right.right = new TreeNode(7);
		System.out.println(sumOfLeftLeaves(tn));
	}

	public static int sumOfLeftLeaves(TreeNode root) {
		if (root == null)
			return 0;
		return sumOfLeftLeaves(root.left, true) + sumOfLeftLeaves(root.right, false);
	}

	public static int sumOfLeftLeaves(TreeNode root, boolean isLeft) {
		if (root == null)
			return 0;
		if (root.left == null && root.right == null) {
			return isLeft ? root.val : 0;
		}

		return sumOfLeftLeaves(root.left, true) + sumOfLeftLeaves(root.right, false);
	}

}


text:
module SolidusBraintree
  VERSION = "1.2.0"
end


text:
package com.nearby.app;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.nearby.app.repository.UserRepository;

@SpringBootApplication
@EnableAutoConfiguration
public class NearByServiceApiApplication {

	public static void main(String[] args) {
		SpringApplication.run(NearByServiceApiApplication.class, args);
	}

	@Bean
    CommandLineRunner init(final UserRepository accountRepository) {

		return new CommandLineRunner() {

        @Override
        public void run(String... arg0) throws Exception {
          //accountRepository.save(new User("arifali", "mondal17"));
        }

      };
	}
}