diff --git a/libs/common/bit_array.go b/libs/common/bit_array.go index 0290921a..50c6f12e 100644 --- a/libs/common/bit_array.go +++ b/libs/common/bit_array.go @@ -8,13 +8,15 @@ import ( "sync" ) +// BitArray is a thread-safe implementation of a bit array. type BitArray struct { mtx sync.Mutex Bits int `json:"bits"` // NOTE: persisted via reflect, must be exported Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported } -// There is no BitArray whose Size is 0. Use nil instead. +// NewBitArray returns a new bit array. +// It returns nil if the number of bits is zero. func NewBitArray(bits int) *BitArray { if bits <= 0 { return nil @@ -25,6 +27,7 @@ func NewBitArray(bits int) *BitArray { } } +// Size returns the number of bits in the bitarray func (bA *BitArray) Size() int { if bA == nil { return 0 @@ -32,7 +35,8 @@ func (bA *BitArray) Size() int { return bA.Bits } -// NOTE: behavior is undefined if i >= bA.Bits +// GetIndex returns the bit at index i within the bit array. +// The behavior is undefined if i >= bA.Bits func (bA *BitArray) GetIndex(i int) bool { if bA == nil { return false @@ -49,7 +53,8 @@ func (bA *BitArray) getIndex(i int) bool { return bA.Elems[i/64]&(uint64(1)< 0 } -// NOTE: behavior is undefined if i >= bA.Bits +// SetIndex sets the bit at index i within the bit array. +// The behavior is undefined if i >= bA.Bits func (bA *BitArray) SetIndex(i int, v bool) bool { if bA == nil { return false @@ -71,6 +76,7 @@ func (bA *BitArray) setIndex(i int, v bool) bool { return true } +// Copy returns a copy of the provided bit array. func (bA *BitArray) Copy() *BitArray { if bA == nil { return nil @@ -98,7 +104,9 @@ func (bA *BitArray) copyBits(bits int) *BitArray { } } -// Returns a BitArray of larger bits size. +// Or returns a bit array resulting from a bitwise OR of the two bit arrays. +// If the two bit-arrys have different lengths, Or right-pads the smaller of the two bit-arrays with zeroes. +// Thus the size of the return value is the maximum of the two provided bit arrays. func (bA *BitArray) Or(o *BitArray) *BitArray { if bA == nil && o == nil { return nil @@ -118,7 +126,9 @@ func (bA *BitArray) Or(o *BitArray) *BitArray { return c } -// Returns a BitArray of smaller bit size. +// And returns a bit array resulting from a bitwise AND of the two bit arrays. +// If the two bit-arrys have different lengths, this truncates the larger of the two bit-arrays from the right. +// Thus the size of the return value is the minimum of the two provided bit arrays. func (bA *BitArray) And(o *BitArray) *BitArray { if bA == nil || o == nil { return nil @@ -136,6 +146,7 @@ func (bA *BitArray) and(o *BitArray) *BitArray { return c } +// Not returns a bit array resulting from a bitwise Not of the provided bit array. func (bA *BitArray) Not() *BitArray { if bA == nil { return nil // Degenerate @@ -149,6 +160,9 @@ func (bA *BitArray) Not() *BitArray { return c } +// Sub subtracts the two bit-arrays bitwise, without carrying the bits. +// This is essentially bA.And(o.Not()). +// If bA is longer than o, o is right padded with zeroes. func (bA *BitArray) Sub(o *BitArray) *BitArray { if bA == nil || o == nil { // TODO: Decide if we should do 1's complement here? @@ -173,6 +187,7 @@ func (bA *BitArray) Sub(o *BitArray) *BitArray { return bA.and(o.Not()) // Note degenerate case where o == nil } +// IsEmpty returns true iff all bits in the bit array are 0 func (bA *BitArray) IsEmpty() bool { if bA == nil { return true // should this be opposite? @@ -187,6 +202,7 @@ func (bA *BitArray) IsEmpty() bool { return true } +// IsFull returns true iff all bits in the bit array are 1. func (bA *BitArray) IsFull() bool { if bA == nil { return true @@ -207,6 +223,8 @@ func (bA *BitArray) IsFull() bool { return (lastElem+1)&((uint64(1)<