github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/utils/bitmap_test.go (about) 1 // Copyright 2023 LiveKit, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package utils 16 17 import ( 18 "math" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 ) 23 24 func TestBitmap(t *testing.T) { 25 b := NewBitmap[uint32](153) 26 require.Equal(t, 4, cap(b.bits)) // rounded up to next power of 2, i. e. 256 27 require.Equal(t, 4, len(b.bits)) 28 29 e := make([]uint64, 4) 30 require.Equal(t, e, b.bits) 31 32 b.Set(666666) 33 require.True(t, b.IsSet(666666)) 34 require.True(t, b.IsSet(666666+256)) // aliased 35 require.True(t, b.IsSet(666666-256)) // aliased 36 require.False(t, b.IsSet(666666-1)) 37 require.False(t, b.IsSet(666666+1)) 38 39 copy(e, b.bits) 40 b.Set(42) // same as above - aliased 41 require.Equal(t, e, b.bits) 42 43 // same slot range 44 b.SetRange(24, 63) 45 // different slot range 46 b.SetRange(64, 240) 47 require.False(t, b.IsSet(241)) 48 require.False(t, b.IsSet(23)) 49 require.True(t, b.IsSet(24)) 50 require.True(t, b.IsSet(240)) 51 e[0] = 0xFFFF_FFFF_FF00_0000 52 e[1] = ^uint64(0) 53 e[2] = ^uint64(0) 54 e[3] = 0x0001_FFFF_FFFF_FFFF 55 require.Equal(t, e, b.bits) 56 57 b.Clear(6700) // aliases to 44 58 e[0] = 0xFFFF_EFFF_FF00_0000 59 require.Equal(t, e, b.bits) 60 require.False(t, b.IsSet(44)) 61 62 // same slot range 63 b.ClearRange(24, 34) 64 e[0] = 0xFFFF_EFF8_0000_0000 65 require.Equal(t, e, b.bits) 66 require.False(t, b.IsSet(24)) 67 require.True(t, b.IsSet(35)) 68 69 // different slot range 70 b.ClearRange(95, 234) 71 e[1] = 0x0000_0000_7FFF_FFFF 72 e[2] = 0x0 73 e[3] = 0x0001_F800_0000_0000 74 require.Equal(t, e, b.bits) 75 require.True(t, b.IsSet(94)) 76 require.False(t, b.IsSet(95)) 77 require.False(t, b.IsSet(234)) 78 require.True(t, b.IsSet(235)) 79 80 // set large range 81 b.SetRange(0, 1000) 82 e[0] = 0xFFFF_FFFF_FFFF_FFFF 83 e[1] = 0xFFFF_FFFF_FFFF_FFFF 84 e[2] = 0xFFFF_FFFF_FFFF_FFFF 85 e[3] = 0xFFFF_FFFF_FFFF_FFFF 86 require.Equal(t, e, b.bits) 87 88 // clear large range 89 b.ClearRange(0, 1000) 90 e[0] = 0x0000_0000_0000_0000 91 e[1] = 0x0000_0000_0000_0000 92 e[2] = 0x0000_0000_0000_0000 93 e[3] = 0x0000_0000_0000_0000 94 require.Equal(t, e, b.bits) 95 96 // large range changes touch each word once 97 sm, ls, rs, lo, ro := b.getSlotsAndOffsets(0, math.MaxUint32) 98 require.Equal(t, []int{3, 0, 4, 0, 0}, []int{sm, ls, rs, lo, ro}) 99 }