2016-02-20 19:56:48 +00:00
|
|
|
package structs
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
// Bitmap is a simple uncompressed bitmap
|
|
|
|
type Bitmap []byte
|
|
|
|
|
|
|
|
// NewBitmap returns a bitmap with up to size indexes
|
2016-08-05 23:08:35 +00:00
|
|
|
func NewBitmap(size uint) (Bitmap, error) {
|
|
|
|
if size == 0 {
|
2016-02-20 19:56:48 +00:00
|
|
|
return nil, fmt.Errorf("bitmap must be positive size")
|
|
|
|
}
|
|
|
|
if size&7 != 0 {
|
|
|
|
return nil, fmt.Errorf("bitmap must be byte aligned")
|
|
|
|
}
|
|
|
|
b := make([]byte, size>>3)
|
|
|
|
return Bitmap(b), nil
|
|
|
|
}
|
|
|
|
|
2016-08-05 23:08:35 +00:00
|
|
|
// Copy returns a copy of the Bitmap
|
|
|
|
func (b Bitmap) Copy() (Bitmap, error) {
|
|
|
|
if b == nil {
|
|
|
|
return nil, fmt.Errorf("can't copy nil Bitmap")
|
|
|
|
}
|
|
|
|
|
2016-08-10 23:37:26 +00:00
|
|
|
raw := make([]byte, len(b))
|
|
|
|
copy(raw, b)
|
|
|
|
return Bitmap(raw), nil
|
2016-08-05 23:08:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Size returns the size of the bitmap
|
|
|
|
func (b Bitmap) Size() uint {
|
|
|
|
return uint(len(b) << 3)
|
|
|
|
}
|
|
|
|
|
2016-02-20 19:56:48 +00:00
|
|
|
// Set is used to set the given index of the bitmap
|
|
|
|
func (b Bitmap) Set(idx uint) {
|
|
|
|
bucket := idx >> 3
|
|
|
|
mask := byte(1 << (idx & 7))
|
|
|
|
b[bucket] |= mask
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check is used to check the given index of the bitmap
|
|
|
|
func (b Bitmap) Check(idx uint) bool {
|
|
|
|
bucket := idx >> 3
|
|
|
|
mask := byte(1 << (idx & 7))
|
|
|
|
return (b[bucket] & mask) != 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear is used to efficiently clear the bitmap
|
|
|
|
func (b Bitmap) Clear() {
|
|
|
|
for i := range b {
|
|
|
|
b[i] = 0
|
|
|
|
}
|
|
|
|
}
|
2016-08-05 23:08:35 +00:00
|
|
|
|
2016-08-10 23:37:26 +00:00
|
|
|
// IndexesInRange returns the indexes in which the values are either set or unset based
|
|
|
|
// on the passed parameter in the passed range
|
|
|
|
func (b Bitmap) IndexesInRange(set bool, from, to uint) []int {
|
2016-08-10 18:47:20 +00:00
|
|
|
var indexes []int
|
2016-08-15 20:13:04 +00:00
|
|
|
for i := from; i <= to; i++ {
|
2016-08-05 23:08:35 +00:00
|
|
|
c := b.Check(i)
|
|
|
|
if c && set || !c && !set {
|
2016-08-10 18:47:20 +00:00
|
|
|
indexes = append(indexes, int(i))
|
2016-08-05 23:08:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return indexes
|
|
|
|
}
|