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) }