public KVSorterIterator sortedIterator() throws IOException {
        try {
            final UnsafeSorterIterator underlying = sorter.getSortedIterator();
            if (!underlying.hasNext()) {
                // Since we won't ever call next() on an empty iterator, we need to clean up resources
                // here in order to prevent memory leaks.
                cleanupResources();
            }
            return new KVSorterIterator(underlying);
        } catch (IOException e) {
            cleanupResources();
            throw e;
        }
    }
Returns a sorted iterator. It is the caller's responsibility to call `cleanupResources()`
after consuming this iterator.
indexr-query-opt/src/main/java/org/apache/spark/sql/execution/UnsafeKVExternalSorter.java