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  }