Skip to content

Commit

Permalink
RunningAverage: basic cleanup of MedianMeanRunningAverage
Browse files Browse the repository at this point in the history
This fixes lack of synchronization in the copy constructor, removes
all the empty javadoc and generally improves code style.
  • Loading branch information
bertm committed Oct 13, 2024
1 parent 9a09bb3 commit 8b78902
Showing 1 changed file with 58 additions and 76 deletions.
134 changes: 58 additions & 76 deletions src/freenet/support/math/MedianMeanRunningAverage.java
Original file line number Diff line number Diff line change
@@ -1,98 +1,80 @@
package freenet.support.math;

import java.util.ArrayList;
import java.util.Collections;

/**
* A RunningAverage that tracks both the median and mean of a series of values.
* WARNING: Uses memory and proportional to the number of reports! Only for debugging!
* (Also uses CPU time O(N log N) with the number of reports in currentValue()).
*
* @author Matthew Toseland <[email protected]> (0xE43DA450)
*/
public final class MedianMeanRunningAverage implements RunningAverage, Cloneable {
private static final long serialVersionUID = 1L;

final ArrayList<Double> reports;
final TrivialRunningAverage mean;
private final ArrayList<Double> reports = new ArrayList<>();
private final TrivialRunningAverage mean;

/**
*
*/
public MedianMeanRunningAverage() {
reports = new ArrayList<Double>();
mean = new TrivialRunningAverage();
}
public MedianMeanRunningAverage() {
mean = new TrivialRunningAverage();
}

/**
*
* @param average
*/
public MedianMeanRunningAverage(MedianMeanRunningAverage average) {
this.mean = new TrivialRunningAverage(average.mean);
this.reports = new ArrayList<Double>();
reports.addAll(average.reports);
}
public MedianMeanRunningAverage(MedianMeanRunningAverage other) {
synchronized (other.reports) {
this.mean = new TrivialRunningAverage(other.mean);
this.reports.addAll(other.reports);
}
}

@Override
public MedianMeanRunningAverage clone() {
// Override clone() for synchronization.
// Implement Cloneable to shut up findbugs.
synchronized (this) {
return new MedianMeanRunningAverage(this);
}
}
@Override
public MedianMeanRunningAverage clone() {
return new MedianMeanRunningAverage(this);
}

@Override
public synchronized long countReports() {
return reports.size();
}
@Override
public long countReports() {
synchronized (reports) {
return reports.size();
}
}

/**
*
* @return
*/
@Override
public synchronized double currentValue() {
int size = reports.size();
int middle = size / 2;
java.util.Collections.sort(reports);
return reports.get(middle);
}
@Override
public double currentValue() {
synchronized (reports) {
int size = reports.size();
int middle = size / 2;
Collections.sort(reports);
return reports.get(middle);
}
}

/**
*
* @param d
*/
@Override
public synchronized void report(double d) {
mean.report(d);
reports.add(d);
}
@Override
public void report(double d) {
synchronized (reports) {
mean.report(d);
reports.add(d);
}
}

/**
*
* @param d
*/
@Override
public void report(long d) {
report((double)d);
}
@Override
public void report(long d) {
report((double) d);
}

@Override
public double valueIfReported(double r) {
throw new UnsupportedOperationException();
}

@Override
public synchronized String toString() {
return "Median "+currentValue()+" mean "+mean.currentValue();
}

/**
*
* @return
*/
public synchronized double meanValue() {
return mean.currentValue();
}
@Override
public double valueIfReported(double r) {
throw new UnsupportedOperationException();
}

@Override
public String toString() {
synchronized (reports) {
return "Median " + currentValue() + " mean " + meanValue();
}
}

public double meanValue() {
return mean.currentValue();
}

}

0 comments on commit 8b78902

Please sign in to comment.