private static Map<TableName, Map<String, Long>>
      loadIncrementalTimestampMap(BackupProtos.BackupImage proto) {
      List<BackupProtos.TableServerTimestamp> list = proto.getTstMapList();

      Map<TableName, Map<String, Long>> incrTimeRanges = new HashMap<>();

      if (list == null || list.size() == 0) {
        return incrTimeRanges;
      }

      for (BackupProtos.TableServerTimestamp tst : list) {
        TableName tn = ProtobufUtil.toTableName(tst.getTableName());
        Map<String, Long> map = incrTimeRanges.get(tn);
        if (map == null) {
          map = new HashMap<>();
          incrTimeRanges.put(tn, map);
        }
        List<BackupProtos.ServerTimestamp> listSt = tst.getServerTimestampList();
        for (BackupProtos.ServerTimestamp stm : listSt) {
          ServerName sn = ProtobufUtil.toServerName(stm.getServerName());
          map.put(sn.getHostname() + ":" + sn.getPort(), stm.getTimestamp());
        }
      }
      return incrTimeRanges;
    }
This method deliberately does not include the backup root dir on the produced proto. This is
because we don't want to persist the root dir on the backup itself, so that backups can still
be used after they have moved locations. A restore's operator will always provide the root
dir.
hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupManifest.java