From 9768728c925cde44d527c1adca7e68e1369790c7 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 31 Aug 2024 14:58:08 -0500 Subject: [PATCH] Add RollingAverage object --- .../core/util/objects/RollingAverage.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/util/objects/RollingAverage.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/RollingAverage.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/RollingAverage.java new file mode 100644 index 000000000..366ee40bc --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/RollingAverage.java @@ -0,0 +1,111 @@ +package com.seibel.distanthorizons.core.util.objects; + +import java.util.Arrays; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * This can be used for easily profiling methods to get the average execution time.
+ * This is a thread safe implementation. + */ +public class RollingAverage +{ + // properties // + + private final double[] values; + private final int size; + private int index = 0; + private double sum = 0.0; + private final Lock arrayLock = new ReentrantLock(); + + + + //=============// + // constructor // + //=============// + + public RollingAverage(int size) + { + if (size <= 0) + { + throw new IllegalArgumentException("Size must be greater than 0"); + } + + this.size = size; + this.values = new double[size]; + } + + + + //=======// + // input // + //=======// + + public void addValue(double value) + { + this.arrayLock.lock(); + try + { + // Subtract the oldest value from the sum + this.sum -= this.values[this.index]; + // Update the buffer with the new value + this.values[this.index] = value; + // Add the new value to the sum + this.sum += value; + // Move to the next index + this.index = (this.index + 1) % this.size; + } + finally + { + this.arrayLock.unlock(); + } + } + + public void clear() + { + this.arrayLock.lock(); + try + { + this.sum = 0; + this.index = 0; + Arrays.fill(this.values, 0); + } + finally + { + this.arrayLock.unlock(); + } + } + + + + //========// + // output // + //========// + + /** Gets the current rolling average. */ + public double getAverage() + { + this.arrayLock.lock(); + try + { + return (this.sum / this.size); + } + finally + { + this.arrayLock.unlock(); + } + } + /** rounded to two decimals*/ + public String getAverageRoundedString() { return String.format("%.2f", this.getAverage()); } + + + + //================// + // base overrides // + //================// + + @Override + public String toString() { return "avg: "+this.getAverageRoundedString()+" max count: "+this.size; } + +} +