@Override
    public void postCollect() {
      final FixedBitSet allVisitedOrds = new FixedBitSet(maxOrd);
      for (long bucket = visitedOrds.size() - 1; bucket >= 0; --bucket) {
        final FixedBitSet bits = visitedOrds.get(bucket);
        if (bits != null) {
          allVisitedOrds.or(bits);
        }
      }

      final org.elasticsearch.common.hash.MurmurHash3.Hash128 hash =
          new org.elasticsearch.common.hash.MurmurHash3.Hash128();
      try (LongArray hashes = bigArrays.newLongArray(maxOrd, false)) {
        for (int ord = allVisitedOrds.nextSetBit(0);
            ord != -1;
            ord = ord + 1 < maxOrd ? allVisitedOrds.nextSetBit(ord + 1) : -1) {
          final BytesRef value = values.lookupOrd(ord);
          org.elasticsearch.common.hash.MurmurHash3.hash128(
              value.bytes, value.offset, value.length, 0, hash);
          hashes.set(ord, hash.h1);
        }

        for (long bucket = visitedOrds.size() - 1; bucket >= 0; --bucket) {
          final FixedBitSet bits = visitedOrds.get(bucket);
          if (bits != null) {
            for (int ord = bits.nextSetBit(0);
                ord != -1;
                ord = ord + 1 < maxOrd ? bits.nextSetBit(ord + 1) : -1) {
              counts.collect(bucket, hashes.get(ord));
            }
          }
        }
      }
    }
 @Override
 public void collect(int doc, long bucketOrd) {
   visitedOrds = bigArrays.grow(visitedOrds, bucketOrd + 1);
   FixedBitSet bits = visitedOrds.get(bucketOrd);
   if (bits == null) {
     bits = new FixedBitSet(maxOrd);
     visitedOrds.set(bucketOrd, bits);
   }
   values.setDocument(doc);
   final int valueCount = values.cardinality();
   for (int i = 0; i < valueCount; ++i) {
     bits.set((int) values.ordAt(i));
   }
 }