github.com/cilium/cilium@v1.16.2/pkg/container/immset_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package container
     5  
     6  import (
     7  	"math/rand/v2"
     8  	"net/netip"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func TestImmSetFunc(t *testing.T) {
    15  	// Test the ImmSet with netip.Addr.
    16  	a1, a2, a3 := netip.MustParseAddr("1.1.1.1"), netip.MustParseAddr("2.2.2.2"), netip.MustParseAddr("3.3.3.3")
    17  
    18  	// Empty set
    19  	s := NewImmSetFunc[netip.Addr](netip.Addr.Compare)
    20  	assert.Equal(t, 0, s.Len(), "expected 0 len for empty set")
    21  	assert.True(t, s.Equal(s), "expected empty set to equal itself")
    22  
    23  	s = s.Insert(a1)
    24  	assert.Equal(t, 1, s.Len(), "expected length of 1 after Insert")
    25  	s = s.Insert(a2)
    26  	assert.Equal(t, 2, s.Len(), "expected length of 2 after second Insert")
    27  	assert.ElementsMatch(t, s.AsSlice(), []netip.Addr{a1, a2})
    28  
    29  	s1 := s.Delete(a2)
    30  	assert.Equal(t, 2, s.Len(), "expected length of 2 for original")
    31  	assert.Equal(t, 1, s1.Len(), "expected length of 1 after Delete")
    32  
    33  	// Initialized set
    34  	s2 := NewImmSetFunc[netip.Addr](netip.Addr.Compare, a1, a2, a3)
    35  	assert.Equal(t, 3, s2.Len(), "expected length of 3 for initialized set")
    36  
    37  	s2 = s2.Difference(s)
    38  	assert.Equal(t, 1, s2.Len(), "expected length of 1 after diff")
    39  	assert.ElementsMatch(t, s2.AsSlice(), []netip.Addr{a3})
    40  
    41  	s2 = s2.Delete(a2 /* no-op */, a3)
    42  	assert.Equal(t, 0, s2.Len(), "expected length of 0 after final delete")
    43  
    44  	s2 = s2.Delete(a3)
    45  	assert.Equal(t, 0, s2.Len(), "expected no change in length after nop delete")
    46  }
    47  
    48  func TestImmSet(t *testing.T) {
    49  	// Empty set
    50  	s := NewImmSet[int]()
    51  	assert.Equal(t, 0, s.Len(), "expected 0 len for empty set")
    52  	assert.True(t, s.Equal(s), "expected empty set to equal itself")
    53  
    54  	s = s.Insert(1)
    55  	assert.Equal(t, 1, s.Len(), "expected length of 1 after Insert")
    56  	s = s.Insert(2)
    57  	assert.Equal(t, 2, s.Len(), "expected length of 2 after second Insert")
    58  	assert.ElementsMatch(t, s.AsSlice(), []int{1, 2})
    59  
    60  	s1 := s.Delete(2)
    61  	assert.Equal(t, 2, s.Len(), "expected length of 2 for original")
    62  	assert.Equal(t, 1, s1.Len(), "expected length of 1 after Delete")
    63  
    64  	// Initialized set
    65  	s2 := NewImmSet[int](1, 2, 3)
    66  	assert.Equal(t, 3, s2.Len(), "expected length of 3 for initialized set")
    67  
    68  	s2 = s2.Difference(s)
    69  	assert.Equal(t, 1, s2.Len(), "expected length of 1 after diff")
    70  	assert.ElementsMatch(t, s2.AsSlice(), []int{3})
    71  
    72  	s2 = s2.Delete(2 /* no-op */, 3)
    73  	assert.Equal(t, 0, s2.Len(), "expected length of 0 after final delete")
    74  
    75  	s2 = s2.Delete(3)
    76  	assert.Equal(t, 0, s2.Len(), "expected no change in length after nop delete")
    77  }
    78  
    79  func TestImmSetUnion(t *testing.T) {
    80  	// Overlapping sets
    81  	s1 := NewImmSet(1, 2, 3)
    82  	assert.Equal(t, 3, s1.Len(), "expected length of 3 for initialized set")
    83  	assert.True(t, s1.Has(1), "expected value 1 to be in the set")
    84  	assert.True(t, s1.Has(2), "expected value 2 to be in the set")
    85  	assert.True(t, s1.Has(3), "expected value 3 to be in the set")
    86  	assert.False(t, s1.Has(4), "expected value 4 to not be in the set")
    87  
    88  	s2 := NewImmSet(3, 4, 5)
    89  	assert.Equal(t, 3, s2.Len(), "expected length of 3 for initialized set")
    90  	assert.False(t, s2.Has(1), "expected value 1 to not be in the set")
    91  	assert.True(t, s2.Has(3), "expected value 3 to be in the set")
    92  	assert.True(t, s2.Has(4), "expected value 4 to be in the set")
    93  	assert.True(t, s2.Has(5), "expected value 5 to be in the set")
    94  
    95  	s3 := s1.Union(s2)
    96  	assert.Equal(t, 5, s3.Len(), "expected length of 5 for the union set")
    97  	assert.True(t, s3.Has(1), "expected value 1 to be in the set")
    98  	assert.True(t, s3.Has(2), "expected value 2 to be in the set")
    99  	assert.True(t, s3.Has(3), "expected value 3 to be in the set")
   100  	assert.True(t, s3.Has(4), "expected value 4 to be in the set")
   101  	assert.True(t, s3.Has(5), "expected value 5 to be in the set")
   102  
   103  	// Disjoint sets
   104  	s4 := NewImmSet(1, 2)
   105  	assert.Equal(t, 2, s4.Len(), "expected length of 2 for initialized set")
   106  	assert.True(t, s4.Has(1), "expected value 1 to be in the set")
   107  	assert.True(t, s4.Has(2), "expected value 2 to be in the set")
   108  	assert.False(t, s4.Has(3), "expected value 3 to not be in the set")
   109  
   110  	s5 := NewImmSet(3, 4)
   111  	assert.Equal(t, 2, s5.Len(), "expected length of 2 for initialized set")
   112  	assert.False(t, s5.Has(1), "expected value 1 to not be in the set")
   113  	assert.True(t, s5.Has(3), "expected value 3 to be in the set")
   114  	assert.True(t, s5.Has(4), "expected value 4 to be in the set")
   115  
   116  	s6 := s4.Union(s5)
   117  	assert.Equal(t, 4, s6.Len(), "expected length of 4 for the union set")
   118  	assert.True(t, s6.Has(1), "expected value 1 to be in the set")
   119  	assert.True(t, s6.Has(2), "expected value 2 to be in the set")
   120  	assert.True(t, s6.Has(3), "expected value 3 to be in the set")
   121  	assert.True(t, s6.Has(4), "expected value 4 to be in the set")
   122  }
   123  
   124  func benchmarkImmSetInsert(b *testing.B, numItems int) {
   125  	s := NewImmSet[int]()
   126  	for i := 0; i < numItems; i++ {
   127  		s = s.Insert(i)
   128  	}
   129  	for n := 0; n < b.N; n++ {
   130  		s.Insert(numItems)
   131  	}
   132  }
   133  
   134  func BenchmarkImmSetInsert_100(b *testing.B)   { benchmarkImmSetInsert(b, 100) }
   135  func BenchmarkImmSetInsert_1000(b *testing.B)  { benchmarkImmSetInsert(b, 1000) }
   136  func BenchmarkImmSetInsert_10000(b *testing.B) { benchmarkImmSetInsert(b, 10000) }
   137  
   138  func benchmarkImmSetInsertMany(b *testing.B, numItems int) {
   139  	a1 := make([]int, numItems)
   140  	a2 := make([]int, numItems)
   141  	for i := 0; i < numItems; i++ {
   142  		a1[i] = int(rand.IntN(numItems))
   143  		a2[i] = int(rand.IntN(numItems))
   144  	}
   145  	s := NewImmSet(a1...)
   146  	b.ResetTimer()
   147  	for n := 0; n < b.N; n++ {
   148  		s.Insert(a2...)
   149  	}
   150  }
   151  
   152  func BenchmarkImmSetInsertMany_100(b *testing.B) {
   153  	benchmarkImmSetInsertMany(b, 100)
   154  }
   155  func BenchmarkImmSetInsertMany_1000(b *testing.B) {
   156  	benchmarkImmSetInsertMany(b, 1000)
   157  }
   158  func BenchmarkImmSetInsertMany_10000(b *testing.B) {
   159  	benchmarkImmSetInsertMany(b, 10000)
   160  }
   161  
   162  func benchmarkImmSetDelete(b *testing.B, numItems int) {
   163  	s := NewImmSet[int]()
   164  	for i := 0; i < numItems; i++ {
   165  		s = s.Insert(i)
   166  	}
   167  	idx := rand.IntN(numItems)
   168  	b.ResetTimer()
   169  
   170  	for n := 0; n < b.N; n++ {
   171  		s.Delete(idx)
   172  	}
   173  }
   174  
   175  func BenchmarkImmSetDelete_100(b *testing.B)   { benchmarkImmSetDelete(b, 100) }
   176  func BenchmarkImmSetDelete_1000(b *testing.B)  { benchmarkImmSetDelete(b, 1000) }
   177  func BenchmarkImmSetDelete_10000(b *testing.B) { benchmarkImmSetDelete(b, 10000) }
   178  
   179  func benchmarkImmSetDeleteMany(b *testing.B, numItems int) {
   180  	s := NewImmSet[int]()
   181  	a := make([]int, 0, numItems)
   182  	for i := 0; i < numItems; i++ {
   183  		s = s.Insert(int(rand.IntN(numItems)))
   184  		a = append(a, int(rand.IntN(numItems)))
   185  	}
   186  	b.ResetTimer()
   187  
   188  	for n := 0; n < b.N; n++ {
   189  		s.Delete(a...)
   190  	}
   191  }
   192  
   193  func BenchmarkImmSetDeleteMany_100(b *testing.B) {
   194  	benchmarkImmSetDeleteMany(b, 100)
   195  }
   196  func BenchmarkImmSetDeleteMany_1000(b *testing.B) {
   197  	benchmarkImmSetDeleteMany(b, 1000)
   198  }
   199  func BenchmarkImmSetDeleteMany_10000(b *testing.B) {
   200  	benchmarkImmSetDeleteMany(b, 10000)
   201  }
   202  
   203  func benchmarkImmSetDifference(b *testing.B, numItems int) {
   204  	s1 := NewImmSet[int]()
   205  	s2 := NewImmSet[int]()
   206  	for i := 0; i < numItems; i++ {
   207  		s1 = s1.Insert(int(rand.IntN(numItems)))
   208  		s2 = s2.Insert(int(rand.IntN(numItems)))
   209  	}
   210  	b.ResetTimer()
   211  
   212  	for n := 0; n < b.N; n++ {
   213  		s1.Difference(s2)
   214  	}
   215  }
   216  
   217  func BenchmarkImmSetDifference_100(b *testing.B) {
   218  	benchmarkImmSetDifference(b, 100)
   219  }
   220  func BenchmarkImmSetDifference_1000(b *testing.B) {
   221  	benchmarkImmSetDifference(b, 1000)
   222  }
   223  func BenchmarkImmSetDifference_10000(b *testing.B) {
   224  	benchmarkImmSetDifference(b, 10000)
   225  }
   226  
   227  func benchmarkImmSetUnion(b *testing.B, numItems int) {
   228  	a1 := make([]int, numItems)
   229  	a2 := make([]int, numItems)
   230  	for i := 0; i < numItems; i++ {
   231  		a1[i] = int(rand.IntN(numItems))
   232  		a2[i] = int(rand.IntN(numItems))
   233  	}
   234  	s1 := NewImmSet(a1...)
   235  	s2 := NewImmSet(a2...)
   236  	b.ResetTimer()
   237  	for n := 0; n < b.N; n++ {
   238  		s1.Union(s2)
   239  	}
   240  }
   241  
   242  func BenchmarkImmSetUnion_100(b *testing.B)   { benchmarkImmSetUnion(b, 100) }
   243  func BenchmarkImmSetUnion_1000(b *testing.B)  { benchmarkImmSetUnion(b, 1000) }
   244  func BenchmarkImmSetUnion_10000(b *testing.B) { benchmarkImmSetUnion(b, 10000) }