package utils
import (
"math"
"testing"
"github.com/stretchr/testify/require"
)
func TestBitmap(t *testing.T) {
b := NewBitmap[uint32](153)
require.Equal(t, 4, cap(b.bits)) require.Equal(t, 4, len(b.bits))
e := make([]uint64, 4)
require.Equal(t, e, b.bits)
b.Set(666666)
require.True(t, b.IsSet(666666))
require.True(t, b.IsSet(666666+256)) require.True(t, b.IsSet(666666-256)) require.False(t, b.IsSet(666666-1))
require.False(t, b.IsSet(666666+1))
copy(e, b.bits)
b.Set(42) require.Equal(t, e, b.bits)
b.SetRange(24, 63)
b.SetRange(64, 240)
require.False(t, b.IsSet(241))
require.False(t, b.IsSet(23))
require.True(t, b.IsSet(24))
require.True(t, b.IsSet(240))
e[0] = 0xFFFF_FFFF_FF00_0000
e[1] = ^uint64(0)
e[2] = ^uint64(0)
e[3] = 0x0001_FFFF_FFFF_FFFF
require.Equal(t, e, b.bits)
b.Clear(6700) e[0] = 0xFFFF_EFFF_FF00_0000
require.Equal(t, e, b.bits)
require.False(t, b.IsSet(44))
b.ClearRange(24, 34)
e[0] = 0xFFFF_EFF8_0000_0000
require.Equal(t, e, b.bits)
require.False(t, b.IsSet(24))
require.True(t, b.IsSet(35))
b.ClearRange(95, 234)
e[1] = 0x0000_0000_7FFF_FFFF
e[2] = 0x0
e[3] = 0x0001_F800_0000_0000
require.Equal(t, e, b.bits)
require.True(t, b.IsSet(94))
require.False(t, b.IsSet(95))
require.False(t, b.IsSet(234))
require.True(t, b.IsSet(235))
b.SetRange(0, 1000)
e[0] = 0xFFFF_FFFF_FFFF_FFFF
e[1] = 0xFFFF_FFFF_FFFF_FFFF
e[2] = 0xFFFF_FFFF_FFFF_FFFF
e[3] = 0xFFFF_FFFF_FFFF_FFFF
require.Equal(t, e, b.bits)
b.ClearRange(0, 1000)
e[0] = 0x0000_0000_0000_0000
e[1] = 0x0000_0000_0000_0000
e[2] = 0x0000_0000_0000_0000
e[3] = 0x0000_0000_0000_0000
require.Equal(t, e, b.bits)
sm, ls, rs, lo, ro := b.getSlotsAndOffsets(0, math.MaxUint32)
require.Equal(t, []int{3, 0, 4, 0, 0}, []int{sm, ls, rs, lo, ro})
}
func BenchmarkBitmap(b *testing.B) {
m := NewBitmap[uint64](128)
b.Run("SetRange", func(b *testing.B) {
for range b.N {
m.SetRange(100, 1100)
}
})
b.Run("Set", func(b *testing.B) {
for i := range b.N {
m.Set(uint64(i))
}
})
b.Run("IsSet/Set", func(b *testing.B) {
for i := range b.N {
_ = m.IsSet(uint64(i))
m.Set(uint64(i))
}
})
b.Run("GetAndSet", func(b *testing.B) {
for i := range b.N {
m.GetAndSet(uint64(i))
}
})
}