aboutsummaryrefslogtreecommitdiffstats
path: root/container-core/src/main/java/com/yahoo/container/jdisc/state/GaugeMetric.java
blob: 97964aa7ed6e0c745be6fac1e1e9bf7bfbc2900d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;

import java.util.List;
import java.util.Optional;

import com.yahoo.collections.Tuple2;

/**
 * A metric which contains a gauge value, i.e a value which represents the magnitude of something
 * measured at a point in time. This metric value contains some additional information about the distribution
 * of this gauge value in the time interval this metric is for.
 *
 * @author Simon Thoresen Hult
 */
public final class GaugeMetric extends MetricValue {

    private double last;
    private double max;
    private double min;
    private double sum;
    private long count;
    private final Optional<List<Tuple2<String, Double>>> percentiles;

    private GaugeMetric(double last, double max, double min, double sum, long count, Optional<List<Tuple2<String, Double>>> percentiles) {
        this.last = last;
        this.max = max;
        this.min = min;
        this.sum = sum;
        this.count = count;
        this.percentiles = percentiles;
    }

    @Override
    void add(Number val) {
        double dval = val.doubleValue();
        last = dval;
        if (dval > max) {
            max = dval;
        }
        if (dval < min) {
            min = dval;
        }
        sum += dval;
        ++count;
    }

    @Override
    void add(MetricValue val) {
        GaugeMetric rhs = (GaugeMetric)val;
        last = rhs.last;
        if (rhs.max > max) {
            max = rhs.max;
        }
        if (rhs.min < min) {
            min = rhs.min;
        }
        sum += rhs.sum;
        count += rhs.count;
    }

    /**
     * Returns the average reading of this value in the time interval, or--if no
     * value has been set within this period--the value of 'last' from the
     * most recent interval where this metric was set.
     */
    public double getAverage() {
        return count != 0 ? (sum / count) : last;
    }

    /**
     * Returns the most recent assignment of this metric in the time interval,
     * or--if no value has been set within this period--the value of 'last'
     * from the most recent interval where this metric was set.
     */
    public double getLast() { return last; }

    /**
     * Returns the max value of this metric in the time interval, or--if no
     * value has been set within this period--the value of 'last' from the
     * most recent interval where this metric was set.
     */
    public double getMax() {
        return (count == 0) ? last : max;
    }

    /**
     * Returns the min value of this metric in the time interval, or--if no
     * value has been set within this period--the value of 'last' from the
     * most recent interval where this metric was set.
     */
    public double getMin() {
        return (count == 0) ? last : min;
    }

    /** Returns the sum of all assignments of this metric in the time interval */
    public double getSum() {
        return sum;
    }

    /** Returns the number of assignments of this value in the time interval */
    public long getCount() {
        return count;
    }

    /** Returns the 95th percentile value for this time interval */
    public Optional<List<Tuple2<String, Double>>> getPercentiles() {
        return percentiles;
    }

    /**
     * Create a partial clone of this gauge where the value of 'last' is
     * carried over to the new gauge with all other fields left at defaults
     * (0 for count and sum, biggest possible double for min, smallest possible
     * double for max). Note that since count is 0, these extreme values will
     * never be output from the min/max getters as these will return 'last'
     * in this case.
     * @return A new gauge instance
     */
    public GaugeMetric newWithPreservedLastValue() {
        // min/max set to enforce update of these values on first call to add()
        return new GaugeMetric(last, Double.MIN_VALUE, Double.MAX_VALUE, 0, 0, Optional.empty());
    }

    public static GaugeMetric newSingleValue(Number val) {
        double dval = val.doubleValue();
        return new GaugeMetric(dval, dval, dval, dval, 1, Optional.empty());
    }

    public static GaugeMetric newInstance(double last, double max, double min, double sum, long count) {
        return new GaugeMetric(last, max, min, sum, count, Optional.empty());
    }

    public static GaugeMetric newInstance(double last, double max, double min, double sum, long count, Optional<List<Tuple2<String, Double>>> percentiles) {
        return new GaugeMetric(last, max, min, sum, count, percentiles);
    }

}