-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbitmap.go
68 lines (57 loc) · 1.23 KB
/
bitmap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package collections
import "errors"
const slotShift = 6
type BitMap struct {
slots []uint64
_padding0 [48]byte
cap uint
_padding1 [56]byte
size int
_padding2 [56]byte
}
func NewBitMap(cap uint) *BitMap {
return &BitMap{
slots: make([]uint64, ((uint64(cap)-1)>>slotShift)+1),
cap: cap,
}
}
func (m *BitMap) Set(pos uint) {
m.checkPos(pos)
old := m.slots[pos>>slotShift]
m.slots[pos>>slotShift] |= uint64(1) << pos
if m.slots[pos>>slotShift] != old {
m.size++
}
}
func (m *BitMap) GetWithoutCheck(pos uint) bool {
return m.slots[pos>>slotShift]&(uint64(1)<<pos) != 0
}
func (m *BitMap) Get(pos uint) bool {
m.checkPos(pos)
return m.slots[pos>>slotShift]&(uint64(1)<<pos) != 0
}
func (m *BitMap) Clear(pos uint) {
m.checkPos(pos)
old := m.slots[pos>>slotShift]
m.slots[pos>>slotShift] &= ^(uint64(1) << pos)
if m.slots[pos>>slotShift] != old {
m.size--
}
}
func (m *BitMap) Merge(o *BitMap) error {
if m.cap != o.cap {
return errors.New("inconsistent capacity cannot be merged")
}
for i := range m.slots {
m.slots[i] |= o.slots[i]
}
return nil
}
func (m *BitMap) Size() int {
return m.size
}
func (m *BitMap) checkPos(pos uint) {
if pos >= m.cap {
panic("Position exceeds bitmap length")
}
}