Skip to content

Commit 6c0ced2

Browse files
committed
refactor: OngoingPowerMeasure now records raw measures & timestamps
1 parent 41dd955 commit 6c0ced2

File tree

2 files changed

+45
-31
lines changed

2 files changed

+45
-31
lines changed

measure/src/main/java/net/laprun/sustainability/power/measure/OngoingPowerMeasure.java

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import net.laprun.sustainability.power.SensorMetadata;
1010

1111
public class OngoingPowerMeasure implements PowerMeasure {
12+
private static final int DEFAULT_SIZE = 32;
1213
private final SensorMetadata sensorMetadata;
13-
private final ComponentMeasure[] measures;
1414
private final long startedAt;
1515
private final double[] averages;
1616
private final Set<Integer> nonZeroComponents;
@@ -20,18 +20,18 @@ public class OngoingPowerMeasure implements PowerMeasure {
2020
private double maxTotal;
2121
private double accumulatedTotal;
2222
private int samples;
23+
private final double[][] measures;
24+
private long[] timestamps;
2325

24-
public OngoingPowerMeasure(SensorMetadata sensorMetadata, ComponentMeasure.Factory<?> componentMeasureFactory) {
26+
public OngoingPowerMeasure(SensorMetadata sensorMetadata) {
2527
this.sensorMetadata = sensorMetadata;
2628
startedAt = System.currentTimeMillis();
2729

2830
final var numComponents = sensorMetadata.componentCardinality();
2931
// we also record the aggregated total for each component participating in the aggregated value
3032
final var measuresNb = numComponents + 1;
31-
measures = new ComponentMeasure[measuresNb];
32-
for (int i = 0; i < measuresNb; i++) {
33-
measures[i] = componentMeasureFactory.create();
34-
}
33+
measures = new double[measuresNb][DEFAULT_SIZE];
34+
timestamps = new long[DEFAULT_SIZE];
3535
totalIndex = numComponents;
3636
averages = new double[measuresNb];
3737
// we don't need to record the total component as a non-zero component since it's almost never zero and we compute the std dev separately
@@ -58,14 +58,14 @@ public void recordMeasure(double[] components) {
5858
if (componentValue != 0) {
5959
nonZeroComponents.add(component);
6060
}
61-
measures[component].recordComponentValue(componentValue);
61+
recordComponentValue(component, componentValue);
6262
averages[component] = averages[component] == 0 ? componentValue
6363
: (previousSize * averages[component] + componentValue) / samples;
6464
}
6565

6666
// record min / max totals
6767
final var recordedTotal = PowerMeasure.sumOfSelectedComponents(components, totalComponents);
68-
measures[totalIndex].recordComponentValue(recordedTotal);
68+
recordComponentValue(totalIndex, recordedTotal);
6969
accumulatedTotal += recordedTotal;
7070
averages[components.length] = averages[components.length] == 0 ? recordedTotal
7171
: (previousSize * averages[components.length] + recordedTotal) / samples;
@@ -77,6 +77,23 @@ public void recordMeasure(double[] components) {
7777
}
7878
}
7979

80+
private void recordComponentValue(int component, double value) {
81+
final var currentSize = measures[component].length;
82+
if (currentSize <= samples) {
83+
final var newSize = currentSize * 2;
84+
for (int index = 0; index < measures.length; index++) {
85+
final var newArray = new double[newSize];
86+
System.arraycopy(measures[index], 0, newArray, 0, currentSize);
87+
measures[index] = newArray;
88+
}
89+
final var newTimestamps = new long[newSize];
90+
System.arraycopy(timestamps, 0, newTimestamps, 0, currentSize);
91+
timestamps = newTimestamps;
92+
}
93+
timestamps[component] = System.currentTimeMillis();
94+
measures[component][samples - 1] = value;
95+
}
96+
8097
@Override
8198
public double total() {
8299
return accumulatedTotal;
@@ -113,21 +130,23 @@ public StdDev standardDeviations() {
113130
}
114131

115132
private double standardDeviation(int component) {
116-
final var values = measures[component].getComponentRawValues();
133+
final var values = measures[component];
117134
if (samples <= 1) {
118135
return 0.0;
119136
}
120137
final double mean = averages[component];
121-
double geometric_deviation_total = 0.0;
122-
for (double value : values) {
123-
double deviation = value - mean;
124-
geometric_deviation_total += (deviation * deviation);
138+
double geometricDeviationTotal = 0.0;
139+
for (int index = 0; index < samples; index++) {
140+
double deviation = values[index] - mean;
141+
geometricDeviationTotal += (deviation * deviation);
125142
}
126-
return FastMath.sqrt(geometric_deviation_total / (samples - 1));
143+
return FastMath.sqrt(geometricDeviationTotal / (samples - 1));
127144
}
128145

129146
@Override
130147
public double[] getMeasuresFor(int component) {
131-
return measures[component].getComponentRawValues();
148+
final var dest = new double[samples];
149+
System.arraycopy(measures[component], 0, dest, 0, samples);
150+
return dest;
132151
}
133152
}

measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
44
import static org.junit.jupiter.api.Assertions.assertEquals;
55

6-
import java.util.List;
76
import java.util.Map;
87
import java.util.stream.Stream;
98

10-
import org.junit.jupiter.params.ParameterizedTest;
11-
import org.junit.jupiter.params.provider.MethodSource;
9+
import org.junit.jupiter.api.Test;
1210

1311
import net.laprun.sustainability.power.SensorMetadata;
1412

@@ -21,13 +19,8 @@ public int componentCardinality() {
2119
}
2220
};
2321

24-
static List<ComponentMeasure.Factory<?>> factories() {
25-
return List.of(DescriptiveStatisticsComponentMeasure::new, HdrHistogramComponentMeasure::new);
26-
}
27-
28-
@ParameterizedTest
29-
@MethodSource("factories")
30-
void testStatistics(ComponentMeasure.Factory<?> factory) {
22+
@Test
23+
void testStatistics() {
3124
final var m1c1 = 10.0;
3225
final var m1c2 = 12.0;
3326
final var m1c3 = 0.0;
@@ -41,7 +34,7 @@ void testStatistics(ComponentMeasure.Factory<?> factory) {
4134
final var m3c3 = 0.0;
4235
final var m3total = m3c1 + m3c2 + m3c3;
4336

44-
final var measure = new OngoingPowerMeasure(metadata, factory);
37+
final var measure = new OngoingPowerMeasure(metadata);
4538

4639
final var components = new double[metadata.componentCardinality()];
4740
components[0] = m1c1;
@@ -59,9 +52,9 @@ void testStatistics(ComponentMeasure.Factory<?> factory) {
5952
components[2] = m3c3;
6053
measure.recordMeasure(components);
6154

62-
// assertArrayEquals(new double[] {m1c1, m2c1}, measure.getMeasuresFor(0));
63-
// assertArrayEquals(new double[] {m1c2, m2c2}, measure.getMeasuresFor(1));
64-
// assertArrayEquals(new double[] {m1c3, m2c3}, measure.getMeasuresFor(2));
55+
assertArrayEquals(new double[] { m1c1, m2c1, m3c1 }, measure.getMeasuresFor(0));
56+
assertArrayEquals(new double[] { m1c2, m2c2, m3c2 }, measure.getMeasuresFor(1));
57+
assertArrayEquals(new double[] { m1c3, m2c3, m3c3 }, measure.getMeasuresFor(2));
6558

6659
assertEquals(m1c1 + m1c2 + m1c3 + m2c1 + m2c2 + m2c3 + m3c1 + m3c2 + m3c3, measure.total());
6760
assertEquals((m1c1 + m1c2 + m1c3 + m2c1 + m2c2 + m2c3 + m3c1 + m3c2 + m3c3) / 3, measure.average());
@@ -74,8 +67,10 @@ void testStatistics(ComponentMeasure.Factory<?> factory) {
7467
assertEquals((m1c2 + m2c2 + m3c2) / 3, c2Avg);
7568
assertEquals(0, c3Avg);
7669

77-
final var stdVarForC1 = Math.sqrt((Math.pow(m1c1 - c1Avg, 2) + Math.pow(m2c1 - c1Avg, 2) + Math.pow(m3c1 - c1Avg, 2)) / (3 - 1));
78-
final var stdVarForC2 = Math.sqrt((Math.pow(m1c2 - c2Avg, 2) + Math.pow(m2c2 - c2Avg, 2) + Math.pow(m3c2 - c2Avg, 2)) / (3 - 1));
70+
final var stdVarForC1 = Math
71+
.sqrt((Math.pow(m1c1 - c1Avg, 2) + Math.pow(m2c1 - c1Avg, 2) + Math.pow(m3c1 - c1Avg, 2)) / (3 - 1));
72+
final var stdVarForC2 = Math
73+
.sqrt((Math.pow(m1c2 - c2Avg, 2) + Math.pow(m2c2 - c2Avg, 2) + Math.pow(m3c2 - c2Avg, 2)) / (3 - 1));
7974

8075
assertEquals(stdVarForC1, measure.standardDeviations().perComponent()[0], 0.0001,
8176
"Standard Deviation did not match the expected value");

0 commit comments

Comments
 (0)