presto-orc/src/main/java/io/prestosql/orc/writer/SliceDictionaryColumnWriter.java/SliceDictionaryColumnWriter/tryConvertToDirect
class SliceDictionaryColumnWriter:    @Override
    public OptionalInt tryConvertToDirect(int maxDirectBytes)
    {
        checkState(!closed);
        checkState(!directEncoded);
        if (directColumnWriter == null) {
            directColumnWriter = new SliceDirectColumnWriter(columnId, type, compression, bufferSize, this::newStringStatisticsBuilder);
        }
        checkState(directColumnWriter.getBufferedBytes() == 0);

        Block dictionaryValues = dictionary.getElementBlock();
        for (DictionaryRowGroup rowGroup : rowGroups) {
            directColumnWriter.beginRowGroup();
            // todo we should be able to pass the stats down to avoid recalculating min and max
            boolean success = writeDictionaryRowGroup(dictionaryValues, rowGroup.getValueCount(), rowGroup.getDictionaryIndexes(), maxDirectBytes);
            directColumnWriter.finishRowGroup();

            if (!success) {
                directColumnWriter.close();
                directColumnWriter.reset();
                return OptionalInt.empty();
            }
        }

        if (inRowGroup) {
            directColumnWriter.beginRowGroup();
            if (!writeDictionaryRowGroup(dictionaryValues, rowGroupValueCount, values, maxDirectBytes)) {
                directColumnWriter.close();
                directColumnWriter.reset();
                return OptionalInt.empty();
            }
        }
        else {
            checkState(rowGroupValueCount == 0);
        }

        rowGroups.clear();

        // free the dictionary
        dictionary.clear();

        rawBytes = 0;
        totalValueCount = 0;
        totalNonNullValueCount = 0;

        rowGroupValueCount = 0;
        statisticsBuilder = newStringStatisticsBuilder();

        directEncoded = true;

        return OptionalInt.of(toIntExact(directColumnWriter.getBufferedBytes()));
    }