private void flushDeletes() {
    if (posDeletes.isEmpty()) {
      return;
    }

    EncryptedOutputFile outputFile = fileFactory.newOutputFile(writerKey);
    PositionDeleteWriter<T> writer =
        io.doAs(
            () ->
                appenderFactory.newPosDeleteWriter(
                    outputFile, format, writerKey.getPartitionKey()));
    try (PositionDeleteWriter<T> closeableWriter = writer) {
      // Sort all the paths.
      List<CharSequence> paths = Lists.newArrayListWithCapacity(posDeletes.keySet().size());
      for (CharSequenceWrapper charSequenceWrapper : posDeletes.keySet()) {
        paths.add(charSequenceWrapper.get());
      }
      paths.sort(Comparators.charSequences());

      // Write all the sorted <path, pos, row> triples.
      PositionDelete<T> positionDelete = PositionDelete.create();
      for (CharSequence path : paths) {
        List<PosRow<T>> positions = posDeletes.get(wrapper.set(path));
        positions.sort(Comparator.comparingLong(PosRow::pos));

        positions.forEach(
            posRow -> closeableWriter.write(positionDelete.set(path, posRow.pos(), posRow.row())));
      }
    } catch (IOException e) {
      throw new UncheckedIOException(
          "Failed to write the sorted path/pos pairs to pos-delete file: "
              + outputFile.encryptingOutputFile().location(),
          e);
    }

    // Clear the buffered pos-deletions.
    posDeletes.clear();
    records = 0;

    // Add the referenced data files.
    referencedDataFiles.addAll(writer.referencedDataFiles());

    // Add the completed delete files.
    completedFiles.add(writer.toDeleteFile());
  }
Abstract implementation of positional delete writer for {@link BaseTable}.

@param <T> to indicate the record data type.
amoro-format-iceberg/src/main/java/org/apache/amoro/io/writer/SortedPosDeleteWriter.java