bb.science
Class StatsOverTime

java.lang.Object
  extended by bb.science.StatsOverTime

public class StatsOverTime
extends Object

Stores statistics over time of an arbitrary data source.

To understand how this class operates, imagine that time is divided into equal sized bins. Whenever the data source generates a value, it is stored in the bin for the time when the value occurred. Statistics for the data in each bin can therefore be calculated; this class stores the min, max, mean, and median. This class also records the bins size (i.e. the number of data values that were added).

The reason why time is divided into bins is because these bin statistics can then be analysed to see how the statistics change over time. For example, you could plot the bin mean versus the time of the bin (its first time) to see how the mean changes.

Each bin is characterised by its start time and its length. To be precise, a bin covers the semi-open time interval [binStart, binStart + binLength).

In order to save memory, the current version of this class only stores the raw data values for the current bin under consideration. As soon as a time of occurence arrives which is outside of this current bin, the current bin is converted into its summary statistics (which hopefully frees a lot of memory) and a new bin is formed. It is an error if a time of occurrence arrives which falls into a previously considered bin. This is not a major limitation, since it will never happen for a data source that is generating data in real time, since time flows in one direction.

This class is not multithread safe.

Author:
Brent Boyer
See Also:
Samples

Nested Class Summary
private static class StatsOverTime.Stats
           
static class StatsOverTime.UnitTest
          See the Overview page of the project's javadocs for a general description of this unit test class.
 
Field Summary
private  long binLength
          Length of time (in milliseconds) of every bin.
private static long binLength_default
          Default value for binLength.
private  Date binStart
          Stores the start Date of the current bin.
private  SortedMap<Date,StatsOverTime.Stats> dateToStats
          Maps a bin's start Date to its Stats.
private  Samples samples
          Stores the data values of the current bin.
 
Constructor Summary
StatsOverTime()
          Calls this(binLength_default).
StatsOverTime(long binLength)
          Fundamental constructor.
 
Method Summary
 void add(Date date, double value)
          Adds value to the bin appropriate for date.
 void addElseLog(Date date, double value, Logger2 logger2)
          Chiefly just calls add(date, value).
private  void calcStatsOfCurrentBin()
          May be repeatedly called (e.g. by toString) on the current bin, as it will simply overwrite the previous mapping.
private  void createNewBin(Date date)
           
private  boolean isInCurrentBin(Date date)
           
 String toString()
          Returns a string report describing the statsistics over time.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

binLength_default

private static final long binLength_default
Default value for binLength.

See Also:
Constant Field Values

binStart

private Date binStart
Stores the start Date of the current bin.

Contract: is never null after the first call to add.


binLength

private final long binLength
Length of time (in milliseconds) of every bin.

Contract: must be > 0.


samples

private Samples samples
Stores the data values of the current bin.

Contract: is never null after the first call to add.


dateToStats

private final SortedMap<Date,StatsOverTime.Stats> dateToStats
Maps a bin's start Date to its Stats.

Contract: is never null, but may be empty, and never contains a null key or value.

Constructor Detail

StatsOverTime

public StatsOverTime()
Calls this(binLength_default).


StatsOverTime

public StatsOverTime(long binLength)
              throws IllegalArgumentException
Fundamental constructor.

Throws:
IllegalArgumentException - if binLength is not positive
Method Detail

addElseLog

public void addElseLog(Date date,
                       double value,
                       Logger2 logger2)
Chiefly just calls add(date, value). However, in the event that any Throwable occurs, this method attempts to always log it to logger2, and if that raises yet another Throwable, tries to log it to LogUtil.getLogger2. So, it is unlikely that this method should ever throw any type of Throwable.

The original motivation for this method was to handle occaisional failures to add. In particular, add (via createNewBin) throws an IllegalStateException if date was refers to a previous bin. This can occur when the operating system resets time to jump backwards. Relevant causes for these backwards jumps are timezone change days, corrections from a time server, or (in theory) negative leap second days (which have yet to occur in practice).


add

public void add(Date date,
                double value)
         throws IllegalArgumentException,
                IllegalStateException
Adds value to the bin appropriate for date.

Throws:
IllegalArgumentException - if date is null; value is not normal;
IllegalStateException - if date falls in a bin that has already been considered by this instance (and this instance has moved on to at least one other different bin)

toString

public String toString()
Returns a string report describing the statsistics over time.

If no data has actually been added to this instance, then the result simply states that.

Otherwise, the result has multiple lines. The first line is a column header line, and all the remaining lines are the bin statistics, in ascending time order of the bins. Each line is tab delimted, so the result is immediately usable by external programs (e.g. can be pasted into a spreadsheet and graphed).

Overrides:
toString in class Object

isInCurrentBin

private boolean isInCurrentBin(Date date)
                        throws IllegalArgumentException
Throws:
IllegalArgumentException

createNewBin

private void createNewBin(Date date)
                   throws IllegalArgumentException,
                          IllegalStateException
Throws:
IllegalArgumentException
IllegalStateException

calcStatsOfCurrentBin

private void calcStatsOfCurrentBin()
May be repeatedly called (e.g. by toString) on the current bin, as it will simply overwrite the previous mapping.