Переглянути джерело

Make deterministic ExpDecaySample tests possible.

Richard Crowley 12 роки тому
батько
коміт
f98197155f
2 змінених файлів з 25 додано та 19 видалено
  1. 23 18
      sample.go
  2. 2 1
      sample_test.go

+ 23 - 18
sample.go

@@ -10,7 +10,7 @@ import (
 	"time"
 )
 
-const rescaleThreshold = 1e9 * 60 * 60
+const rescaleThreshold = time.Hour
 
 // Samples maintain a statistically-significant selection of values from
 // a stream.
@@ -136,13 +136,34 @@ func (s *ExpDecaySample) StdDev() float64 {
 
 // Update samples a new value.
 func (s *ExpDecaySample) Update(v int64) {
+	s.update(time.Now(), v)
+}
+
+// Values returns a copy of the values in the sample.
+func (s *ExpDecaySample) Values() []int64 {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	values := make([]int64, len(s.values))
+	for i, v := range s.values {
+		values[i] = v.v
+	}
+	return values
+}
+
+// Variance returns the variance of the sample.
+func (s *ExpDecaySample) Variance() float64 {
+	return variance(s.Values())
+}
+
+// update samples a new value at a particular timestamp.  This is a method all
+// its own to facilitate testing.
+func (s *ExpDecaySample) update(t time.Time, v int64) {
 	s.mutex.Lock()
 	defer s.mutex.Unlock()
 	s.count++
 	if len(s.values) == s.reservoirSize {
 		heap.Pop(&s.values)
 	}
-	t := time.Now()
 	heap.Push(&s.values, expDecaySample{
 		k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
 		v: v,
@@ -160,22 +181,6 @@ func (s *ExpDecaySample) Update(v int64) {
 	}
 }
 
-// Values returns a copy of the values in the sample.
-func (s *ExpDecaySample) Values() []int64 {
-	s.mutex.Lock()
-	defer s.mutex.Unlock()
-	values := make([]int64, len(s.values))
-	for i, v := range s.values {
-		values[i] = v.v
-	}
-	return values
-}
-
-// Variance returns the variance of the sample.
-func (s *ExpDecaySample) Variance() float64 {
-	return variance(s.Values())
-}
-
 // No-op Sample.
 type NilSample struct{}
 

+ 2 - 1
sample_test.go

@@ -133,10 +133,11 @@ func TestExpDecaySampleNanosecondRegression(t *testing.T) {
 }
 
 func TestExpDecaySampleStatistics(t *testing.T) {
+	now := time.Now()
 	rand.Seed(1)
 	s := NewExpDecaySample(100, 0.99)
 	for i := 1; i <= 10000; i++ {
-		s.Update(int64(i))
+		s.(*ExpDecaySample).update(now.Add(time.Duration(i)), int64(i))
 	}
 	if count := s.Count(); 10000 != count {
 		t.Errorf("s.Count(): 10000 != %v\n", count)