@@ -22,14 +22,11 @@ type bitmapNumber interface {
2222
2323type Bitmap [T bitmapNumber ] struct {
2424 bits []uint64
25- mask int
2625}
2726
2827func NewBitmap [T bitmapNumber ](size int ) * Bitmap [T ] {
29- numElems := 1 << bits .Len64 (uint64 (size + 63 )/ 64 )
3028 return & Bitmap [T ]{
31- bits : make ([]uint64 , numElems ),
32- mask : numElems - 1 ,
29+ bits : make ([]uint64 , 1 << bits .Len64 (uint64 (size + 63 )/ 64 )),
3330 }
3431}
3532
@@ -38,61 +35,71 @@ func (b *Bitmap[T]) Len() int {
3835}
3936
4037func (b * Bitmap [T ]) Set (val T ) {
41- s , o := b .getSlotAndOffset (val )
42- b .bits [s & b .mask ] |= 1 << o
38+ sm , s , o := b .getSlotAndOffset (val )
39+ b .bits [s & sm ] |= 1 << o
40+ }
41+
42+ func (b * Bitmap [T ]) GetAndSet (val T ) bool {
43+ sm , s , o := b .getSlotAndOffset (val )
44+ prev := b .bits [s & sm ]& (1 << o ) != 0
45+ b .bits [s & sm ] |= 1 << o
46+ return prev
4347}
4448
4549func (b * Bitmap [T ]) SetRange (min , max T ) {
4650 if max < min {
4751 return
4852 }
4953
50- ls , rs , lo , ro := b .getSlotsAndOffsets (min , max )
54+ sm , ls , rs , lo , ro := b .getSlotsAndOffsets (min , max )
5155 if ls == rs {
52- b .bits [ls & b . mask ] |= (((1 << (ro - lo + 1 )) - 1 ) << lo )
56+ b .bits [ls & sm ] |= (((1 << (ro - lo + 1 )) - 1 ) << lo )
5357 } else {
54- b .bits [ls & b . mask ] |= ^ ((1 << lo ) - 1 )
58+ b .bits [ls & sm ] |= ^ ((1 << lo ) - 1 )
5559 for i := ls + 1 ; i < rs ; i ++ {
56- b .bits [i & b . mask ] = ^ uint64 (0 )
60+ b .bits [i & sm ] = ^ uint64 (0 )
5761 }
58- b .bits [rs & b . mask ] |= (1 << (ro + 1 )) - 1
62+ b .bits [rs & sm ] |= (1 << (ro + 1 )) - 1
5963 }
6064}
6165
6266func (b * Bitmap [T ]) Clear (val T ) {
63- s , o := b .getSlotAndOffset (val )
64- b .bits [s & b . mask ] &= ^ (1 << o )
67+ sm , s , o := b .getSlotAndOffset (val )
68+ b .bits [s & sm ] &= ^ (1 << o )
6569}
6670
6771func (b * Bitmap [T ]) ClearRange (min , max T ) {
6872 if max < min {
6973 return
7074 }
7175
72- ls , rs , lo , ro := b .getSlotsAndOffsets (min , max )
76+ sm , ls , rs , lo , ro := b .getSlotsAndOffsets (min , max )
7377 if ls == rs {
74- b .bits [ls & b . mask ] &= ^ (((1 << (ro - lo + 1 )) - 1 ) << lo )
78+ b .bits [ls & sm ] &= ^ (((1 << (ro - lo + 1 )) - 1 ) << lo )
7579 } else {
76- b .bits [ls & b . mask ] &= ^ uint64 (0 ) >> (64 - lo )
80+ b .bits [ls & sm ] &= ^ uint64 (0 ) >> (64 - lo )
7781 for i := ls + 1 ; i < rs ; i ++ {
78- b .bits [i & b . mask ] = 0
82+ b .bits [i & sm ] = 0
7983 }
80- b .bits [rs & b . mask ] &= ^ uint64 (0 ) << (ro + 1 )
84+ b .bits [rs & sm ] &= ^ uint64 (0 ) << (ro + 1 )
8185 }
8286}
8387
8488func (b * Bitmap [T ]) IsSet (val T ) bool {
85- s , o := b .getSlotAndOffset (val )
86- return b .bits [s & b . mask ]& (1 << o ) != 0
89+ sm , s , o := b .getSlotAndOffset (val )
90+ return b .bits [s & sm ]& (1 << o ) != 0
8791}
8892
89- func (b * Bitmap [T ]) getSlotAndOffset (val T ) (s , o int ) {
90- s = int (val >> 6 ) // slot
91- o = int (val & 0x3f ) // offset
93+ func (b * Bitmap [T ]) getSlotAndOffset (val T ) (sm , s , o int ) {
94+ sm = len (b .bits ) - 1 // slot mask
95+ s = int (val >> 6 ) // slot
96+ o = int (val & 0x3f ) // offset
9297 return
9398}
9499
95- func (b * Bitmap [T ]) getSlotsAndOffsets (min , max T ) (ls , rs , lo , ro int ) {
100+ func (b * Bitmap [T ]) getSlotsAndOffsets (min , max T ) (sm , ls , rs , lo , ro int ) {
101+ sm = len (b .bits ) - 1 // slot mask
102+
96103 ls = int (min >> 6 ) // left slot
97104 rs = int (max >> 6 ) // right slot
98105
0 commit comments