private Map<Instant, DataRetentionTracker> getTrackersByEarliestCreateTime(
            final DataRetentionRules dataRetentionRules,
            final Map<Instant, Set<DataRetentionRule>> earliestRetainedCreationTimeMap) {

        // All valid trackers key by their rule age, e.g. "30 Days", "Forever", etc.
        final Map<String, DataRetentionTracker> trackersByRuleAge = getTrackers(dataRetentionRules);

        final Map<Instant, DataRetentionTracker> trackersByEarliestCreateTime =
                earliestRetainedCreationTimeMap.keySet()
                        .stream()
                        .map(createTime -> {
                            final String ruleAge = getRuleAge(earliestRetainedCreationTimeMap, createTime);
                            return Tuple.of(createTime, trackersByRuleAge.get(ruleAge));
                        })
                        .filter(tuple2 ->
                                tuple2._2() != null)
                        .collect(Collectors.toMap(
                                Tuple2::_1, Tuple2::_2));

        LOGGER.debug(() -> LogUtil.message("trackersByEarliestCreateTime:\n{}",
                trackersByEarliestCreateTime.entrySet()
                        .stream()
                        .sorted(Entry.comparingByKey())
                        .map(entry ->
                                "createTime: "
                                        + entry.getKey()
                                        + " => (ruleAge: "
                                        + entry.getValue().getRuleAge()
                                        + ", lastRunTime: "
                                        + entry.getValue().getLastRunTime())
                        .collect(Collectors.joining("\n"))));

        return trackersByEarliestCreateTime;
    }
Pkg private so we can test with a known now time
stroom-data/stroom-data-retention-impl/src/main/java/stroom/data/retention/impl/DataRetentionPolicyExecutor.java