private Map<Address, Long> serverToPreservationBoundaryTs(List<BackupInfo> backups)
    throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug(
        "Cleaning WALs if they are older than the WAL cleanup time-boundary. "
          + "Checking WALs against {} backups: {}",
        backups.size(),
        backups.stream().map(BackupInfo::getBackupId).sorted().collect(Collectors.joining(", ")));
    }

    // This map tracks, for every backup root, the most recent created backup (= highest timestamp)
    Map<String, BackupInfo> newestBackupPerRootDir = new HashMap<>();
    for (BackupInfo backup : backups) {
      BackupInfo existingEntry = newestBackupPerRootDir.get(backup.getBackupRootDir());
      if (existingEntry == null || existingEntry.getStartTs() < backup.getStartTs()) {
        newestBackupPerRootDir.put(backup.getBackupRootDir(), backup);
      }
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("WAL cleanup time-boundary using info from: {}. ",
        newestBackupPerRootDir.entrySet().stream()
          .map(e -> "Backup root " + e.getKey() + ": " + e.getValue().getBackupId()).sorted()
          .collect(Collectors.joining(", ")));
    }

    // This map tracks, for every RegionServer, the least recent (= oldest / lowest timestamp)
    // inclusion in any backup. In other words, it is the timestamp boundary up to which all backup
    // roots have included the WAL in their backup.
    Map<Address, Long> boundaries = new HashMap<>();
    for (BackupInfo backupInfo : newestBackupPerRootDir.values()) {
      // Iterate over all tables in the timestamp map, which contains all tables covered in the
      // backup root, not just the tables included in that specific backup (which could be a subset)
      for (TableName table : backupInfo.getTableSetTimestampMap().keySet()) {
        for (Map.Entry<String, Long> entry : backupInfo.getTableSetTimestampMap().get(table)
          .entrySet()) {
          Address address = Address.fromString(entry.getKey());
          Long storedTs = boundaries.get(address);
          if (storedTs == null || entry.getValue() < storedTs) {
            boundaries.put(address, entry.getValue());
          }
        }
      }
    }

    if (LOG.isDebugEnabled()) {
      for (Map.Entry<Address, Long> entry : boundaries.entrySet()) {
        LOG.debug("Server: {}, WAL cleanup boundary: {}", entry.getKey().getHostName(),
          entry.getValue());
      }
    }

    return boundaries;
  }
Calculates the timestamp boundary up to which all backup roots have already included the WAL.
I.e. WALs with a lower (= older) or equal timestamp are no longer needed for future incremental
backups.
hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/master/BackupLogCleaner.java