github.com/fluhus/gostuff@v0.4.1-0.20240331134726-be71864f2b5d/hll/hll_test.go (about) 1 package hll 2 3 import ( 4 "math" 5 "testing" 6 7 "github.com/fluhus/gostuff/bnry" 8 "github.com/spaolacci/murmur3" 9 ) 10 11 func TestCount_short(t *testing.T) { 12 upto := 10000000 13 if testing.Short() { 14 upto = 1000 15 } 16 17 hll := newIntHLL() 18 next := 1 19 ratioSum := 0.0 20 ratioCount := 0.0 21 for i := 1; i <= upto; i++ { 22 hll.Add(i) 23 if i != next { // Check only a sample. 24 continue 25 } 26 next = (next + 1) * 21 / 20 27 ratio := float64(i) / float64(hll.ApproxCount()) 28 ratioSum += math.Abs(math.Log(ratio)) 29 ratioCount++ 30 } 31 avg := math.Exp(ratioSum / ratioCount) 32 want := 1.003 33 if avg > want { 34 t.Errorf("average error=%f, want at most %f", 35 avg, want) 36 } 37 } 38 39 func TestCount_zero(t *testing.T) { 40 hll := newIntHLL() 41 if count := hll.ApproxCount(); count != 0 { 42 t.Fatalf("ApproxCount()=%v, want 0", count) 43 } 44 } 45 46 func TestAddHLL(t *testing.T) { 47 hll1 := newIntHLL() 48 for i := 1; i <= 5; i++ { 49 hll1.Add(i) 50 } 51 if count := hll1.ApproxCount(); count != 5 { 52 t.Fatalf("ApproxCount()=%v, want 5", count) 53 } 54 55 hll2 := newIntHLL() 56 for i := 4; i <= 9; i++ { 57 hll2.Add(i) 58 } 59 if count := hll2.ApproxCount(); count != 6 { 60 t.Fatalf("ApproxCount()=%v, want 6", count) 61 } 62 63 hll1.AddHLL(hll2) 64 if count := hll1.ApproxCount(); count != 9 { 65 t.Fatalf("ApproxCount()=%v, want 9", count) 66 } 67 } 68 69 func BenchmarkAdd(b *testing.B) { 70 hll := New2(16, func(i int) uint64 { return uint64(i) }) 71 for i := 0; i < b.N; i++ { 72 hll.Add(i) 73 } 74 } 75 76 func BenchmarkAdd_intHLL(b *testing.B) { 77 hll := newIntHLL() 78 for i := 0; i < b.N; i++ { 79 hll.Add(i) 80 } 81 } 82 83 func BenchmarkCount(b *testing.B) { 84 const nelements = 1000000 85 hll := newIntHLL() 86 for i := 0; i < nelements; i++ { 87 hll.Add(i) 88 } 89 b.Run("", func(b *testing.B) { 90 for i := 0; i < b.N; i++ { 91 hll.ApproxCount() 92 } 93 }) 94 } 95 96 func newIntHLL() *HLL2[int] { 97 h := murmur3.New64() 98 w := bnry.NewWriter(h) 99 return New2(16, func(i int) uint64 { 100 h.Reset() 101 w.Write(i) 102 return h.Sum64() 103 }) 104 }