TimeWindowedList { public synchronized List<TimestampedValue<T>> getValuesInWindow(long now, Duration subTimePeriod) { long startTime = now - subTimePeriod.toMilliseconds(); List<TimestampedValue<T>> result = new LinkedList<TimestampedValue<T>>(); TimestampedValue<T> mostRecentExpired = null; for (TimestampedValue<T> val : values) { if (val.getTimestamp() < startTime) { mostRecentExpired = val; } else { result.add(val); } } if (minExpiredVals > 0 && mostRecentExpired != null) { result.add(0, mostRecentExpired); } if (result.size() < minVals) { int minIndex = Math.max(0, values.size()-minVals); return ImmutableList.copyOf(values.subList(minIndex, values.size())); } else { return result; } } TimeWindowedList(Duration timePeriod);  TimeWindowedList(Map<String,?> flags); void setTimePeriod(Duration newTimePeriod); synchronized T getLatestValue(); List<TimestampedValue<T>> getValues(); synchronized List<TimestampedValue<T>> getValues(long now); synchronized List<TimestampedValue<T>> getValuesInWindow(long now, Duration subTimePeriod); void add(T val); synchronized void add(T val, long timestamp); synchronized void pruneValues(long now); @Override String toString();  }
@Test public void testGetsWindowWithMinWhenEmpty() { TimeWindowedList list = new TimeWindowedList<Object>(MutableMap.of("timePeriod", 1L, "minVals", 1)); assertEquals(list.getValuesInWindow(1000L, TEN_MILLISECONDS), timestampedValues()); }
@Test public void testGetsWindowWithMinExpiredWhenEmpty() { TimeWindowedList list = new TimeWindowedList<Object>(MutableMap.of("timePeriod", 1L, "minExpiredVals", 1)); assertEquals(list.getValuesInWindow(1000L, TEN_MILLISECONDS), timestampedValues()); }