private static void appendSnapshotsToDelete(Interval interval, List<PurgeableAnalysisDto> toDelete) { if (interval.count() > 1) { List<PurgeableAnalysisDto> deletables = Lists.newArrayList(); List<PurgeableAnalysisDto> toKeep = Lists.newArrayList(); for (PurgeableAnalysisDto snapshot : interval.get()) { if (isDeletable(snapshot)) { deletables.add(snapshot); } else { toKeep.add(snapshot); } } if (!toKeep.isEmpty()) { toDelete.addAll(deletables); } else if (deletables.size() > 1) { // keep last snapshot toDelete.addAll(deletables.subList(0, deletables.size() - 1)); } } }
@Override public List<PurgeableAnalysisDto> filter(List<PurgeableAnalysisDto> history) { List<Interval> intervals = Interval.group(history, start, end, dateField); List<PurgeableAnalysisDto> result = Lists.newArrayList(); for (Interval interval : intervals) { appendSnapshotsToDelete(interval, result); } return result; }
static List<Interval> group(List<PurgeableAnalysisDto> snapshots, Date start, Date end, int calendarField) { List<Interval> intervals = Lists.newArrayList(); GregorianCalendar calendar = new GregorianCalendar(); int lastYear = -1; int lastFieldValue = -1; Interval currentInterval = null; for (PurgeableAnalysisDto snapshot : snapshots) { if (!DateUtils.isSameDay(start, snapshot.getDate()) && snapshot.getDate().after(start) && (snapshot.getDate().before(end) || DateUtils.isSameDay(end, snapshot.getDate()))) { calendar.setTime(snapshot.getDate()); int currentFieldValue = calendar.get(calendarField); int currentYear = calendar.get(Calendar.YEAR); if (lastYear != currentYear || lastFieldValue != currentFieldValue) { currentInterval = new Interval(); intervals.add(currentInterval); } lastFieldValue = currentFieldValue; lastYear = currentYear; if (currentInterval != null) { currentInterval.add(snapshot); } } } return intervals; } }
@Test public void shouldIgnoreTimeWhenGroupingByIntervals() { List<PurgeableAnalysisDto> snapshots = Arrays.asList( DbCleanerTestUtils.createAnalysisWithDateTime("u1", "2011-05-25T00:16:48+0100"), DbCleanerTestUtils.createAnalysisWithDateTime("u2", "2012-01-26T00:16:48+0100"), DbCleanerTestUtils.createAnalysisWithDateTime("u3", "2012-01-27T00:16:48+0100") ); List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDateTime("2011-05-25T00:00:00+0100"), DateUtils.parseDateTime("2012-01-26T00:00:00+0100"), Calendar.MONTH); assertThat(intervals.size()).isEqualTo(1); assertThat(intervals.get(0).count()).isEqualTo(1); assertThat(intervals.get(0).get().get(0).getAnalysisUuid()).isEqualTo(("u2")); } }
@Test public void shouldNotJoinMonthsOfDifferentYears() { List<PurgeableAnalysisDto> snapshots = Arrays.asList( DbCleanerTestUtils.createAnalysisWithDate("u1", "2010-04-03"), DbCleanerTestUtils.createAnalysisWithDate("u2", "2011-04-13") ); List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDateTime("2010-01-01T00:00:00+0100"), DateUtils.parseDateTime("2011-12-31T00:00:00+0100"), Calendar.MONTH); assertThat(intervals.size()).isEqualTo(2); assertThat(intervals.get(0).count()).isEqualTo(1); assertThat(calendarField(intervals.get(0), Calendar.MONTH)).isEqualTo((Calendar.APRIL)); assertThat(calendarField(intervals.get(0), Calendar.YEAR)).isEqualTo((2010)); assertThat(intervals.get(1).count()).isEqualTo(1); assertThat(calendarField(intervals.get(1), Calendar.MONTH)).isEqualTo((Calendar.APRIL)); assertThat(calendarField(intervals.get(1), Calendar.YEAR)).isEqualTo((2011)); }
@Test public void shouldGroupByIntervals() { List<PurgeableAnalysisDto> snapshots = Arrays.asList( DbCleanerTestUtils.createAnalysisWithDate("u1", "2011-04-03"), DbCleanerTestUtils.createAnalysisWithDate("u2", "2011-05-01"), DbCleanerTestUtils.createAnalysisWithDate("u3", "2011-05-19"), DbCleanerTestUtils.createAnalysisWithDate("u4", "2011-06-02"), DbCleanerTestUtils.createAnalysisWithDate("u5", "2011-06-20"), DbCleanerTestUtils.createAnalysisWithDate("u6", "2012-06-29") // out of scope ); List<Interval> intervals = Interval.group(snapshots, DateUtils.parseDate("2010-01-01"), DateUtils.parseDate("2011-12-31"), Calendar.MONTH); assertThat(intervals.size()).isEqualTo(3); assertThat(intervals.get(0).count()).isEqualTo(1); assertThat(calendarField(intervals.get(0), Calendar.MONTH)).isEqualTo((Calendar.APRIL)); assertThat(intervals.get(1).count()).isEqualTo(2); assertThat(calendarField(intervals.get(1), Calendar.MONTH)).isEqualTo((Calendar.MAY)); assertThat(intervals.get(2).count()).isEqualTo(2); assertThat(calendarField(intervals.get(2), Calendar.MONTH)).isEqualTo((Calendar.JUNE)); }
static List<Interval> group(List<PurgeableAnalysisDto> snapshots, Date start, Date end, int calendarField) { List<Interval> intervals = Lists.newArrayList(); GregorianCalendar calendar = new GregorianCalendar(); int lastYear = -1; int lastFieldValue = -1; Interval currentInterval = null; for (PurgeableAnalysisDto snapshot : snapshots) { if (!DateUtils.isSameDay(start, snapshot.getDate()) && snapshot.getDate().after(start) && (snapshot.getDate().before(end) || DateUtils.isSameDay(end, snapshot.getDate()))) { calendar.setTime(snapshot.getDate()); int currentFieldValue = calendar.get(calendarField); int currentYear = calendar.get(Calendar.YEAR); if (lastYear != currentYear || lastFieldValue != currentFieldValue) { currentInterval = new Interval(); intervals.add(currentInterval); } lastFieldValue = currentFieldValue; lastYear = currentYear; if (currentInterval != null) { currentInterval.add(snapshot); } } } return intervals; } }
@Override public List<PurgeableAnalysisDto> filter(List<PurgeableAnalysisDto> history) { List<Interval> intervals = Interval.group(history, start, end, dateField); List<PurgeableAnalysisDto> result = Lists.newArrayList(); for (Interval interval : intervals) { appendSnapshotsToDelete(interval, result); } return result; }
private void appendSnapshotsToDelete(Interval interval, List<PurgeableAnalysisDto> toDelete) { if (interval.count() > 1) { List<PurgeableAnalysisDto> deletables = Lists.newArrayList(); List<PurgeableAnalysisDto> toKeep = Lists.newArrayList(); for (PurgeableAnalysisDto snapshot : interval.get()) { if (isDeletable(snapshot)) { deletables.add(snapshot); } else { toKeep.add(snapshot); } } if (!toKeep.isEmpty()) { toDelete.addAll(deletables); } else if (deletables.size() > 1) { // keep last snapshot toDelete.addAll(deletables.subList(0, deletables.size() - 1)); } } }