get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/avl/seqset_test.go (about) 1 // Copyright 2023 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package avl 15 16 import ( 17 "encoding/base64" 18 "math/rand" 19 "testing" 20 ) 21 22 func TestSeqSetBasics(t *testing.T) { 23 var ss SequenceSet 24 25 seqs := []uint64{22, 222, 2000, 2, 2, 4} 26 for _, seq := range seqs { 27 ss.Insert(seq) 28 require_True(t, ss.Exists(seq)) 29 } 30 31 require_True(t, ss.Nodes() == 1) 32 require_True(t, ss.Size() == len(seqs)-1) // We have one dup in there. 33 lh, rh := ss.Heights() 34 require_True(t, lh == 0) 35 require_True(t, rh == 0) 36 } 37 38 func TestSeqSetLeftLean(t *testing.T) { 39 var ss SequenceSet 40 41 for i := uint64(4 * numEntries); i > 0; i-- { 42 ss.Insert(i) 43 } 44 45 require_True(t, ss.Nodes() == 5) 46 require_True(t, ss.Size() == 4*numEntries) 47 lh, rh := ss.Heights() 48 require_True(t, lh == 2) 49 require_True(t, rh == 1) 50 } 51 52 func TestSeqSetRightLean(t *testing.T) { 53 var ss SequenceSet 54 55 for i := uint64(0); i < uint64(4*numEntries); i++ { 56 ss.Insert(i) 57 } 58 59 require_True(t, ss.Nodes() == 4) 60 require_True(t, ss.Size() == 4*numEntries) 61 lh, rh := ss.Heights() 62 require_True(t, lh == 1) 63 require_True(t, rh == 2) 64 } 65 66 func TestSeqSetCorrectness(t *testing.T) { 67 // Generate 100k sequences across 500k range. 68 num := 100_000 69 max := 500_000 70 71 set := make(map[uint64]struct{}, num) 72 var ss SequenceSet 73 for i := 0; i < num; i++ { 74 n := uint64(rand.Int63n(int64(max + 1))) 75 ss.Insert(n) 76 set[n] = struct{}{} 77 } 78 79 for i := uint64(0); i <= uint64(max); i++ { 80 _, exists := set[i] 81 require_True(t, ss.Exists(i) == exists) 82 } 83 } 84 85 func TestSeqSetRange(t *testing.T) { 86 num := 2*numEntries + 22 87 nums := make([]uint64, 0, num) 88 for i := 0; i < num; i++ { 89 nums = append(nums, uint64(i)) 90 } 91 rand.Shuffle(len(nums), func(i, j int) { nums[i], nums[j] = nums[j], nums[i] }) 92 93 var ss SequenceSet 94 for _, n := range nums { 95 ss.Insert(n) 96 } 97 98 nums = nums[:0] 99 ss.Range(func(n uint64) bool { 100 nums = append(nums, n) 101 return true 102 }) 103 require_True(t, len(nums) == num) 104 for i := uint64(0); i < uint64(num); i++ { 105 require_True(t, nums[i] == i) 106 } 107 108 // Test truncating the range call. 109 nums = nums[:0] 110 ss.Range(func(n uint64) bool { 111 if n >= 10 { 112 return false 113 } 114 nums = append(nums, n) 115 return true 116 }) 117 require_True(t, len(nums) == 10) 118 for i := uint64(0); i < 10; i++ { 119 require_True(t, nums[i] == i) 120 } 121 } 122 123 func TestSeqSetDelete(t *testing.T) { 124 var ss SequenceSet 125 126 // Simple single node. 127 seqs := []uint64{22, 222, 2222, 2, 2, 4} 128 for _, seq := range seqs { 129 ss.Insert(seq) 130 } 131 132 for _, seq := range seqs { 133 ss.Delete(seq) 134 require_True(t, !ss.Exists(seq)) 135 } 136 require_True(t, ss.root == nil) 137 } 138 139 func TestSeqSetInsertAndDeletePedantic(t *testing.T) { 140 var ss SequenceSet 141 142 num := 50*numEntries + 22 143 nums := make([]uint64, 0, num) 144 for i := 0; i < num; i++ { 145 nums = append(nums, uint64(i)) 146 } 147 rand.Shuffle(len(nums), func(i, j int) { nums[i], nums[j] = nums[j], nums[i] }) 148 149 // Make sure always balanced. 150 testBalanced := func() { 151 t.Helper() 152 // Check heights. 153 ss.root.nodeIter(func(n *node) { 154 if n != nil && n.h != maxH(n)+1 { 155 t.Fatalf("Node height is wrong: %+v", n) 156 } 157 }) 158 // Check balance factor. 159 if bf := balanceF(ss.root); bf > 1 || bf < -1 { 160 t.Fatalf("Unbalanced tree") 161 } 162 } 163 164 for _, n := range nums { 165 ss.Insert(n) 166 testBalanced() 167 } 168 require_True(t, ss.root != nil) 169 170 for _, n := range nums { 171 ss.Delete(n) 172 testBalanced() 173 require_True(t, !ss.Exists(n)) 174 if ss.Size() > 0 { 175 require_True(t, ss.root != nil) 176 } 177 } 178 require_True(t, ss.root == nil) 179 } 180 181 func TestSeqSetMinMax(t *testing.T) { 182 var ss SequenceSet 183 184 // Simple single node. 185 seqs := []uint64{22, 222, 2222, 2, 2, 4} 186 for _, seq := range seqs { 187 ss.Insert(seq) 188 } 189 190 min, max := ss.MinMax() 191 require_True(t, min == 2 && max == 2222) 192 193 // Multi-node 194 ss.Empty() 195 196 num := 22*numEntries + 22 197 nums := make([]uint64, 0, num) 198 for i := 0; i < num; i++ { 199 nums = append(nums, uint64(i)) 200 } 201 rand.Shuffle(len(nums), func(i, j int) { nums[i], nums[j] = nums[j], nums[i] }) 202 for _, n := range nums { 203 ss.Insert(n) 204 } 205 206 min, max = ss.MinMax() 207 require_True(t, min == 0 && max == uint64(num-1)) 208 } 209 210 func TestSeqSetClone(t *testing.T) { 211 // Generate 100k sequences across 500k range. 212 num := 100_000 213 max := 500_000 214 215 var ss SequenceSet 216 for i := 0; i < num; i++ { 217 ss.Insert(uint64(rand.Int63n(int64(max + 1)))) 218 } 219 220 ssc := ss.Clone() 221 require_True(t, ss.Size() == ssc.Size()) 222 require_True(t, ss.Nodes() == ssc.Nodes()) 223 } 224 225 func TestSeqSetUnion(t *testing.T) { 226 var ss1, ss2 SequenceSet 227 228 seqs1 := []uint64{22, 222, 2222, 2, 2, 4} 229 for _, seq := range seqs1 { 230 ss1.Insert(seq) 231 } 232 233 seqs2 := []uint64{33, 333, 3333, 3, 33_333, 333_333} 234 for _, seq := range seqs2 { 235 ss2.Insert(seq) 236 } 237 238 ss := Union(&ss1, &ss2) 239 require_True(t, ss.Size() == 11) 240 241 seqs := append(seqs1, seqs2...) 242 for _, n := range seqs { 243 require_True(t, ss.Exists(n)) 244 } 245 } 246 247 func TestSeqSetFirst(t *testing.T) { 248 var ss SequenceSet 249 250 seqs := []uint64{22, 222, 2222, 222_222} 251 for _, seq := range seqs { 252 // Normal case where we pick first/base. 253 ss.Insert(seq) 254 require_True(t, ss.root.base == (seq/numEntries)*numEntries) 255 ss.Empty() 256 // Where we set the minimum start value. 257 ss.SetInitialMin(seq) 258 ss.Insert(seq) 259 require_True(t, ss.root.base == seq) 260 ss.Empty() 261 } 262 } 263 264 // Test that we can union with nodes vs individual sequence insertion. 265 func TestSeqSetDistinctUnion(t *testing.T) { 266 // Distinct sets. 267 var ss1 SequenceSet 268 seqs1 := []uint64{1, 10, 100, 200} 269 for _, seq := range seqs1 { 270 ss1.Insert(seq) 271 } 272 273 var ss2 SequenceSet 274 seqs2 := []uint64{5000, 6100, 6200, 6222} 275 for _, seq := range seqs2 { 276 ss2.Insert(seq) 277 } 278 279 ss := ss1.Clone() 280 allSeqs := append(seqs1, seqs2...) 281 282 ss.Union(&ss2) 283 require_True(t, ss.Size() == len(allSeqs)) 284 for _, seq := range allSeqs { 285 require_True(t, ss.Exists(seq)) 286 } 287 } 288 289 func TestSeqSetDecodeV1(t *testing.T) { 290 // Encoding from v1 which was 64 buckets. 291 seqs := []uint64{22, 222, 2222, 222_222, 2_222_222} 292 encStr := ` 293 FgEDAAAABQAAAABgAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAADgIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA== 294 ` 295 296 enc, err := base64.StdEncoding.DecodeString(encStr) 297 require_NoError(t, err) 298 299 ss, _, err := Decode(enc) 300 require_NoError(t, err) 301 302 require_True(t, ss.Size() == len(seqs)) 303 for _, seq := range seqs { 304 require_True(t, ss.Exists(seq)) 305 } 306 } 307 308 func require_NoError(t *testing.T, err error) { 309 t.Helper() 310 if err != nil { 311 t.Fatalf("require no error, but got: %v", err) 312 } 313 } 314 315 func require_True(t *testing.T, b bool) { 316 t.Helper() 317 if !b { 318 t.Fatalf("require true") 319 } 320 }