public synchronized void add(T val, long timestamp) { values.add(values.size(), new TimestampedValue<T>(val, timestamp)); pruneValues(timestamp); }
@Override public boolean equals(Object other) { if (!(other instanceof TimestampedValue)) { return false; } TimestampedValue<?> o = (TimestampedValue<?>) other; return o.getTimestamp() == timestamp && Objects.equal(o.getValue(), value); }
/** * @return null if empty, or the most recent value */ private <T extends Number> T latestInWindow(List<TimestampedValue<T>> vals) { return vals.isEmpty() ? null : vals.get(vals.size()-1).getValue(); } }
public synchronized void pruneValues(long now) { long startTime = now - timePeriod.toMilliseconds(); int expiredValsCount = 0; if (timePeriod.equals(Duration.ZERO)) { expiredValsCount = values.size(); } else { for (TimestampedValue<T> val : values) { if (val.getTimestamp() < startTime) { expiredValsCount++; } else { break; } } } int numToPrune = Math.min(expiredValsCount - minExpiredVals, values.size()-minVals); for (int i = 0; i < numToPrune; i++) { values.removeFirst(); } }
public synchronized T getLatestValue() { return (values.isEmpty()) ? null : values.get(values.size()-1).getValue(); }
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) { // discard; but remember most recent too-old value so we include that as the "initial" 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; } }
/** * If the entire time-window is not covered by the given values, then returns Integer.MIN_VALUE */ private <T extends Number> T minInWindow(List<TimestampedValue<T>> vals, Duration timeWindow) { long now = System.currentTimeMillis(); long epoch = now - timeWindow.toMilliseconds(); T result = null; double resultAsDouble = Integer.MIN_VALUE; for (TimestampedValue<T> val : vals) { T valAsNum = val.getValue(); double valAsDouble = (valAsNum != null) ? valAsNum.doubleValue() : 0; if (result == null && val.getTimestamp() > epoch) { result = withDefault(null, Integer.MIN_VALUE); resultAsDouble = result.doubleValue(); } if (result == null || (val.getValue() != null && valAsDouble < resultAsDouble)) { result = valAsNum; resultAsDouble = valAsDouble; } } return withDefault(result, Integer.MIN_VALUE); }
private <T> List<TimestampedValue<T>> timestampedValues(T v1, long t1, T v2, long t2) { return Lists.newArrayList(new TimestampedValue<T>(v1, t1), new TimestampedValue<T>(v2, t2)); } }
/** * If the entire time-window is not covered by the given values, then returns Integer.MAX_VALUE. */ private <T extends Number> T maxInWindow(List<TimestampedValue<T>> vals, Duration timeWindow) { // TODO bad casting from Integer default result to T long now = System.currentTimeMillis(); long epoch = now - timeWindow.toMilliseconds(); T result = null; double resultAsDouble = Integer.MAX_VALUE; for (TimestampedValue<T> val : vals) { T valAsNum = val.getValue(); double valAsDouble = (valAsNum != null) ? valAsNum.doubleValue() : 0; if (result == null && val.getTimestamp() > epoch) { result = withDefault(null, Integer.MAX_VALUE); resultAsDouble = result.doubleValue(); } if (result == null || (valAsNum != null && valAsDouble > resultAsDouble)) { result = valAsNum; resultAsDouble = valAsDouble; } } return withDefault(result, Integer.MAX_VALUE); }
private <T> List<TimestampedValue<T>> timestampedValues(T v1, long t1) { return Lists.newArrayList(new TimestampedValue<T>(v1, t1)); }