a41f938cec
As we have seen, dependencies version can prevent the build. We should user lock versions on dependencies that we know work: * Packages are vendored * Add Godep support * Added addtional install step in readme * Fix travis build error
180 lignes
3,1 Kio
Go
180 lignes
3,1 Kio
Go
// Package bitmap provides a []bool/bitmap implementation with standardized
|
|
// iteration. Bitmaps are the equivalent of []bool, with improved compression
|
|
// for runs of similar values, and faster operations on ranges and the like.
|
|
package bitmap
|
|
|
|
import (
|
|
"math"
|
|
|
|
"github.com/RoaringBitmap/roaring"
|
|
)
|
|
|
|
const MaxInt = -1
|
|
|
|
// Bitmaps store the existence of values in [0,math.MaxUint32] more
|
|
// efficiently than []bool. The empty value starts with no bits set.
|
|
type Bitmap struct {
|
|
rb *roaring.Bitmap
|
|
}
|
|
|
|
// The number of set bits in the bitmap. Also known as cardinality.
|
|
func (me *Bitmap) Len() int {
|
|
if me.rb == nil {
|
|
return 0
|
|
}
|
|
return int(me.rb.GetCardinality())
|
|
}
|
|
|
|
func (me Bitmap) ToSortedSlice() (ret []int) {
|
|
if me.rb == nil {
|
|
return
|
|
}
|
|
for _, ui32 := range me.rb.ToArray() {
|
|
ret = append(ret, int(int32(ui32)))
|
|
}
|
|
return
|
|
}
|
|
|
|
func (me *Bitmap) lazyRB() *roaring.Bitmap {
|
|
if me.rb == nil {
|
|
me.rb = roaring.NewBitmap()
|
|
}
|
|
return me.rb
|
|
}
|
|
|
|
func (me *Bitmap) Iter(f func(interface{}) bool) {
|
|
me.IterTyped(func(i int) bool {
|
|
return f(i)
|
|
})
|
|
}
|
|
|
|
// Returns true if all values were traversed without early termination.
|
|
func (me Bitmap) IterTyped(f func(int) bool) bool {
|
|
if me.rb == nil {
|
|
return true
|
|
}
|
|
it := me.rb.Iterator()
|
|
for it.HasNext() {
|
|
if !f(int(it.Next())) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func checkInt(i int) {
|
|
if i < math.MinInt32 || i > math.MaxInt32 {
|
|
panic("out of bounds")
|
|
}
|
|
}
|
|
|
|
func (me *Bitmap) Add(is ...int) {
|
|
rb := me.lazyRB()
|
|
for _, i := range is {
|
|
checkInt(i)
|
|
rb.AddInt(i)
|
|
}
|
|
}
|
|
|
|
func (me *Bitmap) AddRange(begin, end int) {
|
|
if begin >= end {
|
|
return
|
|
}
|
|
me.lazyRB().AddRange(uint64(begin), uint64(end))
|
|
}
|
|
|
|
func (me *Bitmap) Remove(i int) {
|
|
if me.rb == nil {
|
|
return
|
|
}
|
|
me.rb.Remove(uint32(i))
|
|
}
|
|
|
|
func (me *Bitmap) Union(other *Bitmap) {
|
|
me.lazyRB().Or(other.lazyRB())
|
|
}
|
|
|
|
func (me *Bitmap) Contains(i int) bool {
|
|
if me.rb == nil {
|
|
return false
|
|
}
|
|
return me.rb.Contains(uint32(i))
|
|
}
|
|
|
|
type Iter struct {
|
|
ii roaring.IntIterable
|
|
}
|
|
|
|
func (me *Iter) Next() bool {
|
|
if me == nil {
|
|
return false
|
|
}
|
|
return me.ii.HasNext()
|
|
}
|
|
|
|
func (me *Iter) Value() interface{} {
|
|
return me.ValueInt()
|
|
}
|
|
|
|
func (me *Iter) ValueInt() int {
|
|
return int(me.ii.Next())
|
|
}
|
|
|
|
func (me *Iter) Stop() {}
|
|
|
|
func Sub(left, right *Bitmap) *Bitmap {
|
|
return &Bitmap{
|
|
rb: roaring.AndNot(left.lazyRB(), right.lazyRB()),
|
|
}
|
|
}
|
|
|
|
func (me *Bitmap) Sub(other *Bitmap) {
|
|
if other.rb == nil {
|
|
return
|
|
}
|
|
if me.rb == nil {
|
|
return
|
|
}
|
|
me.rb.AndNot(other.rb)
|
|
}
|
|
|
|
func (me *Bitmap) Clear() {
|
|
if me.rb == nil {
|
|
return
|
|
}
|
|
me.rb.Clear()
|
|
}
|
|
|
|
func (me Bitmap) Copy() (ret Bitmap) {
|
|
ret = me
|
|
if ret.rb != nil {
|
|
ret.rb = ret.rb.Clone()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (me *Bitmap) FlipRange(begin, end int) {
|
|
me.lazyRB().FlipInt(begin, end)
|
|
}
|
|
|
|
func (me *Bitmap) Get(bit int) bool {
|
|
return me.rb != nil && me.rb.ContainsInt(bit)
|
|
}
|
|
|
|
func (me *Bitmap) Set(bit int, value bool) {
|
|
if value {
|
|
me.lazyRB().AddInt(bit)
|
|
} else {
|
|
if me.rb != nil {
|
|
me.rb.Remove(uint32(bit))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (me *Bitmap) RemoveRange(begin, end int) *Bitmap {
|
|
if me.rb == nil {
|
|
return me
|
|
}
|
|
me.rb.RemoveRange(uint64(begin), uint64(end))
|
|
return me
|
|
}
|