The class below implements an exponentially time-decaying counter. The rate of the decay is defined by it's half-life, which is specified in seconds.
/** * An exponentially time-decaying counter. * @author Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz **/ public class DecayingCounter { private double value; private long time; private final double tau; /** * Creates a new decaying counter with an initial value of 0. * @param halfLife * half-life in seconds. **/ public DecayingCounter (double halfLife) { this(halfLife, 0.0); } /** * Creates a new decaying counter. * @param halfLife * half-life in seconds. * @param initialValue * initial value of the counter. **/ public DecayingCounter (double halfLife, double initialValue) { tau = halfLife / Math.log(2.0); set(initialValue); } /** * Sets the counter to a new value. **/ public void set (double newValue) { value = newValue; time = System.nanoTime(); } /** * Returns the current counter value. **/ public double get() { update(); return value; } /** * Increments the counter by 1 and returns the new value. **/ public double increment() { update(); value += 1.0; return value; } private void update() { long newTime = System.nanoTime(); long deltaTime = newTime - time; if (deltaTime > 0) value *= Math.exp(deltaTime * -1E-9 / tau); time = newTime; } } // end class DecayingCounter
// A simple test program for the DecayingCounter class. public class TestDecayingCounter { public static void main (String[] args) throws Exception { DecayingCounter counter = new DecayingCounter(2.0, 8.0); // Half-life 2 seconds, initial value 8. int ctr2 = 12; // first increment after 6 seconds while (true) { System.out.println(counter.get()); Thread.sleep(500); // wait for half a second if (ctr2-- <= 0) { System.out.println ("--- increment ---"); counter.increment(); ctr2 = 6; }}} // next increment after 3 seconds } // end class TestDeayingCounter
Author: Christian d'Heureuse (www.source-code.biz, www.inventec.ch/chdh)
License: Free
Index