Iris/src/main/java/com/volmit/iris/util/AtomicAverage.java
2020-12-04 05:07:44 -05:00

96 lines
1.6 KiB
Java

package com.volmit.iris.util;
import com.google.common.util.concurrent.AtomicDoubleArray;
/**
* Provides an incredibly fast averaging object. It swaps values from a sum
* using an array. Averages do not use any form of looping. An average of 10,000
* entries is the same speed as an average with 5 entries.
*
* @author cyberpwn
*
*/
public class AtomicAverage {
protected AtomicDoubleArray values;
private double average;
private double lastSum;
private boolean dirty;
protected int cursor;
private boolean brandNew;
/**
* Create an average holder
*
* @param size the size of entries to keep
*/
public AtomicAverage(int size) {
values = new AtomicDoubleArray(size);
DoubleArrayUtils.fill(values, 0);
brandNew = true;
average = 0;
cursor = 0;
lastSum = 0;
dirty = false;
}
/**
* Put a value into the average (rolls over if full)
*
* @param i the value
*/
public void put(double i) {
try
{
dirty = true;
if(brandNew)
{
DoubleArrayUtils.fill(values, i);
lastSum = size() * i;
brandNew = false;
return;
}
double current = values.get(cursor);
lastSum = (lastSum - current) + i;
values.set(cursor, i);
cursor = cursor + 1 < size() ? cursor + 1 : 0;
}
catch(Throwable e)
{
}
}
/**
* Get the current average
*
* @return the average
*/
public double getAverage() {
if (dirty) {
calculateAverage();
return getAverage();
}
return average;
}
private void calculateAverage() {
average = lastSum / (double) size();
dirty = false;
}
public int size()
{
return values.length();
}
public boolean isDirty()
{
return dirty;
}
}