github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/diagnostic/memsize/interval_set_test.go (about) 1 package memsize 2 3 import ( 4 "math/rand" 5 "testing" 6 ) 7 8 func TestIntervalSet(t *testing.T) { 9 tests := []struct { 10 data []interval 11 expectedCovered []int 12 }{ 13 { 14 data: []interval{{1, 10}}, 15 expectedCovered: []int{10}, 16 }, 17 { 18 data: []interval{{1, 10}, {11, 10}}, 19 expectedCovered: []int{10, 20}, 20 }, 21 { 22 data: []interval{{1, 10}, {5, 10}}, 23 expectedCovered: []int{10, 14}, 24 }, 25 { 26 data: []interval{{1, 10}, {5, 10}, {6, 9}, {6, 10}, {100, 1}, {100, 2}, {101, 1}}, 27 expectedCovered: []int{10, 14, 14, 15, 16, 17, 17}, 28 }, 29 { 30 data: []interval{{100, 1}, {99, 1}, {99, 2}, {0, 10}, {10, 10}}, 31 expectedCovered: []int{1, 2, 2, 12, 22}, 32 }, 33 } 34 35 for testId, test := range tests { 36 for numToAdd := range test.data { 37 var set intervalSet 38 for i := 0; i <= numToAdd; i++ { 39 newInterval := test.data[i] 40 set.add(newInterval) 41 } 42 got := set.totalCovered() 43 if got != test.expectedCovered[numToAdd] { 44 t.Errorf("test: %d, query: %d: got %v, expected %v", testId, numToAdd, got, test.expectedCovered[numToAdd]) 45 } 46 } 47 } 48 } 49 50 func TestEmptySet(t *testing.T) { 51 var set intervalSet 52 if got := set.totalCovered(); got != 0 { 53 t.Errorf("empty set should have 0 coverage. got %d", got) 54 } 55 } 56 57 // TestRandomAddition creates a random slice of intervals and adds them in random order to the intervalSet. 58 // It periodically checks TotalCovered() against another implementation of interval set. 59 func TestRandomAddition(t *testing.T) { 60 tests := []struct { 61 setsize int 62 testrepeats int 63 size int 64 intervalrepeats int 65 sampleProb float64 66 }{ 67 { 68 setsize: 100, 69 testrepeats: 100, 70 size: 1, 71 intervalrepeats: 2, 72 sampleProb: .2, 73 }, 74 { 75 setsize: 1000, 76 testrepeats: 100, 77 size: 3, 78 intervalrepeats: 2, 79 sampleProb: .2, 80 }, 81 { 82 setsize: 1000, 83 testrepeats: 100, 84 size: 3, 85 intervalrepeats: 2, 86 sampleProb: 0, 87 }, 88 } 89 90 for _, test := range tests { 91 for testRepeat := 0; testRepeat < test.testrepeats; testRepeat++ { 92 r := rand.New(rand.NewSource(int64(testRepeat))) 93 var intervals []interval 94 for i := 0; i < test.setsize; i++ { 95 for j := 0; j < test.intervalrepeats; j++ { 96 intervals = append(intervals, interval{start: uintptr(i), length: int64(test.size)}) 97 } 98 } 99 shuffle(intervals, int64(testRepeat)) 100 set := intervalSet{} 101 coveredMap := make(map[uintptr]struct{}) 102 for _, x := range intervals { 103 set.add(x) 104 for j := uintptr(0); j < uintptr(x.length); j++ { 105 coveredMap[x.start+j] = struct{}{} 106 } 107 if r.Float64() < test.sampleProb { 108 gotCovered := set.totalCovered() 109 if gotCovered != len(coveredMap) { 110 t.Errorf("set.Covered()=%d, len(coveredMap) = %d", gotCovered, len(coveredMap)) 111 } 112 } 113 } 114 115 if gotSize := set.totalCovered(); gotSize != test.size+test.setsize-1 { 116 t.Errorf("total covering - got: %d, expected %d", gotSize, test.setsize+test.setsize-1) 117 } 118 } 119 } 120 } 121 122 // randomly shuffle a set of intervals 123 func shuffle(set []interval, seed int64) { 124 r := rand.New(rand.NewSource(seed)) 125 r.Shuffle(len(set), func(i, j int) { 126 set[i], set[j] = set[j], set[i] 127 }) 128 }