github.com/zeebo/mon@v0.0.0-20211012163247-13d39bdb54fa/internal/lfht/lfht_test.go (about) 1 package lfht 2 3 import ( 4 "runtime" 5 "testing" 6 7 . "github.com/zeebo/mon/internal/tests" 8 "github.com/zeebo/pcg" 9 ) 10 11 func TestTable(t *testing.T) { 12 var ta Table 13 for i := uint32(0); i < 100; i++ { 14 ta.Upsert(Key(i), Empty) 15 if ta.Lookup(Key(i)) != Value { 16 ta.dump() 17 t.Fatal(i) 18 } 19 } 20 for i := uint32(0); i < 100; i++ { 21 if ta.Lookup(Key(i)) != Value { 22 ta.dump() 23 t.Fatal(i) 24 } 25 } 26 for iter := ta.Iterator(); iter.Next(); { 27 if ta.Lookup(iter.Key()) != iter.Value() { 28 ta.dump() 29 t.Fatal(iter.Key(), iter.Value()) 30 } 31 } 32 } 33 34 func TestTable_Iterator(t *testing.T) { 35 for i := 0; i < 100; i++ { 36 var ta Table 37 for i := uint32(0); i < 100; i++ { 38 ta.Upsert(Key(i), Empty) 39 } 40 41 var ( 42 done = make(chan struct{}) 43 count = make(chan int, runtime.GOMAXPROCS(-1)) 44 ) 45 46 for i := 0; i < cap(count); i++ { 47 go func() { 48 rng := pcg.New(pcg.Uint64()) 49 total := 0 50 again: 51 select { 52 case <-done: 53 default: 54 ta.Upsert(Key(rng.Uint32n(Size)), Empty) 55 total++ 56 runtime.Gosched() 57 goto again 58 } 59 count <- total 60 }() 61 } 62 63 got := make(map[string]struct{}) 64 for iter := ta.Iterator(); iter.Next(); { 65 got[iter.Key()] = struct{}{} 66 runtime.Gosched() 67 } 68 close(done) 69 70 total := 0 71 for i := 0; i < cap(count); i++ { 72 total += <-count 73 } 74 75 for i := uint32(0); i < 100; i++ { 76 if _, ok := got[Key(i)]; !ok { 77 t.Fatal(total, len(got), i) 78 } 79 } 80 } 81 } 82 83 func BenchmarkLFHT(b *testing.B) { 84 RunBenchmarks(b, func() Type { return new(Table) }) 85 86 b.Run("Iterate", func(b *testing.B) { 87 var ta Table 88 for i := uint32(0); i < Size; i++ { 89 ta.Upsert(Key(i), Empty) 90 } 91 b.ReportAllocs() 92 b.ResetTimer() 93 94 iter := ta.Iterator() 95 for i := 0; i < b.N; i++ { 96 if !iter.Next() { 97 iter = ta.Iterator() 98 } 99 } 100 }) 101 }