@Override
  public void flush(SegmentWriteState state, Sorter.DocMap sortMap, DocValuesConsumer dvConsumer)
      throws IOException {
    final int valueCount = hash.size();
    final PackedLongValues ords;
    final int[] sortedValues;
    final int[] ordMap;
    if (finalOrds == null) {
      sortedValues = hash.sort();
      ords = pending.build();
      ordMap = new int[valueCount];
      for (int ord = 0; ord < valueCount; ord++) {
        ordMap[sortedValues[ord]] = ord;
      }
    } else {
      sortedValues = finalSortedValues;
      ords = finalOrds;
      ordMap = finalOrdMap;
    }

    final int[] sorted;
    if (sortMap != null) {
      sorted =
          sortDocValues(
              state.segmentInfo.maxDoc(),
              sortMap,
              new BufferedSortedDocValues(
                  hash, valueCount, ords, sortedValues, ordMap, docsWithField.iterator()));
    } else {
      sorted = null;
    }
    dvConsumer.addSortedField(
        fieldInfo,
        new EmptyDocValuesProducer() {
          @Override
          public SortedDocValues getSorted(FieldInfo fieldInfoIn) {
            if (fieldInfoIn != fieldInfo) {
              throw new IllegalArgumentException("wrong fieldInfo");
            }
            final SortedDocValues buf =
                new BufferedSortedDocValues(
                    hash, valueCount, ords, sortedValues, ordMap, docsWithField.iterator());
            if (sorted == null) {
              return buf;
            }
            return new SortingLeafReader.SortingSortedDocValues(buf, sorted);
          }
        });
  }