@@ -16,16 +16,24 @@ const (
1616// Bits externally represented as `bool` are stored internally as `uint64`s.
1717// The total number of bits stored is set at creation and is immutable.
1818type BitArray struct {
19+ // buf is a backing array that bits writes into by default when the no. of bits requested to allocate is
20+ // < 512. Only if more is asked, we'll skip buf and allocate directly into bits
21+ buf [8 ]Bit
1922 bits []Bit
2023 n int // no. of bits
2124}
2225
23- // New creates a new BitArray of `n` bits.
24- func New (n int ) BitArray {
25- return BitArray {
26- bits : make ([]Bit , int (math .Ceil (float64 (n )/ 64 ))),
27- n : n ,
26+ // New creates a new BitArray of `n` bits. If n <= 512, no allocation is done.
27+ func New (n int ) (ba BitArray ) {
28+ nblk := nbitsToNblks (n )
29+ ba .n = n
30+ ba .bits = ba .buf [:]
31+ if nblk <= 8 {
32+ ba .bits = ba .buf [:nblk ]
33+ return
2834 }
35+ ba .bits = append (ba .bits , make ([]Bit , nblk - len (ba .buf ))... )
36+ return
2937}
3038
3139// Copy copies src into dst.
@@ -65,16 +73,8 @@ func FromUint64(u uint64) BitArray {
6573// Size returns the no. of bits stored.
6674func (ba * BitArray ) Size () int { return ba .n }
6775
68- func biandsi (k int ) (uint64 , uint64 ) {
69- i := uint64 (k )
70- return i / 64 , i % 64
71- }
72-
73- func (ba * BitArray ) set1 (bi , si uint64 ) { ba .bits [bi ] |= 1 << si }
74- func (ba * BitArray ) set0 (bi , si uint64 ) { ba .bits [bi ] &= ^ (1 << si ) }
75-
7676// Set sets the bit at position k.
77- func (ba * BitArray ) Set (k int ) { ba . set1 ( biandsi (k )) }
77+ func (ba * BitArray ) Set (k int ) { bi , si := biandsi (k ); set ( & ba . bits [ bi ], si ) }
7878
7979// SetAll sets all the bits.
8080func (ba * BitArray ) SetAll () {
@@ -84,7 +84,7 @@ func (ba *BitArray) SetAll() {
8484}
8585
8686// Clr clears the bit at position k.
87- func (ba * BitArray ) Clr (k int ) { ba . set0 ( biandsi (k )) }
87+ func (ba * BitArray ) Clr (k int ) { bi , si := biandsi (k ); clr ( & ba . bits [ bi ], si ) }
8888
8989// ClrAll clears all the bits.
9090func (ba * BitArray ) ClrAll () {
@@ -93,25 +93,24 @@ func (ba *BitArray) ClrAll() {
9393 }
9494}
9595
96- func (ba * BitArray ) chk (bi , si uint64 ) bool { return (ba .bits [bi ]>> si )& 1 > 0 }
97-
9896// ChkSet returns the value of the bit at position k before setting it.
9997func (ba * BitArray ) ChkSet (k int ) (b bool ) {
10098 bi , si := biandsi (k )
101- b = ba .chk (bi , si )
99+ u := & ba .bits [bi ]
100+ b = chk (* u , si ) != 0
102101 if ! b {
103- ba . set1 ( bi , si )
102+ set ( u , si )
104103 }
105104 return
106-
107105}
108106
109107// ChkClr returns the value of the bit at position k before clearing it.
110108func (ba * BitArray ) ChkClr (k int ) (b bool ) {
111109 bi , si := biandsi (k )
112- b = ba .chk (bi , si )
110+ u := & ba .bits [bi ]
111+ b = chk (* u , si ) != 0
113112 if b {
114- ba . set0 ( bi , si )
113+ clr ( u , si )
115114 }
116115 return
117116}
@@ -125,29 +124,33 @@ func (ba *BitArray) Tgl(k int) {
125124// Cnt returns the number of set bits.
126125func (ba * BitArray ) Cnt () (n int ) {
127126 for _ , b := range ba .bits {
128- n += bits .OnesCount64 (uint64 ( b ) )
127+ n += bits .OnesCount64 (b )
129128 }
130129 return
131130}
132131
133132// Chk returns the value of the bit at position k.
134133func (ba * BitArray ) Chk (k int ) bool {
135134 bi , si := biandsi (k )
136- return (ba .bits [bi ]>> si )& 1 > 0
135+ return chk (ba .bits [bi ], si ) != 0
137136}
138137
139138// Put sets the value of the bit at position k to v.
140139func (ba * BitArray ) Put (k int , v Bit ) {
141140 bi , si := biandsi (k )
142- ba . bits [ bi ] = ( ba .bits [bi ] & ^ ( 1 << si )) | ( v << si )
141+ put ( & ba .bits [bi ], si , v )
143142}
144143
145144// Swap swaps the value of bit at position k with v. On return, v contains the old value.
146- func (ba * BitArray ) Swap (k int , v * Bit ) {
145+ func (ba * BitArray ) Swap (k int , b * Bit ) {
147146 bi , si := biandsi (k )
148- ob := (ba .bits [bi ] >> si ) & 1
149- ba .bits [bi ] = (ba .bits [bi ] & ^ (1 << si )) | (* v << si )
150- * v = ob
147+ t := & ba .bits [bi ]
148+ ob := chk (* t , si )
149+ if ob == * b {
150+ return
151+ }
152+ put (t , si , ob )
153+ * b = ob
151154}
152155
153156func (ba * BitArray ) String () string {
@@ -160,3 +163,15 @@ func (ba *BitArray) String() string {
160163 }
161164 return string (sb )
162165}
166+
167+ func nbitsToNblks (n int ) int { return int (math .Ceil (float64 (n ) / 64 )) }
168+
169+ func set (u * uint64 , si uint64 ) { * u |= 1 << si }
170+ func clr (u * uint64 , si uint64 ) { * u &= ^ (1 << si ) }
171+ func chk (u uint64 , si uint64 ) Bit { return (u >> si ) & 1 }
172+ func put (u * uint64 , si uint64 , b Bit ) { * u = (* u & ^ (1 << si )) | (b << si ) }
173+
174+ func biandsi (k int ) (uint64 , uint64 ) {
175+ i := uint64 (k )
176+ return i / 64 , i % 64
177+ }
0 commit comments