summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2020-10-20 22:52:21 +0200
committerJon Bratseth <bratseth@gmail.com>2020-10-22 15:31:33 +0200
commit53e5f06cd8e545be91a7fc1e9cf0e7eacb249aae (patch)
treec5f84be1f45ae12b77557cb9faa2778f8cd66ee8
parent3013538d73fc9546f5d3eba7a3211e6b5c41f485 (diff)
Make NodeTimeseries immutable
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeMetricsDb.java18
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeTimeseries.java22
3 files changed, 20 insertions, 22 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
index 49dea25f8a8..52f6a5bbabc 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ClusterTimeseries.java
@@ -93,7 +93,7 @@ public class ClusterTimeseries {
private List<NodeTimeseries> filterStale(List<NodeTimeseries> timeseries,
Map<String, Instant> startTimePerHost) {
if (startTimePerHost.isEmpty()) return timeseries; // Map is either empty or complete
- return timeseries.stream().map(m -> m.copyAfter(startTimePerHost.get(m.hostname()))).collect(Collectors.toList());
+ return timeseries.stream().map(m -> m.justAfter(startTimePerHost.get(m.hostname()))).collect(Collectors.toList());
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeMetricsDb.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeMetricsDb.java
index c4aacb63de6..271f8601ae2 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeMetricsDb.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeMetricsDb.java
@@ -10,10 +10,10 @@ import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
/**
* An in-memory time-series "database" of node metrics.
@@ -55,7 +55,7 @@ public class NodeMetricsDb {
new ArrayList<>());
db.put(hostname, timeseries);
}
- timeseries.add(snapshot);
+ db.put(hostname, timeseries.add(snapshot));
}
/** Must be called intermittently (as long as any add methods are called) to gc old data */
@@ -63,11 +63,13 @@ public class NodeMetricsDb {
synchronized (lock) {
// Each measurement is Object + long + float = 16 + 8 + 4 = 28 bytes
// 12 hours with 1k nodes and 3 resources and 1 measurement/sec is about 5Gb
- for (Iterator<NodeTimeseries> i = db.values().iterator(); i.hasNext(); ) {
- var snapshot = i.next();
- snapshot.removeOlderThan(clock.instant().minus(Autoscaler.scalingWindow(snapshot.type())).toEpochMilli());
- if (snapshot.isEmpty())
- i.remove();
+ for (String hostname : db.keySet()) {
+ var timeseries = db.get(hostname);
+ timeseries = timeseries.justAfter(clock.instant().minus(Autoscaler.scalingWindow(timeseries.type())));
+ if (timeseries.isEmpty())
+ db.remove(hostname);
+ else
+ db.put(hostname, timeseries);
}
}
}
@@ -82,7 +84,7 @@ public class NodeMetricsDb {
for (String hostname : hostnames) {
NodeTimeseries measurements = db.get(hostname);
if (measurements == null) continue;
- measurements = measurements.copyAfter(startTime);
+ measurements = measurements.justAfter(startTime);
if (measurements.isEmpty()) continue;
measurementsList.add(measurements);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeTimeseries.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeTimeseries.java
index e6f786f55aa..778a2110d2c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeTimeseries.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/NodeTimeseries.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.provision.autoscale;
import com.yahoo.config.provision.ClusterSpec;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -26,8 +27,6 @@ public class NodeTimeseries {
this.snapshots = snapshots;
}
- // Public access
-
public boolean isEmpty() { return snapshots.isEmpty(); }
public int size() { return snapshots.size(); }
@@ -40,20 +39,17 @@ public class NodeTimeseries {
public String hostname() { return hostname; }
- public NodeTimeseries copyAfter(Instant oldestTime) {
+ public NodeTimeseries add(MetricSnapshot snapshot) {
+ List<MetricSnapshot> list = new ArrayList<>(snapshots);
+ list.add(snapshot);
+ return new NodeTimeseries(hostname(), type(), list);
+ }
+
+ public NodeTimeseries justAfter(Instant oldestTime) {
return new NodeTimeseries(hostname, type,
snapshots.stream()
- .filter(measurement -> measurement.at().equals(oldestTime) || measurement.at().isAfter(oldestTime))
+ .filter(snapshot -> snapshot.at().equals(oldestTime) || snapshot.at().isAfter(oldestTime))
.collect(Collectors.toList()));
}
- // Restricted mutation
-
- void add(MetricSnapshot snapshot) { snapshots.add(snapshot); }
-
- void removeOlderThan(long oldestTimestamp) {
- while (!snapshots.isEmpty() && snapshots.get(0).at().toEpochMilli() < oldestTimestamp)
- snapshots.remove(0);
- }
-
}