protected final MatchCode tryDropDelete(ExtendedCell cell) {
    long timestamp = cell.getTimestamp();
    // If it is not the time to drop the delete marker, just return
    if (timeToPurgeDeletes > 0 && now - timestamp <= timeToPurgeDeletes) {
      return MatchCode.INCLUDE;
    }
    if (
      keepDeletedCells == KeepDeletedCells.TRUE
        || (keepDeletedCells == KeepDeletedCells.TTL && timestamp >= oldestUnexpiredTS)
    ) {
      // If keepDeletedCell is true, or the delete marker is not expired yet, we should include it
      // in version counting to see if we can drop it. The only exception is that, we can make
      // sure that no put is older than this delete marker. And under this situation, all later
      // cells of this column(must be delete markers) can be skipped.
      if (timestamp < earliestPutTs) {
        return columns.getNextRowOrNextColumn(cell);
      } else {
        return null;
      }
    } else {
      return MatchCode.SKIP;
    }
  }
Oldest put in any of the involved store files Used to decide whether it is ok to delete family
delete marker of this store keeps deleted KVs.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/DropDeletesCompactionScanQueryMatcher.java