public static <T> long LazyMovingImmediateAverage( final int periods, final int interval_secs, final LazyMovingImmediateAverageAdapter<T> adapter, final T instance) { LazyMovingImmediateAverageState current = adapter.getCurrent(instance); if (current == null) { final LazyMovingImmediateAverageState state = current = new LazyMovingImmediateAverageState(); SimpleTimer.addTickReceiver( new TimerTickReceiver() { public void tick(long mono_now, int tick_count) { long now = SystemTime.getMonotonousTime(); if (now - state.last_read > 60 * 1000) { SimpleTimer.removeTickReceiver(this); adapter.setCurrent(instance, null); } else if (tick_count % interval_secs == 0) { long value = adapter.getValue(instance); long last = state.last_value; long diff = value - last; if (last >= 0 && diff >= 0) { MovingImmediateAverage average = state.average; if (diff == 0) { state.consec_zeros++; } else { state.consec_zeros = 0; } if (average == null) { if (diff > 0) { state.average = average = MovingImmediateAverage(periods); int zeros_to_do = Math.min(state.consec_zeros, periods); for (int i = 0; i < zeros_to_do; i++) { average.update(0); } } } if (average != null) { long ave = (long) average.update(diff); if (ave == 0 && average.getSampleCount() >= periods) { // looks pretty dead state.average = null; } } } state.last_value = value; } } }); adapter.setCurrent(instance, current); } else { current.last_read = SystemTime.getMonotonousTime(); } MovingImmediateAverage average = current.average; if (average == null) { return (0); } else { return ((long) average.getAverage() / interval_secs); } }