aboutsummaryrefslogtreecommitdiffstats
path: root/container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java
diff options
context:
space:
mode:
authorgjoranv <gv@verizonmedia.com>2021-04-13 17:03:46 +0200
committergjoranv <gv@verizonmedia.com>2021-04-13 17:03:46 +0200
commit3f46e126abf3da75ae561ff9f5070b977b3004e3 (patch)
tree581403a84038d1299edf14d5ed54aeae0541d5cc /container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java
parent94611f2c72d033a15b251b59781ff7dddfef63fe (diff)
Add java source from simplemetrics.
Diffstat (limited to 'container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java')
-rw-r--r--container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java b/container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java
new file mode 100644
index 00000000000..b75a0529a03
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/metrics/simple/Bucket.java
@@ -0,0 +1,209 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.metrics.simple;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import com.yahoo.collections.LazyMap;
+import com.yahoo.collections.LazySet;
+import java.util.logging.Level;
+
+/**
+ * An aggregation of data which is only written to from a single thread.
+ *
+ * @author Steinar Knutsen
+ */
+public class Bucket {
+
+ private static final Logger log = Logger.getLogger(Bucket.class.getName());
+ private final Map<Identifier, UntypedMetric> values = LazyMap.newHashMap();
+
+ boolean gotTimeStamps;
+ long fromMillis;
+ long toMillis;
+
+ public Bucket() {
+ this.gotTimeStamps = false;
+ this.fromMillis = 0;
+ this.toMillis = 0;
+ }
+
+ public Bucket(long fromMillis, long toMillis) {
+ this.gotTimeStamps = true;
+ this.fromMillis = fromMillis;
+ this.toMillis = toMillis;
+ }
+
+ public Set<Map.Entry<Identifier, UntypedMetric>> entrySet() {
+ return values.entrySet();
+ }
+
+ void put(Sample x) {
+ UntypedMetric value = get(x);
+ Measurement m = x.getMeasurement();
+ switch (x.getMetricType()) {
+ case GAUGE:
+ value.put(m.getMagnitude());
+ break;
+ case COUNTER:
+ value.add(m.getMagnitude());
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported metric type: " + x.getMetricType());
+ }
+ }
+
+ void put(Identifier id, UntypedMetric value) {
+ values.put(id, value);
+ }
+
+ boolean hasIdentifier(Identifier id) {
+ return values.containsKey(id);
+ }
+
+ void merge(Bucket other, boolean otherIsNewer) {
+ LazySet<String> malformedMetrics = LazySet.newHashSet();
+ for (Map.Entry<Identifier, UntypedMetric> entry : other.values.entrySet()) {
+ String metricName = entry.getKey().getName();
+ try {
+ if (!malformedMetrics.contains(metricName)) {
+ get(entry.getKey(), entry.getValue()).merge(entry.getValue(), otherIsNewer);
+ }
+ } catch (IllegalArgumentException e) {
+ log.log(Level.WARNING, "Problems merging metric " + metricName + ", possibly ignoring data.");
+ // avoid spamming the log if there are a lot of mismatching
+ // threads
+ malformedMetrics.add(metricName);
+ }
+ }
+ }
+
+ void merge(Bucket other) {
+ boolean otherIsNewer = resolveTimeStamps(other);
+ merge(other, otherIsNewer);
+ }
+
+ private boolean resolveTimeStamps(Bucket other) {
+ boolean otherIsNewer = other.fromMillis > this.fromMillis;
+ if (! gotTimeStamps) {
+ fromMillis = other.fromMillis;
+ toMillis = other.toMillis;
+ gotTimeStamps = other.gotTimeStamps;
+ } else if (other.gotTimeStamps) {
+ fromMillis = Math.min(fromMillis, other.fromMillis);
+ toMillis = Math.max(toMillis, other.toMillis);
+ }
+ return otherIsNewer;
+ }
+
+ private UntypedMetric get(Sample sample) {
+ Identifier dim = sample.getIdentifier();
+ UntypedMetric v = values.get(dim);
+
+ if (v == null) {
+ // please keep inside guard, as sample.getHistogramDefinition(String) touches a volatile
+ v = new UntypedMetric(sample.getHistogramDefinition(dim.getName()));
+ values.put(dim, v);
+ }
+ return v;
+ }
+
+ private UntypedMetric get(Identifier dim, UntypedMetric other) {
+ UntypedMetric v = values.get(dim);
+
+ if (v == null) {
+ v = new UntypedMetric(other.getMetricDefinition());
+ values.put(dim, v);
+ }
+ return v;
+ }
+
+ public Collection<String> getAllMetricNames() {
+ Set<String> names = new HashSet<>();
+ for (Identifier id : values.keySet()) {
+ names.add(id.getName());
+ }
+ return names;
+ }
+
+ public Collection<Map.Entry<Point, UntypedMetric>> getValuesForMetric(String metricName) {
+ List<Map.Entry<Point, UntypedMetric>> singleMetric = new ArrayList<>();
+ for (Map.Entry<Identifier, UntypedMetric> entry : values.entrySet()) {
+ if (metricName.equals(entry.getKey().getName())) {
+ singleMetric.add(locationValuePair(entry));
+ }
+ }
+ return singleMetric;
+ }
+
+ public Map<Point, UntypedMetric> getMapForMetric(String metricName) {
+ Map<Point, UntypedMetric> result = new HashMap<>();
+ for (Map.Entry<Identifier, UntypedMetric> entry : values.entrySet()) {
+ if (metricName.equals(entry.getKey().getName())) {
+ result.put(entry.getKey().getLocation(), entry.getValue());
+ }
+ }
+ return result;
+ }
+
+ public Map<String, List<Map.Entry<Point, UntypedMetric>>> getValuesByMetricName() {
+ Map<String, List<Map.Entry<Point, UntypedMetric>>> result = new HashMap<>();
+ for (Map.Entry<Identifier, UntypedMetric> entry : values.entrySet()) {
+ List<Map.Entry<Point, UntypedMetric>> singleMetric;
+ if (result.containsKey(entry.getKey().getName())) {
+ singleMetric = result.get(entry.getKey().getName());
+ } else {
+ singleMetric = new ArrayList<>();
+ result.put(entry.getKey().getName(), singleMetric);
+ }
+ singleMetric.add(locationValuePair(entry));
+ }
+ return result;
+ }
+
+ private SimpleImmutableEntry<Point, UntypedMetric> locationValuePair(Map.Entry<Identifier, UntypedMetric> entry) {
+ return new SimpleImmutableEntry<>(entry.getKey().getLocation(), entry.getValue());
+ }
+
+ @Override
+ public String toString() {
+ return "Bucket [values=" + (values != null ? toString(values.entrySet(), 3) : null) + "]";
+ }
+
+ private String toString(Collection<?> collection, int maxLen) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ int i = 0;
+ for (Iterator<?> iterator = collection.iterator(); iterator.hasNext() && i < maxLen; i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ builder.append(iterator.next());
+ }
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /**
+ * This bucket contains data newer than approximately this point in time.
+ */
+ public long getFromMillis() {
+ return fromMillis;
+ }
+
+ /**
+ * This bucket contains data older than approximately this point in time.
+ */
+ public long getToMillis() {
+ return toMillis;
+ }
+
+}