/** {@inheritDoc} */
 public void setNextReader(LeafReaderContext ctx) throws IOException {
   if (valueSource == null) {
     // first time we've collected local values, get the right ValueSource
     valueSource = (null == ft) ? statsField.getValueSource() : ft.getValueSource(sf, null);
     vsContext = ValueSource.newContext(statsField.getSearcher());
   }
   values = valueSource.getValues(vsContext, ctx);
 }
  protected AbstractStatsValues(StatsField statsField) {
    this.statsField = statsField;
    this.computeCount = statsField.calculateStats(Stat.count);
    this.computeMissing = statsField.calculateStats(Stat.missing);
    this.computeCalcDistinct =
        statsField.calculateStats(Stat.countDistinct)
            || statsField.calculateStats(Stat.distinctValues);
    this.computeMin = statsField.calculateStats(Stat.min);
    this.computeMax = statsField.calculateStats(Stat.max);
    this.computeMinOrMax = computeMin || computeMax;

    this.distinctValues = computeCalcDistinct ? new TreeSet<T>() : null;

    this.computeCardinality = statsField.calculateStats(Stat.cardinality);
    if (computeCardinality) {

      hasher = statsField.getHllOptions().getHasher();
      hll = statsField.getHllOptions().newHLL();
      assert null != hll : "Cardinality requires an HLL";
    } else {
      hll = null;
      hasher = null;
    }

    // alternatively, we could refactor a common base class that doesn't know/care
    // about either SchemaField or ValueSource - but then there would be a lot of
    // duplicate code between "NumericSchemaFieldStatsValues" and
    // "NumericValueSourceStatsValues" which would have diff parent classes
    //
    // part of the complexity here being that the StatsValues API serves two
    // masters: collecting concrete Values from things like DocValuesStats and
    // the distributed aggregation logic, but also collecting docIds which it
    // then
    // uses to go out and pull concreate values from the ValueSource
    // (from a func, or single valued field)
    if (null != statsField.getSchemaField()) {
      assert null == statsField.getValueSource();
      this.sf = statsField.getSchemaField();
      this.ft = sf.getType();
    } else {
      assert null != statsField.getValueSource();
      assert null == statsField.getSchemaField();
      this.sf = null;
      this.ft = null;
    }
  }