Parcourir la source

Add Sum to Histogram and Sample interfaces.

Richard Crowley il y a 12 ans
Parent
commit
aefccf14c6
3 fichiers modifiés avec 39 ajouts et 13 suppressions
  1. 9 0
      histogram.go
  2. 6 8
      librato/librato.go
  3. 24 5
      sample.go

+ 9 - 0
histogram.go

@@ -20,6 +20,7 @@ type Histogram interface {
 	Percentiles([]float64) []float64
 	Sample() Sample
 	StdDev() float64
+	Sum() int64
 	Update(int64)
 	Variance() float64
 }
@@ -89,6 +90,9 @@ func (NilHistogram) Sample() Sample { return NilSample{} }
 // No-op.
 func (NilHistogram) StdDev() float64 { return 0.0 }
 
+// No-op.
+func (NilHistogram) Sum() int64 { return 0 }
+
 // No-op.
 func (NilHistogram) Update(v int64) {}
 
@@ -172,6 +176,11 @@ func (h *StandardHistogram) StdDev() float64 {
 	return math.Sqrt(h.Variance())
 }
 
+// Return the sum of inputs since the histogram was last cleared.
+func (h *StandardHistogram) Sum() int64 {
+	return atomic.LoadInt64(&h.sum)
+}
+
 // Update the histogram with a new value.
 func (h *StandardHistogram) Update(v int64) {
 	h.mutex.Lock()

+ 6 - 8
librato/librato.go

@@ -54,11 +54,10 @@ func (self *Reporter) Run() {
 
 // calculate sum of squares from data provided by metrics.Histogram
 // see http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
-func sumSquares(m metrics.Histogram) float64 {
-	count := float64(m.Count())
-	sum := m.Mean() * float64(m.Count())
-	sumSquared := math.Pow(float64(sum), 2)
-	sumSquares := math.Pow(count*m.StdDev(), 2) + sumSquared/float64(m.Count())
+func sumSquares(s metrics.Sample) float64 {
+	count := float64(s.Count())
+	sumSquared := math.Pow(float64(s.Sum()), 2)
+	sumSquares := math.Pow(count*s.StdDev(), 2) + sumSquared/float64(s.Count())
 	if math.IsNaN(sumSquares) {
 		return 0.0
 	}
@@ -66,8 +65,7 @@ func sumSquares(m metrics.Histogram) float64 {
 }
 func sumSquaresTimer(m metrics.Timer) float64 {
 	count := float64(m.Count())
-	sum := m.Mean() * float64(m.Count())
-	sumSquared := math.Pow(float64(sum), 2)
+	sumSquared := math.Pow(float64(s.Sum()), 2)
 	sumSquares := math.Pow(count*m.StdDev(), 2) + sumSquared/float64(m.Count())
 	if math.IsNaN(sumSquares) {
 		return 0.0
@@ -102,7 +100,7 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
 				s := m.Sample()
 				measurement[Name] = fmt.Sprintf("%s.%s", name, "hist")
 				measurement[Count] = uint64(s.Count())
-				measurement[Sum] = s.Mean() * float64(s.Count())
+				measurement[Sum] = s.Sum()
 				measurement[Max] = float64(s.Max())
 				measurement[Min] = float64(s.Min())
 				measurement[SumSquares] = sumSquares(s)

+ 24 - 5
sample.go

@@ -28,6 +28,7 @@ type Sample interface {
 	Percentiles([]float64) []float64
 	Size() int
 	StdDev() float64
+	Sum() int64
 	Update(int64)
 	Values() []int64
 	Variance() float64
@@ -134,6 +135,11 @@ func (s *ExpDecaySample) StdDev() float64 {
 	return SampleStdDev(s.Values())
 }
 
+// Sum returns the sum of the sample.
+func (s *ExpDecaySample) Sum() int64 {
+	return SampleSum(s.Values())
+}
+
 // Update samples a new value.
 func (s *ExpDecaySample) Update(v int64) {
 	s.update(time.Now(), v)
@@ -216,6 +222,9 @@ func (NilSample) Size() int { return 0 }
 // No-op.
 func (NilSample) StdDev() float64 { return 0.0 }
 
+// No-op.
+func (NilSample) Sum() int64 { return 0 }
+
 // No-op.
 func (NilSample) Update(v int64) {}
 
@@ -244,11 +253,7 @@ func SampleMean(values []int64) float64 {
 	if 0 == len(values) {
 		return 0.0
 	}
-	var sum int64
-	for _, v := range values {
-		sum += v
-	}
-	return float64(sum) / float64(len(values))
+	return float64(SampleSum(values)) / float64(len(values))
 }
 
 // SampleMin returns the minimum value of the slice of int64.
@@ -298,6 +303,15 @@ func SampleStdDev(values []int64) float64 {
 	return math.Sqrt(SampleVariance(values))
 }
 
+// SampleSum returns the sum of the slice of int64.
+func SampleSum(values []int64) int64 {
+	var sum int64
+	for _, v := range values {
+		sum += v
+	}
+	return sum
+}
+
 // SampleVariance returns the variance of the slice of int64.
 func SampleVariance(values []int64) float64 {
 	m := SampleMean(values)
@@ -405,6 +419,11 @@ func (s *UniformSample) StdDev() float64 {
 	return SampleStdDev(s.values)
 }
 
+// Sum returns the sum of the sample.
+func (s *UniformSample) Sum() int64 {
+	return SampleSum(s.values)
+}
+
 // Update the sample with a new value.
 func (s *UniformSample) Update(v int64) {
 	s.mutex.Lock()