Make class thread safe.

This commit is contained in:
Michael Lipp 2024-04-17 11:20:11 +02:00
parent 98f5c1e402
commit b58c813e89

View file

@ -20,6 +20,7 @@ package org.jdrupes.vmoperator.vmconlet;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -30,7 +31,8 @@ import java.util.List;
@SuppressWarnings("PMD.DataflowAnomalyAnalysis") @SuppressWarnings("PMD.DataflowAnomalyAnalysis")
public class TimeSeries { public class TimeSeries {
private final List<Entry> data = new LinkedList<>(); @SuppressWarnings("PMD.LooseCoupling")
private final LinkedList<Entry> data = new LinkedList<>();
private final Duration period; private final Duration period;
/** /**
@ -52,25 +54,26 @@ public class TimeSeries {
@SuppressWarnings("PMD.AvoidLiteralsInIfCondition") @SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
public TimeSeries add(Instant time, Number... numbers) { public TimeSeries add(Instant time, Number... numbers) {
var newEntry = new Entry(time, numbers); var newEntry = new Entry(time, numbers);
boolean adjust = false; boolean nothingNew = false;
synchronized (data) {
if (data.size() >= 2) { if (data.size() >= 2) {
var lastEntry = data.get(data.size() - 1); var lastEntry = data.get(data.size() - 1);
var lastButOneEntry = data.get(data.size() - 2); var lastButOneEntry = data.get(data.size() - 2);
adjust = lastEntry.valuesEqual(lastButOneEntry) nothingNew = lastEntry.valuesEqual(lastButOneEntry)
&& lastEntry.valuesEqual(newEntry); && lastEntry.valuesEqual(newEntry);
} }
if (adjust) { if (nothingNew) {
data.get(data.size() - 1).adjustTime(time); data.removeLast();
} else {
data.add(new Entry(time, numbers));
} }
data.add(new Entry(time, numbers));
// Purge // Purge
Instant limit = time.minus(period); Instant limit = time.minus(period);
while (data.size() > 2 while (data.size() > 2
&& data.get(0).getTime().isBefore(limit) && data.get(0).getTime().isBefore(limit)
&& data.get(1).getTime().isBefore(limit)) { && data.get(1).getTime().isBefore(limit)) {
data.remove(0); data.removeFirst();
}
} }
return this; return this;
} }
@ -81,14 +84,16 @@ public class TimeSeries {
* @return the list * @return the list
*/ */
public List<Entry> entries() { public List<Entry> entries() {
return data; synchronized (data) {
return new ArrayList<>(data);
}
} }
/** /**
* The Class Entry. * The Class Entry.
*/ */
public static class Entry { public static class Entry {
private Instant timestamp; private final Instant timestamp;
private final Number[] values; private final Number[] values;
/** /**
@ -103,15 +108,6 @@ public class TimeSeries {
values = numbers; values = numbers;
} }
/**
* Changes the entry's time.
*
* @param time the time
*/
public void adjustTime(Instant time) {
timestamp = time;
}
/** /**
* Returns the entry's time. * Returns the entry's time.
* *