فهرست منبع

Fix bug that freezes an ExpDecaySample

Pieter Noordhuis 13 سال پیش
والد
کامیت
ad651a26f3
2فایلهای تغییر یافته به همراه32 افزوده شده و 1 حذف شده
  1. 1 1
      sample.go
  2. 31 0
      sample_test.go

+ 1 - 1
sample.go

@@ -80,7 +80,7 @@ func (s *ExpDecaySample) arbiter() {
 		select {
 		case v := <-s.in:
 			now := time.Now()
-			k := math.Exp(float64(now.Sub(start))*s.alpha) / rand.Float64()
+			k := math.Exp(now.Sub(start).Seconds()*s.alpha) / rand.Float64()
 			count++
 			values[k] = v
 			if count > s.reservoirSize {

+ 31 - 0
sample_test.go

@@ -4,6 +4,7 @@ import (
 	"math/rand"
 	"runtime"
 	"testing"
+	"time"
 )
 
 func TestExpDecaySample10(t *testing.T) {
@@ -60,6 +61,36 @@ func TestExpDecaySample1000(t *testing.T) {
 	}
 }
 
+// This test makes sure that the sample's priority is not amplified by using
+// nanosecond duration since start rather than second duration since start.
+// The priority becomes +Inf quickly after starting if this is done,
+// effectively freezing the set of samples until a rescale step happens.
+func TestExpDecaySampleNanosecondRegression(t *testing.T) {
+	s := NewExpDecaySample(100, 0.99)
+
+	for i := 0; i < 100; i++ {
+		s.Update(10)
+	}
+
+	time.Sleep(1 * time.Millisecond)
+
+	for i := 0; i < 100; i++ {
+		s.Update(20)
+	}
+
+	v := s.Values()
+	avg := float64(0)
+
+	for i := 0; i < len(v); i++ {
+		avg += float64(v[i])
+	}
+
+	avg /= float64(len(v))
+	if avg > 16 || avg < 14 {
+		t.Errorf("out of range [14, 16]: %v\n", avg)
+	}
+}
+
 func TestUniformSample(t *testing.T) {
 	s := NewUniformSample(100)
 	for i := 0; i < 1000; i++ {