Codebase list golang-github-beorn7-perks / ea22b6e quantile / stream_test.go
ea22b6e

Tree @ea22b6e (Download .tar.gz)

stream_test.go @ea22b6e

61af1a0
 
 
 
 
 
 
 
 
20433c1
61af1a0
 
 
ea22b6e
61af1a0
 
 
 
 
ea22b6e
 
 
61af1a0
ea22b6e
 
 
61af1a0
ea22b6e
 
 
61af1a0
 
 
 
 
ac5ec5b
61af1a0
 
20433c1
61af1a0
 
 
 
 
 
 
 
 
 
ea22b6e
61af1a0
 
 
 
 
 
 
 
 
 
 
ea22b6e
 
 
61af1a0
ea22b6e
 
 
61af1a0
ea22b6e
 
 
61af1a0
 
 
c4274eb
 
 
da72989
c4274eb
 
 
 
 
 
 
 
 
 
 
 
 
 
e3edcea
 
 
 
 
 
 
 
 
 
bd1cf5e
 
 
 
 
 
 
 
 
 
 
 
 
 
ea22b6e
61af1a0
ea22b6e
 
 
 
 
 
 
 
 
61af1a0
package quantile

import (
	"math/rand"
	"sort"
	"testing"
)

func TestQuantRandQuery(t *testing.T) {
	s := NewTargeted(0.5, 0.90, 0.99)
	a := make([]float64, 0, 1e5)
	rand.Seed(42)
	for i := 0; i < cap(a); i++ {
		v := rand.NormFloat64()
		s.Insert(v)
		a = append(a, v)
	}
	t.Logf("len: %d", s.Count())
	sort.Float64s(a)
	w, min, max := getPerc(a, 0.50)
	if g := s.Query(0.50); g < min || g > max {
		t.Errorf("perc50: want %v [%f,%f], got %v", w, min, max, g)
	}
	w, min, max = getPerc(a, 0.90)
	if g := s.Query(0.90); g < min || g > max {
		t.Errorf("perc90: want %v [%f,%f], got %v", w, min, max, g)
	}
	w, min, max = getPerc(a, 0.99)
	if g := s.Query(0.99); g < min || g > max {
		t.Errorf("perc99: want %v [%f,%f], got %v", w, min, max, g)
	}
}

func TestQuantRandMergeQuery(t *testing.T) {
	ch := make(chan float64)
	done := make(chan *Stream)
	for i := 0; i < 2; i++ {
		go func() {
			s := NewTargeted(0.5, 0.90, 0.99)
			for v := range ch {
				s.Insert(v)
			}
			done <- s
		}()
	}

	rand.Seed(42)
	a := make([]float64, 0, 1e6)
	for i := 0; i < cap(a); i++ {
		v := rand.NormFloat64()
		a = append(a, v)
		ch <- v
	}
	close(ch)

	s := <-done
	o := <-done
	s.Merge(o.Samples())

	t.Logf("len: %d", s.Count())
	sort.Float64s(a)
	w, min, max := getPerc(a, 0.50)
	if g := s.Query(0.50); g < min || g > max {
		t.Errorf("perc50: want %v [%f,%f], got %v", w, min, max, g)
	}
	w, min, max = getPerc(a, 0.90)
	if g := s.Query(0.90); g < min || g > max {
		t.Errorf("perc90: want %v [%f,%f], got %v", w, min, max, g)
	}
	w, min, max = getPerc(a, 0.99)
	if g := s.Query(0.99); g < min || g > max {
		t.Errorf("perc99: want %v [%f,%f], got %v", w, min, max, g)
	}
}

func TestUncompressed(t *testing.T) {
	tests := []float64{0.50, 0.90, 0.95, 0.99}
	q := NewTargeted(tests...)
	for i := 100; i > 0; i-- {
		q.Insert(float64(i))
	}
	if g := q.Count(); g != 100 {
		t.Errorf("want count 100, got %d", g)
	}
	// Before compression, Query should have 100% accuracy.
	for _, v := range tests {
		w := v * 100
		if g := q.Query(v); g != w {
			t.Errorf("want %f, got %f", w, g)
		}
	}
}

func TestUncompressedSamples(t *testing.T) {
	q := NewTargeted(0.99)
	for i := 1; i <= 100; i++ {
		q.Insert(float64(i))
	}
	if g := q.Samples().Len(); g != 100 {
		t.Errorf("want count 100, got %d", g)
	}
}

func TestUncompressedOne(t *testing.T) {
	q := NewTargeted(0.90)
	q.Insert(3.14)
	if g := q.Query(0.90); g != 3.14 {
		t.Error("want PI, got", g)
	}
}

func TestDefaults(t *testing.T) {
	if g := NewTargeted(0.99).Query(0.99); g != 0 {
		t.Errorf("want 0, got %f", g)
	}
}

func getPerc(x []float64, p float64) (want, min, max float64) {
	k := int(float64(len(x)) * p)
	lower := int(float64(len(x)) * (p - 0.04))
	if lower < 0 {
		lower = 0
	}
	upper := int(float64(len(x))*(p+0.04)) + 1
	if upper >= len(x) {
		upper = len(x) - 1
	}
	return x[k], x[lower], x[upper]
}