mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 09:05:55 +00:00
Add B+tree to enterprise subpackage
This commit is contained in:
parent
4014f22802
commit
faa79a385c
14 changed files with 476 additions and 456 deletions
4
Makefile
4
Makefile
|
|
@ -39,6 +39,10 @@ cover-viz: cover
|
|||
build: vendor
|
||||
go build -tags release -ldflags $(LDFLAGS) $(FLAGS) ./cmd/pilosa
|
||||
|
||||
# Compile Pilosa EE
|
||||
build-ee: vendor
|
||||
go build -tags release -tags enterprise -ldflags $(LDFLAGS) $(FLAGS) ./cmd/pilosa
|
||||
|
||||
# Create a single release build under the build directory
|
||||
release-build: vendor
|
||||
$(MAKE) $(if $(DOCKER_BUILD),docker-)build FLAGS="-o build/pilosa-$(VERSION_ID)/pilosa"
|
||||
|
|
|
|||
|
|
@ -187,12 +187,12 @@ func (b *Bitmap) createSegmentIfNotExists(slice uint64) *BitmapSegment {
|
|||
}
|
||||
|
||||
// Insert new segment.
|
||||
b.segments = append(b.segments, BitmapSegment{data: *roaring.NewSliceBitmap()})
|
||||
b.segments = append(b.segments, BitmapSegment{data: *roaring.NewBitmap()})
|
||||
if i < len(b.segments) {
|
||||
copy(b.segments[i+1:], b.segments[i:])
|
||||
}
|
||||
b.segments[i] = BitmapSegment{
|
||||
data: *roaring.NewSliceBitmap(),
|
||||
data: *roaring.NewBitmap(),
|
||||
slice: slice,
|
||||
writable: true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func (cmd *CheckCommand) checkBitmapFile(path string) error {
|
|||
defer syscall.Munmap(data)
|
||||
|
||||
// Attach the mmap file to the bitmap.
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
if err := bm.UnmarshalBinary(data); err != nil {
|
||||
return errors.Wrap(err, "unmarshalling")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func (cmd *InspectCommand) Run(ctx context.Context) error {
|
|||
// Attach the mmap file to the bitmap.
|
||||
t := time.Now()
|
||||
fmt.Fprintf(cmd.Stderr, "unmarshaling bitmap...")
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
if err := bm.UnmarshalBinary(data); err != nil {
|
||||
return errors.Wrap(err, "unmarshalling")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,14 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package roaring
|
||||
package b
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/pilosa/pilosa/roaring"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -93,7 +95,7 @@ type (
|
|||
|
||||
de struct { // d element
|
||||
k uint64
|
||||
v *Container
|
||||
v *roaring.Container
|
||||
}
|
||||
|
||||
// Enumerator captures the state of enumerating a tree. It is returned
|
||||
|
|
@ -417,7 +419,7 @@ func (t *Tree) find(q interface{}, k uint64) (i int, ok bool) {
|
|||
|
||||
// First returns the first item of the tree in the key collating order, or
|
||||
// (zero-value, zero-value) if the tree is empty.
|
||||
func (t *Tree) First() (k uint64, v *Container) {
|
||||
func (t *Tree) First() (k uint64, v *roaring.Container) {
|
||||
if q := t.first; q != nil {
|
||||
q := &q.d[0]
|
||||
k, v = q.k, q.v
|
||||
|
|
@ -427,7 +429,7 @@ func (t *Tree) First() (k uint64, v *Container) {
|
|||
|
||||
// Get returns the value associated with k and true if it exists. Otherwise Get
|
||||
// returns (zero-value, false).
|
||||
func (t *Tree) Get(k uint64) (v *Container, ok bool) {
|
||||
func (t *Tree) Get(k uint64) (v *roaring.Container, ok bool) {
|
||||
q := t.r
|
||||
if q == nil {
|
||||
return
|
||||
|
|
@ -453,7 +455,7 @@ func (t *Tree) Get(k uint64) (v *Container, ok bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *Tree) insert(q *d, i int, k uint64, v *Container) *d {
|
||||
func (t *Tree) insert(q *d, i int, k uint64, v *roaring.Container) *d {
|
||||
t.ver++
|
||||
c := q.c
|
||||
if i < c {
|
||||
|
|
@ -468,7 +470,7 @@ func (t *Tree) insert(q *d, i int, k uint64, v *Container) *d {
|
|||
|
||||
// Last returns the last item of the tree in the key collating order, or
|
||||
// (zero-value, zero-value) if the tree is empty.
|
||||
func (t *Tree) Last() (k uint64, v *Container) {
|
||||
func (t *Tree) Last() (k uint64, v *roaring.Container) {
|
||||
if q := t.last; q != nil {
|
||||
q := &q.d[q.c-1]
|
||||
k, v = q.k, q.v
|
||||
|
|
@ -481,7 +483,7 @@ func (t *Tree) Len() int {
|
|||
return t.c
|
||||
}
|
||||
|
||||
func (t *Tree) overflow(p *x, q *d, pi, i int, k uint64, v *Container) {
|
||||
func (t *Tree) overflow(p *x, q *d, pi, i int, k uint64, v *roaring.Container) {
|
||||
t.ver++
|
||||
l, r := p.siblings(pi)
|
||||
|
||||
|
|
@ -577,7 +579,7 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) {
|
|||
}
|
||||
|
||||
// Set sets the value associated with k.
|
||||
func (t *Tree) Set(k uint64, v *Container) {
|
||||
func (t *Tree) Set(k uint64, v *roaring.Container) {
|
||||
//dbg("--- PRE Set(%v, %v)\n%s", k, v, t.dump())
|
||||
//defer func() {
|
||||
// dbg("--- POST\n%s\n====\n", t.dump())
|
||||
|
|
@ -643,11 +645,11 @@ func (t *Tree) Set(k uint64, v *Container) {
|
|||
// tree.Put(k, func(uint64, bool){ return v, true })
|
||||
//
|
||||
// modulo the differing return values.
|
||||
func (t *Tree) Put(k uint64, upd func(oldV *Container, exists bool) (newV *Container, write bool)) (oldV *Container, written bool) {
|
||||
func (t *Tree) Put(k uint64, upd func(oldV *roaring.Container, exists bool) (newV *roaring.Container, write bool)) (oldV *roaring.Container, written bool) {
|
||||
pi := -1
|
||||
var p *x
|
||||
q := t.r
|
||||
var newV *Container
|
||||
var newV *roaring.Container
|
||||
if q == nil {
|
||||
// new KV pair in empty tree
|
||||
newV, written = upd(newV, false)
|
||||
|
|
@ -710,7 +712,7 @@ func (t *Tree) Put(k uint64, upd func(oldV *Container, exists bool) (newV *Conta
|
|||
}
|
||||
}
|
||||
|
||||
func (t *Tree) split(p *x, q *d, pi, i int, k uint64, v *Container) {
|
||||
func (t *Tree) split(p *x, q *d, pi, i int, k uint64, v *roaring.Container) {
|
||||
t.ver++
|
||||
r := btDPool.Get().(*d)
|
||||
if q.n != nil {
|
||||
|
|
@ -856,7 +858,7 @@ func (e *Enumerator) Close() {
|
|||
// Next returns the currently enumerated item, if it exists and moves to the
|
||||
// next item in the key collation order. If there is no item to return, err ==
|
||||
// io.EOF is returned.
|
||||
func (e *Enumerator) Next() (k uint64, v *Container, err error) {
|
||||
func (e *Enumerator) Next() (k uint64, v *roaring.Container, err error) {
|
||||
if err = e.err; err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -904,7 +906,7 @@ func (e *Enumerator) next() error {
|
|||
// Prev returns the currently enumerated item, if it exists and moves to the
|
||||
// previous item in the key collation order. If there is no item to return, err
|
||||
// == io.EOF is returned.
|
||||
func (e *Enumerator) Prev() (k uint64, v *Container, err error) {
|
||||
func (e *Enumerator) Prev() (k uint64, v *roaring.Container, err error) {
|
||||
if err = e.err; err != nil {
|
||||
return
|
||||
}
|
||||
165
enterprise/b/containers_btree.go
Normal file
165
enterprise/b/containers_btree.go
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
package b
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/pilosa/pilosa/roaring"
|
||||
)
|
||||
|
||||
func cmp(a, b uint64) int {
|
||||
return int(a - b)
|
||||
}
|
||||
|
||||
func NewBTreeContainers() *BTreeContainers {
|
||||
return &BTreeContainers{
|
||||
tree: TreeNew(cmp),
|
||||
}
|
||||
}
|
||||
|
||||
type BTreeContainers struct {
|
||||
tree *Tree
|
||||
|
||||
lastKey uint64
|
||||
lastContainer *roaring.Container
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Get(key uint64) *roaring.Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == btc.lastKey && btc.lastContainer != nil {
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
var c *roaring.Container
|
||||
el, ok := btc.tree.Get(key)
|
||||
if ok {
|
||||
c = el
|
||||
btc.lastKey = key
|
||||
btc.lastContainer = c
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Put(key uint64, c *roaring.Container) {
|
||||
// If a mapped container is added to the tree, reset the
|
||||
// lastContainer cache so that the cache is not pointing
|
||||
// at a read-only mmap.
|
||||
if c.mapped {
|
||||
btc.lastContainer = nil
|
||||
}
|
||||
btc.tree.Set(key, c)
|
||||
}
|
||||
|
||||
func (u updater) update(oldV *roaring.Container, exists bool) (*roaring.Container, bool) {
|
||||
// update the existing container
|
||||
if exists {
|
||||
oldV.containerType = u.containerType
|
||||
oldV.n = u.n
|
||||
oldV.mapped = u.mapped
|
||||
return oldV, false
|
||||
}
|
||||
return &roaring.Container{
|
||||
containerType: u.containerType,
|
||||
n: u.n,
|
||||
mapped: u.mapped,
|
||||
}, true
|
||||
}
|
||||
|
||||
// this struct is added to prevent the closure locals from being escaped out to the heap
|
||||
type updater struct {
|
||||
key uint64
|
||||
containerType byte
|
||||
n int
|
||||
mapped bool
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) PutContainerValues(key uint64, containerType byte, n int, mapped bool) {
|
||||
a := updater{key, containerType, n, mapped}
|
||||
btc.tree.Put(key, a.update)
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Remove(key uint64) {
|
||||
btc.tree.Delete(key)
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) GetOrCreate(key uint64) *roaring.Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == btc.lastKey && btc.lastContainer != nil {
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
btc.lastKey = key
|
||||
v, ok := btc.tree.Get(key)
|
||||
if !ok {
|
||||
cont := newContainer()
|
||||
btc.tree.Set(key, cont)
|
||||
btc.lastContainer = cont
|
||||
return cont
|
||||
}
|
||||
|
||||
btc.lastContainer = v
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Clone() Containers {
|
||||
nbtc := NewBTreeContainers()
|
||||
|
||||
itr, err := btc.tree.SeekFirst()
|
||||
if err == io.EOF {
|
||||
return nbtc
|
||||
}
|
||||
for {
|
||||
k, v, err := itr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
nbtc.tree.Set(k, v.clone())
|
||||
}
|
||||
return nbtc
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Last() (key uint64, c *roaring.Container) {
|
||||
if btc.tree.Len() == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
k, v := btc.tree.Last()
|
||||
return k, v
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Size() int {
|
||||
return btc.tree.Len()
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Iterator(key uint64) (citer Contiterator, found bool) {
|
||||
e, ok := btc.tree.Seek(key)
|
||||
if ok {
|
||||
found = true
|
||||
}
|
||||
|
||||
return &BTCIterator{
|
||||
e: e,
|
||||
}, found
|
||||
}
|
||||
|
||||
type BTCIterator struct {
|
||||
e *Enumerator
|
||||
key uint64
|
||||
val *roaring.Container
|
||||
}
|
||||
|
||||
func (i *BTCIterator) Next() bool {
|
||||
|
||||
k, v, err := i.e.Next()
|
||||
if err == io.EOF {
|
||||
return false
|
||||
}
|
||||
i.key = k
|
||||
i.val = v
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *BTCIterator) Value() (uint64, *roaring.Container) {
|
||||
if i.val == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return i.key, i.val
|
||||
}
|
||||
|
|
@ -189,7 +189,7 @@ func (f *Fragment) Open() error {
|
|||
func (f *Fragment) openStorage() error {
|
||||
// Create a roaring bitmap to serve as storage for the slice.
|
||||
if f.storage == nil {
|
||||
f.storage = roaring.NewBTreeBitmap()
|
||||
f.storage = roaring.NewBitmap()
|
||||
}
|
||||
// Open the data file to be mmap'd and used as an ops log.
|
||||
file, err := os.OpenFile(f.path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
|
|
|
|||
143
roaring/containers.go
Normal file
143
roaring/containers.go
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
package roaring
|
||||
|
||||
type SliceContainers struct {
|
||||
keys []uint64
|
||||
containers []*Container
|
||||
lastKey uint64
|
||||
lastContainer *Container
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Get(key uint64) *Container {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
return nil
|
||||
}
|
||||
return sc.containers[i]
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Put(key uint64, c *Container) {
|
||||
i := search64(sc.keys, key)
|
||||
|
||||
// If index is negative then there's not an exact match
|
||||
// and a container needs to be added.
|
||||
if i < 0 {
|
||||
sc.insertAt(key, c, -i-1)
|
||||
} else {
|
||||
sc.containers[i] = c
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) PutContainerValues(key uint64, containerType byte, n int, mapped bool) {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
c := newContainer()
|
||||
c.containerType = containerType
|
||||
c.n = n
|
||||
c.mapped = mapped
|
||||
sc.insertAt(key, c, -i-1)
|
||||
} else {
|
||||
c := sc.containers[i]
|
||||
c.containerType = containerType
|
||||
c.n = n
|
||||
c.mapped = mapped
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Remove(key uint64) {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
return
|
||||
}
|
||||
sc.keys = append(sc.keys[:i], sc.keys[i+1:]...)
|
||||
sc.containers = append(sc.containers[:i], sc.containers[i+1:]...)
|
||||
|
||||
}
|
||||
func (sc *SliceContainers) insertAt(key uint64, c *Container, i int) {
|
||||
sc.keys = append(sc.keys, 0)
|
||||
copy(sc.keys[i+1:], sc.keys[i:])
|
||||
sc.keys[i] = key
|
||||
|
||||
sc.containers = append(sc.containers, nil)
|
||||
copy(sc.containers[i+1:], sc.containers[i:])
|
||||
sc.containers[i] = c
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) GetOrCreate(key uint64) *Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == sc.lastKey && sc.lastContainer != nil {
|
||||
return sc.lastContainer
|
||||
}
|
||||
|
||||
sc.lastKey = key
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
c := newContainer()
|
||||
sc.insertAt(key, c, -i-1)
|
||||
sc.lastContainer = c
|
||||
return c
|
||||
}
|
||||
|
||||
sc.lastContainer = sc.containers[i]
|
||||
return sc.lastContainer
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Clone() Containerser {
|
||||
other := NewContainers()
|
||||
other.keys = make([]uint64, len(sc.keys))
|
||||
other.containers = make([]*Container, len(sc.containers))
|
||||
copy(other.keys, sc.keys)
|
||||
for i, c := range sc.containers {
|
||||
other.containers[i] = c.clone()
|
||||
}
|
||||
return other
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Last() (key uint64, c *Container) {
|
||||
if len(sc.keys) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return sc.keys[len(sc.keys)-1], sc.containers[len(sc.keys)-1]
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Size() int {
|
||||
return len(sc.keys)
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) seek(key uint64) (int, bool) {
|
||||
i := search64(sc.keys, key)
|
||||
found := true
|
||||
if i < 0 {
|
||||
found = false
|
||||
i = -i - 1
|
||||
}
|
||||
return i, found
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Iterator(key uint64) (citer Contiterator, found bool) {
|
||||
i, found := sc.seek(key)
|
||||
return &SliceIterator{e: sc, i: i}, found
|
||||
}
|
||||
|
||||
type SliceIterator struct {
|
||||
e *SliceContainers
|
||||
i int
|
||||
key uint64
|
||||
value *Container
|
||||
}
|
||||
|
||||
func (si *SliceIterator) Next() bool {
|
||||
if si.e == nil || si.i > len(si.e.keys)-1 {
|
||||
return false
|
||||
}
|
||||
si.key = si.e.keys[si.i]
|
||||
si.value = si.e.containers[si.i]
|
||||
si.i++
|
||||
return true
|
||||
}
|
||||
|
||||
func (si *SliceIterator) Value() (uint64, *Container) {
|
||||
return si.key, si.value
|
||||
}
|
||||
|
|
@ -1,163 +1,9 @@
|
|||
// +build enterprise
|
||||
|
||||
package roaring
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
import "github.com/pilosa/pilosa/enterprise/b"
|
||||
|
||||
func cmp(a, b uint64) int {
|
||||
return int(a - b)
|
||||
}
|
||||
|
||||
func NewBTreeContainers() *BTreeContainers {
|
||||
return &BTreeContainers{
|
||||
tree: TreeNew(cmp),
|
||||
}
|
||||
}
|
||||
|
||||
type BTreeContainers struct {
|
||||
tree *Tree
|
||||
|
||||
lastKey uint64
|
||||
lastContainer *Container
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Get(key uint64) *Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == btc.lastKey && btc.lastContainer != nil {
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
var c *Container
|
||||
el, ok := btc.tree.Get(key)
|
||||
if ok {
|
||||
c = el
|
||||
btc.lastKey = key
|
||||
btc.lastContainer = c
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Put(key uint64, c *Container) {
|
||||
// If a mapped container is added to the tree, reset the
|
||||
// lastContainer cache so that the cache is not pointing
|
||||
// at a read-only mmap.
|
||||
if c.mapped {
|
||||
btc.lastContainer = nil
|
||||
}
|
||||
btc.tree.Set(key, c)
|
||||
}
|
||||
|
||||
func (u updater) update(oldV *Container, exists bool) (*Container, bool) {
|
||||
// update the existing container
|
||||
if exists {
|
||||
oldV.containerType = u.containerType
|
||||
oldV.n = u.n
|
||||
oldV.mapped = u.mapped
|
||||
return oldV, false
|
||||
}
|
||||
return &Container{
|
||||
containerType: u.containerType,
|
||||
n: u.n,
|
||||
mapped: u.mapped,
|
||||
}, true
|
||||
}
|
||||
|
||||
// this struct is added to prevent the closure locals from being escaped out to the heap
|
||||
type updater struct {
|
||||
key uint64
|
||||
containerType byte
|
||||
n int
|
||||
mapped bool
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) PutContainerValues(key uint64, containerType byte, n int, mapped bool) {
|
||||
a := updater{key, containerType, n, mapped}
|
||||
btc.tree.Put(key, a.update)
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Remove(key uint64) {
|
||||
btc.tree.Delete(key)
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) GetOrCreate(key uint64) *Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == btc.lastKey && btc.lastContainer != nil {
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
btc.lastKey = key
|
||||
v, ok := btc.tree.Get(key)
|
||||
if !ok {
|
||||
cont := newContainer()
|
||||
btc.tree.Set(key, cont)
|
||||
btc.lastContainer = cont
|
||||
return cont
|
||||
}
|
||||
|
||||
btc.lastContainer = v
|
||||
return btc.lastContainer
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Clone() Containers {
|
||||
nbtc := NewBTreeContainers()
|
||||
|
||||
itr, err := btc.tree.SeekFirst()
|
||||
if err == io.EOF {
|
||||
return nbtc
|
||||
}
|
||||
for {
|
||||
k, v, err := itr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
nbtc.tree.Set(k, v.clone())
|
||||
}
|
||||
return nbtc
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Last() (key uint64, c *Container) {
|
||||
if btc.tree.Len() == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
k, v := btc.tree.Last()
|
||||
return k, v
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Size() int {
|
||||
return btc.tree.Len()
|
||||
}
|
||||
|
||||
func (btc *BTreeContainers) Iterator(key uint64) (citer Contiterator, found bool) {
|
||||
e, ok := btc.tree.Seek(key)
|
||||
if ok {
|
||||
found = true
|
||||
}
|
||||
|
||||
return &BTCIterator{
|
||||
e: e,
|
||||
}, found
|
||||
}
|
||||
|
||||
type BTCIterator struct {
|
||||
e *Enumerator
|
||||
key uint64
|
||||
val *Container
|
||||
}
|
||||
|
||||
func (i *BTCIterator) Next() bool {
|
||||
|
||||
k, v, err := i.e.Next()
|
||||
if err == io.EOF {
|
||||
return false
|
||||
}
|
||||
i.key = k
|
||||
i.val = v
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *BTCIterator) Value() (uint64, *Container) {
|
||||
if i.val == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return i.key, i.val
|
||||
func NewContainers() *b.BTreeContainers {
|
||||
return &b.BTreeContainers{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,147 +1,7 @@
|
|||
// +build !enterprise
|
||||
|
||||
package roaring
|
||||
|
||||
func NewSliceContainers() *SliceContainers {
|
||||
func NewContainers() *SliceContainers {
|
||||
return &SliceContainers{}
|
||||
}
|
||||
|
||||
type SliceContainers struct {
|
||||
keys []uint64
|
||||
containers []*Container
|
||||
lastKey uint64
|
||||
lastContainer *Container
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Get(key uint64) *Container {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
return nil
|
||||
}
|
||||
return sc.containers[i]
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Put(key uint64, c *Container) {
|
||||
i := search64(sc.keys, key)
|
||||
|
||||
// If index is negative then there's not an exact match
|
||||
// and a container needs to be added.
|
||||
if i < 0 {
|
||||
sc.insertAt(key, c, -i-1)
|
||||
} else {
|
||||
sc.containers[i] = c
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) PutContainerValues(key uint64, containerType byte, n int, mapped bool) {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
c := newContainer()
|
||||
c.containerType = containerType
|
||||
c.n = n
|
||||
c.mapped = mapped
|
||||
sc.insertAt(key, c, -i-1)
|
||||
} else {
|
||||
c := sc.containers[i]
|
||||
c.containerType = containerType
|
||||
c.n = n
|
||||
c.mapped = mapped
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Remove(key uint64) {
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
return
|
||||
}
|
||||
sc.keys = append(sc.keys[:i], sc.keys[i+1:]...)
|
||||
sc.containers = append(sc.containers[:i], sc.containers[i+1:]...)
|
||||
|
||||
}
|
||||
func (sc *SliceContainers) insertAt(key uint64, c *Container, i int) {
|
||||
sc.keys = append(sc.keys, 0)
|
||||
copy(sc.keys[i+1:], sc.keys[i:])
|
||||
sc.keys[i] = key
|
||||
|
||||
sc.containers = append(sc.containers, nil)
|
||||
copy(sc.containers[i+1:], sc.containers[i:])
|
||||
sc.containers[i] = c
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) GetOrCreate(key uint64) *Container {
|
||||
// Check the last* cache for same container.
|
||||
if key == sc.lastKey && sc.lastContainer != nil {
|
||||
return sc.lastContainer
|
||||
}
|
||||
|
||||
sc.lastKey = key
|
||||
i := search64(sc.keys, key)
|
||||
if i < 0 {
|
||||
c := newContainer()
|
||||
sc.insertAt(key, c, -i-1)
|
||||
sc.lastContainer = c
|
||||
return c
|
||||
}
|
||||
|
||||
sc.lastContainer = sc.containers[i]
|
||||
return sc.lastContainer
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Clone() Containers {
|
||||
other := NewSliceContainers()
|
||||
other.keys = make([]uint64, len(sc.keys))
|
||||
other.containers = make([]*Container, len(sc.containers))
|
||||
copy(other.keys, sc.keys)
|
||||
for i, c := range sc.containers {
|
||||
other.containers[i] = c.clone()
|
||||
}
|
||||
return other
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Last() (key uint64, c *Container) {
|
||||
if len(sc.keys) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return sc.keys[len(sc.keys)-1], sc.containers[len(sc.keys)-1]
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Size() int {
|
||||
return len(sc.keys)
|
||||
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) seek(key uint64) (int, bool) {
|
||||
i := search64(sc.keys, key)
|
||||
found := true
|
||||
if i < 0 {
|
||||
found = false
|
||||
i = -i - 1
|
||||
}
|
||||
return i, found
|
||||
}
|
||||
|
||||
func (sc *SliceContainers) Iterator(key uint64) (citer Contiterator, found bool) {
|
||||
i, found := sc.seek(key)
|
||||
return &SliceIterator{e: sc, i: i}, found
|
||||
}
|
||||
|
||||
type SliceIterator struct {
|
||||
e *SliceContainers
|
||||
i int
|
||||
key uint64
|
||||
value *Container
|
||||
}
|
||||
|
||||
func (si *SliceIterator) Next() bool {
|
||||
if si.e == nil || si.i > len(si.e.keys)-1 {
|
||||
return false
|
||||
}
|
||||
si.key = si.e.keys[si.i]
|
||||
si.value = si.e.containers[si.i]
|
||||
si.i++
|
||||
return true
|
||||
}
|
||||
|
||||
func (si *SliceIterator) Value() (uint64, *Container) {
|
||||
return si.key, si.value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestContainersSliceIterator(t *testing.T) {
|
||||
btc := NewBTreeContainers()
|
||||
testContainersIterator(btc, t)
|
||||
}
|
||||
//func TestContainersSliceIterator(t *testing.T) {
|
||||
// btc := NewBTreeContainers()
|
||||
// testContainersIterator(btc, t)
|
||||
//}
|
||||
func TestContainersBTreeIterator(t *testing.T) {
|
||||
slc := NewSliceContainers()
|
||||
slc := NewContainers()
|
||||
testContainersIterator(slc, t)
|
||||
|
||||
}
|
||||
func testContainersIterator(cs Containers, t *testing.T) {
|
||||
func testContainersIterator(cs Containerser, t *testing.T) {
|
||||
itr, found := cs.Iterator(0)
|
||||
if found {
|
||||
t.Fatalf("shouldn't have found 0 in empty btc")
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ const (
|
|||
maxContainerVal = 0xffff
|
||||
)
|
||||
|
||||
type Containers interface {
|
||||
type Containerser interface {
|
||||
// Get returns nil if the key does not exist.
|
||||
Get(key uint64) *Container
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ type Containers interface {
|
|||
GetOrCreate(key uint64) *Container
|
||||
|
||||
// Clone does a deep copy of Containers, including cloning all containers contained.
|
||||
Clone() Containers
|
||||
Clone() Containerser
|
||||
|
||||
// Last returns the highest key and associated container.
|
||||
Last() (key uint64, c *Container)
|
||||
|
|
@ -103,7 +103,7 @@ type Contiterator interface {
|
|||
|
||||
// Bitmap represents a roaring bitmap.
|
||||
type Bitmap struct {
|
||||
conts Containers
|
||||
conts Containerser
|
||||
|
||||
// Number of operations written to the writer.
|
||||
opN int
|
||||
|
|
@ -112,22 +112,22 @@ type Bitmap struct {
|
|||
OpWriter io.Writer
|
||||
}
|
||||
|
||||
// NewSliceBitmap returns a Bitmap with an initial set of values.
|
||||
func NewSliceBitmap(a ...uint64) *Bitmap {
|
||||
// NewBitmap returns a Bitmap with an initial set of values.
|
||||
func NewBitmap(a ...uint64) *Bitmap {
|
||||
b := &Bitmap{
|
||||
conts: NewSliceContainers(),
|
||||
conts: NewContainers(),
|
||||
}
|
||||
b.Add(a...)
|
||||
return b
|
||||
}
|
||||
|
||||
func NewBTreeBitmap(a ...uint64) *Bitmap {
|
||||
b := &Bitmap{
|
||||
conts: NewBTreeContainers(),
|
||||
}
|
||||
b.Add(a...)
|
||||
return b
|
||||
}
|
||||
//func NewBTreeBitmap(a ...uint64) *Bitmap {
|
||||
// b := &Bitmap{
|
||||
// conts: NewBTreeContainers(),
|
||||
// }
|
||||
// b.Add(a...)
|
||||
// return b
|
||||
//}
|
||||
|
||||
// Clone returns a heap allocated copy of the bitmap.
|
||||
// Note: The OpWriter IS NOT copied to the new bitmap.
|
||||
|
|
@ -329,7 +329,7 @@ func (b *Bitmap) OffsetRange(offset, start, end uint64) *Bitmap {
|
|||
off := highbits(offset)
|
||||
hi0, hi1 := highbits(start), highbits(end)
|
||||
citer, _ := b.conts.Iterator(hi0)
|
||||
other := NewSliceBitmap()
|
||||
other := NewBitmap()
|
||||
for citer.Next() {
|
||||
k, c := citer.Value()
|
||||
if k >= hi1 {
|
||||
|
|
@ -374,7 +374,7 @@ func (b *Bitmap) IntersectionCount(other *Bitmap) uint64 {
|
|||
|
||||
// Intersect returns the intersection of b and other.
|
||||
func (b *Bitmap) Intersect(other *Bitmap) *Bitmap {
|
||||
output := NewSliceBitmap()
|
||||
output := NewBitmap()
|
||||
iiter, _ := b.conts.Iterator(0)
|
||||
jiter, _ := other.conts.Iterator(0)
|
||||
i, j := iiter.Next(), jiter.Next()
|
||||
|
|
@ -399,7 +399,7 @@ func (b *Bitmap) Intersect(other *Bitmap) *Bitmap {
|
|||
|
||||
// Union returns the bitwise union of b and other.
|
||||
func (b *Bitmap) Union(other *Bitmap) *Bitmap {
|
||||
output := NewSliceBitmap()
|
||||
output := NewBitmap()
|
||||
|
||||
iiter, _ := b.conts.Iterator(0)
|
||||
jiter, _ := other.conts.Iterator(0)
|
||||
|
|
@ -427,7 +427,7 @@ func (b *Bitmap) Union(other *Bitmap) *Bitmap {
|
|||
|
||||
// Difference returns the difference of b and other.
|
||||
func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
|
||||
output := NewSliceBitmap()
|
||||
output := NewBitmap()
|
||||
|
||||
iiter, _ := b.conts.Iterator(0)
|
||||
jiter, _ := other.conts.Iterator(0)
|
||||
|
|
@ -454,7 +454,7 @@ func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
|
|||
|
||||
// Xor returns the bitwise exclusive or of b and other.
|
||||
func (b *Bitmap) Xor(other *Bitmap) *Bitmap {
|
||||
output := NewSliceBitmap()
|
||||
output := NewBitmap()
|
||||
|
||||
iiter, _ := b.conts.Iterator(0)
|
||||
jiter, _ := other.conts.Iterator(0)
|
||||
|
|
@ -768,7 +768,7 @@ func (b *Bitmap) Check() error {
|
|||
|
||||
// Flip performs a logical negate of the bits in the range [start,end].
|
||||
func (b *Bitmap) Flip(start, end uint64) *Bitmap {
|
||||
result := NewSliceBitmap()
|
||||
result := NewBitmap()
|
||||
itr := b.Iterator()
|
||||
v, eof := itr.Next()
|
||||
//copy over previous bits.
|
||||
|
|
|
|||
|
|
@ -1513,7 +1513,7 @@ func MakeBitmap(start []uint64) []uint64 {
|
|||
return b
|
||||
}
|
||||
func MakeLastBitSet() []uint64 {
|
||||
obj := NewSliceBitmap(65535)
|
||||
obj := NewBitmap(65535)
|
||||
c := obj.container(0)
|
||||
c.arrayToBitmap()
|
||||
return c.bitmap
|
||||
|
|
@ -1781,9 +1781,9 @@ func TestDifferenceRunRun(t *testing.T) {
|
|||
|
||||
func TestWriteReadArray(t *testing.T) {
|
||||
ca := &Container{array: []uint16{1, 10, 100, 1000}, n: 4, containerType: ContainerArray}
|
||||
ba := NewSliceBitmap()
|
||||
ba := NewBitmap()
|
||||
ba.conts.Put(0, ca)
|
||||
ba2 := NewSliceBitmap()
|
||||
ba2 := NewBitmap()
|
||||
var buf bytes.Buffer
|
||||
_, err := ba.WriteTo(&buf)
|
||||
if err != nil {
|
||||
|
|
@ -1804,9 +1804,9 @@ func TestWriteReadBitmap(t *testing.T) {
|
|||
for i := 0; i < 129; i++ {
|
||||
cb.bitmap[i] = 0x5555555555555555
|
||||
}
|
||||
bb := NewSliceBitmap()
|
||||
bb := NewBitmap()
|
||||
bb.conts.Put(0, cb)
|
||||
bb2 := NewSliceBitmap()
|
||||
bb2 := NewBitmap()
|
||||
var buf bytes.Buffer
|
||||
_, err := bb.WriteTo(&buf)
|
||||
if err != nil {
|
||||
|
|
@ -1827,9 +1827,9 @@ func TestWriteReadFullBitmap(t *testing.T) {
|
|||
for i := 0; i < bitmapN; i++ {
|
||||
cb.bitmap[i] = 0xffffffffffffffff
|
||||
}
|
||||
bb := NewSliceBitmap()
|
||||
bb := NewBitmap()
|
||||
bb.conts.Put(0, cb)
|
||||
bb2 := NewSliceBitmap()
|
||||
bb2 := NewBitmap()
|
||||
var buf bytes.Buffer
|
||||
_, err := bb.WriteTo(&buf)
|
||||
if err != nil {
|
||||
|
|
@ -1853,9 +1853,9 @@ func TestWriteReadFullBitmap(t *testing.T) {
|
|||
|
||||
func TestWriteReadRun(t *testing.T) {
|
||||
cr := &Container{runs: []interval16{{start: 3, last: 13}, {start: 100, last: 109}}, n: 21, containerType: ContainerRun}
|
||||
br := NewSliceBitmap()
|
||||
br := NewBitmap()
|
||||
br.conts.Put(0, cr)
|
||||
br2 := NewSliceBitmap()
|
||||
br2 := NewBitmap()
|
||||
var buf bytes.Buffer
|
||||
_, err := br.WriteTo(&buf)
|
||||
if err != nil {
|
||||
|
|
@ -2124,7 +2124,7 @@ func TestXorBitmapRun(t *testing.T) {
|
|||
|
||||
func TestIteratorArray(t *testing.T) {
|
||||
// use values that span two containers
|
||||
b := NewSliceBitmap(0, 1, 10, 100, 1000, 10000, 90000, 100000)
|
||||
b := NewBitmap(0, 1, 10, 100, 1000, 10000, 90000, 100000)
|
||||
if !b.conts.Get(0).isArray() {
|
||||
t.Fatalf("wrong container type")
|
||||
}
|
||||
|
|
@ -2171,7 +2171,7 @@ func TestIteratorBitmap(t *testing.T) {
|
|||
// use values that span two containers
|
||||
// this dataset will update to bitmap after enough Adds,
|
||||
// but won't update to RLE until Optimize() is called
|
||||
b := NewSliceBitmap()
|
||||
b := NewBitmap()
|
||||
for i := uint64(61000); i < 71000; i++ {
|
||||
b.Add(i)
|
||||
}
|
||||
|
|
@ -2222,7 +2222,7 @@ func TestIteratorBitmap(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIteratorRuns(t *testing.T) {
|
||||
b := NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 100003, 100004, 100005)
|
||||
b := NewBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 100003, 100004, 100005)
|
||||
b.Optimize()
|
||||
if !b.conts.Get(0).isRun() {
|
||||
t.Fatalf("wrong container type")
|
||||
|
|
@ -2289,7 +2289,7 @@ func TestIteratorVarious(t *testing.T) {
|
|||
exp uint64
|
||||
}{
|
||||
{
|
||||
bm: NewSliceBitmap(3, 4, 5),
|
||||
bm: NewBitmap(3, 4, 5),
|
||||
exp: 3,
|
||||
},
|
||||
{
|
||||
|
|
@ -2297,7 +2297,7 @@ func TestIteratorVarious(t *testing.T) {
|
|||
exp: 61221,
|
||||
},
|
||||
{
|
||||
bm: NewSliceBitmap(2, 66000, 70000, 70001, 70002, 70003, 70004),
|
||||
bm: NewBitmap(2, 66000, 70000, 70001, 70002, 70003, 70004),
|
||||
exp: 7,
|
||||
},
|
||||
}
|
||||
|
|
@ -2438,7 +2438,7 @@ func TestRunBinSearch(t *testing.T) {
|
|||
}
|
||||
}
|
||||
func TestBitmap_RemoveEmptyContainers(t *testing.T) {
|
||||
bm1 := NewSliceBitmap(1<<16, 2<<16, 3<<16)
|
||||
bm1 := NewBitmap(1<<16, 2<<16, 3<<16)
|
||||
bm1.Remove(2 << 16)
|
||||
if bm1.countEmptyContainers() != 1 {
|
||||
t.Fatalf("Should be 1 empty container ")
|
||||
|
|
@ -2451,13 +2451,13 @@ func TestBitmap_RemoveEmptyContainers(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_BitmapWriteToWithEmpty(t *testing.T) {
|
||||
bm1 := NewSliceBitmap(1<<16, 2<<16, 3<<16)
|
||||
bm1 := NewBitmap(1<<16, 2<<16, 3<<16)
|
||||
bm1.Remove(2 << 16)
|
||||
var buf bytes.Buffer
|
||||
if _, err := bm1.WriteTo(&buf); err != nil {
|
||||
t.Fatalf("Failure to write to bitmap buffer. ")
|
||||
}
|
||||
bm0 := NewSliceBitmap()
|
||||
bm0 := NewBitmap()
|
||||
bm0.UnmarshalBinary(buf.Bytes())
|
||||
if bm0.countEmptyContainers() != 0 {
|
||||
t.Fatalf("Should be no empty containers ")
|
||||
|
|
@ -2686,7 +2686,7 @@ func bitmapVariousContainers() *Bitmap {
|
|||
bits = append(bits, bitCont(7, true, true, true)...)
|
||||
bits = append(bits, arrCont(8, true, true, true)...)
|
||||
bits = append(bits, rleCont(9, true, true, true)...)
|
||||
bm := NewSliceBitmap(bits...)
|
||||
bm := NewBitmap(bits...)
|
||||
bm.Optimize()
|
||||
return bm
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import (
|
|||
)
|
||||
|
||||
func TestBitmapClone(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap()
|
||||
b := roaring.NewBitmap()
|
||||
for i := uint64(61000); i < 71000; i++ {
|
||||
b.Add(i)
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ func TestBitmapClone(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestContainerCount(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap(65535)
|
||||
b := roaring.NewBitmap(65535)
|
||||
|
||||
if b.Count() != b.CountRange(0, 65546) {
|
||||
t.Fatalf("Count != CountRange\n")
|
||||
|
|
@ -144,7 +144,7 @@ func TestCountRange(t *testing.T) {
|
|||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%s: %d to %d in '%v'", test.name, test.start, test.end, test.bitmap), func(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap(test.bitmap...)
|
||||
b := roaring.NewBitmap(test.bitmap...)
|
||||
actual := b.CountRange(test.start, test.end)
|
||||
if actual != test.exp {
|
||||
t.Errorf("got: %d, exp: %d", actual, test.exp)
|
||||
|
|
@ -154,7 +154,7 @@ func TestCountRange(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckBitmap(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap()
|
||||
b := roaring.NewBitmap()
|
||||
x := 0
|
||||
for i := uint64(61000); i < 71000; i++ {
|
||||
x++
|
||||
|
|
@ -171,7 +171,7 @@ func TestCheckBitmap(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckArray(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap(0, 1, 10, 100, 1000, 10000, 90000, 100000)
|
||||
b := roaring.NewBitmap(0, 1, 10, 100, 1000, 10000, 90000, 100000)
|
||||
err := b.Check()
|
||||
if err != nil {
|
||||
t.Fatalf("%v\n", err)
|
||||
|
|
@ -179,7 +179,7 @@ func TestCheckArray(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckRun(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 100003, 100004, 100005)
|
||||
b := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 100003, 100004, 100005)
|
||||
b.Optimize() // convert to runs
|
||||
err := b.Check()
|
||||
if err != nil {
|
||||
|
|
@ -187,7 +187,7 @@ func TestCheckRun(t *testing.T) {
|
|||
}
|
||||
}
|
||||
func TestCheckFullRun(t *testing.T) {
|
||||
b := roaring.NewSliceBitmap()
|
||||
b := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 2097152; i++ {
|
||||
if i%16384 == 0 {
|
||||
b.Optimize() // convert to runs
|
||||
|
|
@ -208,7 +208,7 @@ func TestCheckFullRun(t *testing.T) {
|
|||
// Ensure that we can transition between runs and arrays when materializing the bitmap.
|
||||
func TestContainerTransitions(t *testing.T) {
|
||||
// [run, run][array][run]
|
||||
b := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 132000, 132001, 132002, 132003, 132004, 132005)
|
||||
b := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 132000, 132001, 132002, 132003, 132004, 132005)
|
||||
b.Optimize() // convert to runs
|
||||
if !reflect.DeepEqual(b.Slice(), []uint64{0, 1, 2, 3, 4, 5, 1000, 1001, 1002, 1003, 1004, 1005, 100000, 100001, 100002, 132000, 132001, 132002, 132003, 132004, 132005}) {
|
||||
t.Fatalf("unexpected slice: %+v", b.Slice())
|
||||
|
|
@ -216,7 +216,7 @@ func TestContainerTransitions(t *testing.T) {
|
|||
|
||||
// Test the case where last and first bits of adjoining containers are set.
|
||||
// [run][array][run]
|
||||
b2 := roaring.NewSliceBitmap(65531, 65532, 65533, 65534, 65535, 65536, 131071, 131072, 131073, 131074, 131075, 131076)
|
||||
b2 := roaring.NewBitmap(65531, 65532, 65533, 65534, 65535, 65536, 131071, 131072, 131073, 131074, 131075, 131076)
|
||||
b2.Optimize() // convert to runs
|
||||
if !reflect.DeepEqual(b2.Slice(), []uint64{65531, 65532, 65533, 65534, 65535, 65536, 131071, 131072, 131073, 131074, 131075, 131076}) {
|
||||
t.Fatalf("unexpected slice: %+v", b2.Slice())
|
||||
|
|
@ -225,26 +225,26 @@ func TestContainerTransitions(t *testing.T) {
|
|||
|
||||
// Ensure an empty bitmap returns false if checking for existence.
|
||||
func TestBitmap_Contains_Empty(t *testing.T) {
|
||||
if roaring.NewSliceBitmap().Contains(1000) {
|
||||
if roaring.NewBitmap().Contains(1000) {
|
||||
t.Fatal("expected false")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure an empty bitmap does nothing when removing an element.
|
||||
func TestBitmap_Remove_Empty(t *testing.T) {
|
||||
roaring.NewSliceBitmap().Remove(1000)
|
||||
roaring.NewBitmap().Remove(1000)
|
||||
}
|
||||
|
||||
// Ensure a bitmap can return a slice of values.
|
||||
func TestBitmap_Slice(t *testing.T) {
|
||||
if a := roaring.NewSliceBitmap(1, 2, 3).Slice(); !reflect.DeepEqual(a, []uint64{1, 2, 3}) {
|
||||
if a := roaring.NewBitmap(1, 2, 3).Slice(); !reflect.DeepEqual(a, []uint64{1, 2, 3}) {
|
||||
t.Fatalf("unexpected slice: %+v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure an empty bitmap returns an empty slice of values.
|
||||
func TestBitmap_Slice_Empty(t *testing.T) {
|
||||
if a := roaring.NewSliceBitmap().Slice(); len(a) != 0 {
|
||||
if a := roaring.NewBitmap().Slice(); len(a) != 0 {
|
||||
t.Fatalf("unexpected slice: %+v", a)
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ func TestBitmap_Slice_Empty(t *testing.T) {
|
|||
// Ensure a bitmap can return a slice of values within a range.
|
||||
// TODO duplicate for all container types
|
||||
func TestBitmap_SliceRange(t *testing.T) {
|
||||
if a := roaring.NewSliceBitmap(0, 1000001, 1000002, 1000003).SliceRange(1, 1000003); !reflect.DeepEqual(a, []uint64{1000001, 1000002}) {
|
||||
if a := roaring.NewBitmap(0, 1000001, 1000002, 1000003).SliceRange(1, 1000003); !reflect.DeepEqual(a, []uint64{1000001, 1000002}) {
|
||||
t.Fatalf("unexpected slice: %+v", a)
|
||||
}
|
||||
}
|
||||
|
|
@ -260,7 +260,7 @@ func TestBitmap_SliceRange(t *testing.T) {
|
|||
// Ensure a bitmap can loop over a set of values.
|
||||
func TestBitmap_ForEach(t *testing.T) {
|
||||
var a []uint64
|
||||
roaring.NewSliceBitmap(1, 2, 3).ForEach(func(v uint64) {
|
||||
roaring.NewBitmap(1, 2, 3).ForEach(func(v uint64) {
|
||||
a = append(a, v)
|
||||
})
|
||||
if !reflect.DeepEqual(a, []uint64{1, 2, 3}) {
|
||||
|
|
@ -271,7 +271,7 @@ func TestBitmap_ForEach(t *testing.T) {
|
|||
// Ensure a bitmap can loop over a set of values in a range.
|
||||
func TestBitmap_ForEachRange(t *testing.T) {
|
||||
var a []uint64
|
||||
roaring.NewSliceBitmap(1, 2, 3, 4).ForEachRange(2, 4, func(v uint64) {
|
||||
roaring.NewBitmap(1, 2, 3, 4).ForEachRange(2, 4, func(v uint64) {
|
||||
a = append(a, v)
|
||||
})
|
||||
if !reflect.DeepEqual(a, []uint64{2, 3}) {
|
||||
|
|
@ -281,7 +281,7 @@ func TestBitmap_ForEachRange(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the highest value.
|
||||
func TestBitmap_Max(t *testing.T) {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for i := uint64(1000); i <= 100000; i++ {
|
||||
bm.Add(i)
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ func TestBitmap_BitmapCountRangeEdgeCase(t *testing.T) {
|
|||
e := uint64(2010 * 1048576)
|
||||
|
||||
start := s + (39314024 % 1048576)
|
||||
bm0 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 65536; i++ {
|
||||
if (i+1)%4096 == 0 {
|
||||
start += 16384
|
||||
|
|
@ -315,7 +315,7 @@ func TestBitmap_BitmapCountRangeEdgeCase(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_BitmapCountRange(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
for i := uint64(628); i < 2683301; i++ {
|
||||
bm0.Add(i)
|
||||
}
|
||||
|
|
@ -343,20 +343,20 @@ func TestBitmap_BitmapCountRange(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_ArrayCountRange(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177, 2683313)
|
||||
bm0 := roaring.NewBitmap(0, 2683177, 2683313)
|
||||
if n := bm0.CountRange(1, 2683313); n != 1 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmap_RunCountRange(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014)
|
||||
bm0 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006, 1000010, 1000011, 1000012, 1000013, 1000014)
|
||||
bm0.Optimize() // convert to runs
|
||||
if n := bm0.CountRange(15, 1000003); n != 5 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
|
||||
bm1.Optimize() // convert to runs
|
||||
if n := bm1.CountRange(5, 12); n != 7 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -364,8 +364,8 @@ func TestBitmap_RunCountRange(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Intersectionz(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(628); i < 2683301; i++ {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -378,8 +378,8 @@ func TestBitmap_Intersectionz(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Union1(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(628); i < 2683301; i++ {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -402,8 +402,8 @@ func TestBitmap_Union1(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Intersection_Empty(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
bm1 := roaring.NewBitmap()
|
||||
|
||||
result := bm0.Intersect(bm1)
|
||||
if n := result.Count(); n != 0 {
|
||||
|
|
@ -413,8 +413,8 @@ func TestBitmap_Intersection_Empty(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_IntersectArrayArray(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1, 2683, 5005)
|
||||
bm1 := roaring.NewSliceBitmap(0, 2683, 2684, 5000)
|
||||
bm0 := roaring.NewBitmap(0, 1, 2683, 5005)
|
||||
bm1 := roaring.NewBitmap(0, 2683, 2684, 5000)
|
||||
|
||||
result := bm0.Intersect(bm1)
|
||||
if n := result.Count(); n != 2 {
|
||||
|
|
@ -423,12 +423,12 @@ func TestBitmap_IntersectArrayArray(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_IntersectBitmapBitmap(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 65536; i += 2 {
|
||||
bm0.Add(i)
|
||||
}
|
||||
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 65536; i += 3 {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -441,9 +441,9 @@ func TestBitmap_IntersectBitmapBitmap(t *testing.T) {
|
|||
|
||||
func TestBitmap_IntersectRunRun(t *testing.T) {
|
||||
// Intersect two runs that result in an array.
|
||||
bm0 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15)
|
||||
bm0 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15)
|
||||
bm0.Optimize() // convert to runs
|
||||
bm1 := roaring.NewSliceBitmap(5, 6, 7, 8, 9, 10, 11)
|
||||
bm1 := roaring.NewBitmap(5, 6, 7, 8, 9, 10, 11)
|
||||
bm1.Optimize() // convert to runs
|
||||
result := bm0.Intersect(bm1)
|
||||
if n := result.Count(); n != 3 {
|
||||
|
|
@ -451,7 +451,7 @@ func TestBitmap_IntersectRunRun(t *testing.T) {
|
|||
}
|
||||
|
||||
// Intersect two runs that result in a bitmap.
|
||||
bm2 := roaring.NewSliceBitmap()
|
||||
bm2 := roaring.NewBitmap()
|
||||
runLen := uint64(25)
|
||||
spaceLen := uint64(8)
|
||||
offset := (runLen / 2) + spaceLen
|
||||
|
|
@ -461,7 +461,7 @@ func TestBitmap_IntersectRunRun(t *testing.T) {
|
|||
}
|
||||
}
|
||||
bm2.Optimize() // convert to runs
|
||||
bm3 := roaring.NewSliceBitmap()
|
||||
bm3 := roaring.NewBitmap()
|
||||
runLen = uint64(32)
|
||||
spaceLen = uint64(1)
|
||||
for i := uint64(0); i < (65536 - runLen); i += (runLen + spaceLen) {
|
||||
|
|
@ -477,8 +477,8 @@ func TestBitmap_IntersectRunRun(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Difference(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(628); i < 2683301; i++ {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -489,8 +489,8 @@ func TestBitmap_Difference(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Difference2(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1, 2, 131072, 262144, pilosa.SliceWidth+5, pilosa.SliceWidth+7)
|
||||
bm1 := roaring.NewSliceBitmap(2, 3, 100000, 262144, 2*pilosa.SliceWidth+1)
|
||||
bm0 := roaring.NewBitmap(0, 1, 2, 131072, 262144, pilosa.SliceWidth+5, pilosa.SliceWidth+7)
|
||||
bm1 := roaring.NewBitmap(2, 3, 100000, 262144, 2*pilosa.SliceWidth+1)
|
||||
result := bm0.Difference(bm1)
|
||||
if !reflect.DeepEqual(result.Slice(), []uint64{0, 1, 131072, pilosa.SliceWidth + 5, pilosa.SliceWidth + 7}) {
|
||||
t.Fatalf("unexpected : %v", result.Slice())
|
||||
|
|
@ -498,8 +498,8 @@ func TestBitmap_Difference2(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Difference_Empty(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 2683177)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(0, 2683177)
|
||||
bm1 := roaring.NewBitmap()
|
||||
result := bm0.Difference(bm1)
|
||||
if n := result.Count(); n != 2 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -507,8 +507,8 @@ func TestBitmap_Difference_Empty(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_DifferenceArrayArray(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 4, 8, 12, 16, 20)
|
||||
bm1 := roaring.NewSliceBitmap(1, 3, 6, 9, 12, 15, 18)
|
||||
bm0 := roaring.NewBitmap(0, 4, 8, 12, 16, 20)
|
||||
bm1 := roaring.NewBitmap(1, 3, 6, 9, 12, 15, 18)
|
||||
result := bm0.Difference(bm1)
|
||||
if n := result.Count(); n != 5 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -516,9 +516,9 @@ func TestBitmap_DifferenceArrayArray(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_DifferenceArrayRun(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 4, 8, 12, 16, 20, 36, 40, 44)
|
||||
bm0 := roaring.NewBitmap(0, 4, 8, 12, 16, 20, 36, 40, 44)
|
||||
|
||||
bm1 := roaring.NewSliceBitmap(1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 31, 32, 33, 34, 35, 36)
|
||||
bm1 := roaring.NewBitmap(1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 31, 32, 33, 34, 35, 36)
|
||||
bm1.Optimize() // convert to runs
|
||||
result := bm0.Difference(bm1)
|
||||
if n := result.Count(); n != 6 {
|
||||
|
|
@ -527,8 +527,8 @@ func TestBitmap_DifferenceArrayRun(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Union(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewSliceBitmap(0, 50000, 1000001, 1000002)
|
||||
bm0 := roaring.NewBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewBitmap(0, 50000, 1000001, 1000002)
|
||||
result := bm0.Union(bm1)
|
||||
if n := result.Count(); n != 5 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -537,7 +537,7 @@ func TestBitmap_Union(t *testing.T) {
|
|||
|
||||
func TestBitmap_Xor(t *testing.T) {
|
||||
bm0 := testBM()
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3)
|
||||
result := bm1.Xor(bm0)
|
||||
if n := result.Count(); n != 75011 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -555,8 +555,8 @@ func TestBitmap_Xor(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Xor_ArrayArray(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewSliceBitmap(0, 50000, 1000001, 1000002)
|
||||
bm0 := roaring.NewBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewBitmap(0, 50000, 1000001, 1000002)
|
||||
result := bm0.Xor(bm1)
|
||||
if n := result.Count(); n != 2 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -572,8 +572,8 @@ func TestBitmap_Xor_ArrayArray(t *testing.T) {
|
|||
|
||||
//empty array test
|
||||
func TestBitmap_Xor_Empty(t *testing.T) {
|
||||
bm1 := roaring.NewSliceBitmap(0, 50000, 1000001, 1000002)
|
||||
empty := roaring.NewSliceBitmap()
|
||||
bm1 := roaring.NewBitmap(0, 50000, 1000001, 1000002)
|
||||
empty := roaring.NewBitmap()
|
||||
result := bm1.Xor(empty)
|
||||
|
||||
if n := result.Count(); n != 4 {
|
||||
|
|
@ -581,8 +581,8 @@ func TestBitmap_Xor_Empty(t *testing.T) {
|
|||
}
|
||||
}
|
||||
func TestBitmap_Xor_ArrayBitmap(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(1, 70, 200, 4097, 4098)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(1, 70, 200, 4097, 4098)
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 10000; i += 2 {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -603,7 +603,7 @@ func TestBitmap_Xor_ArrayBitmap(t *testing.T) {
|
|||
t.Fatalf("test 3 unexpected n: %d", n)
|
||||
}
|
||||
|
||||
empty := roaring.NewSliceBitmap()
|
||||
empty := roaring.NewBitmap()
|
||||
result = bm1.Xor(empty)
|
||||
if n := result.Count(); n != 5000 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -611,8 +611,8 @@ func TestBitmap_Xor_ArrayBitmap(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBitmap_Xor_BitmapBitmap(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap()
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap()
|
||||
bm1 := roaring.NewBitmap()
|
||||
|
||||
for i := uint64(0); i < 10000; i += 2 {
|
||||
bm1.Add(i)
|
||||
|
|
@ -630,7 +630,7 @@ func TestBitmap_Xor_BitmapBitmap(t *testing.T) {
|
|||
|
||||
// Ensure bitmap contents alternate.
|
||||
func TestBitmap_Flip_Empty(t *testing.T) {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
results := bm.Flip(0, 10)
|
||||
if n := results.Count(); n != 11 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -643,7 +643,7 @@ func TestBitmap_Flip_Empty(t *testing.T) {
|
|||
|
||||
// Test Subrange Flip should not affect bits outside of Range
|
||||
func TestBitmap_Flip_Array(t *testing.T) {
|
||||
bm := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024)
|
||||
bm := roaring.NewBitmap(0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024)
|
||||
results := bm.Flip(0, 4)
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{8, 16, 32, 64, 128, 256, 512, 1024}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
|
|
@ -657,7 +657,7 @@ func TestBitmap_Flip_Array(t *testing.T) {
|
|||
|
||||
// Ensure Flip works with underlying Bitmap container.
|
||||
func TestBitmap_Flip_Bitmap(t *testing.T) {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
size := uint64(10000)
|
||||
for i := uint64(0); i < size; i += 2 {
|
||||
bm.Add(i)
|
||||
|
|
@ -674,7 +674,7 @@ func TestBitmap_Flip_Bitmap(t *testing.T) {
|
|||
|
||||
// Verify Flip works correctly with in different regions of bitmap, beginning, middle, and end.
|
||||
func TestBitmap_Flip_After(t *testing.T) {
|
||||
bm := roaring.NewSliceBitmap(0, 2, 4, 8)
|
||||
bm := roaring.NewBitmap(0, 2, 4, 8)
|
||||
results := bm.Flip(9, 10)
|
||||
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{0, 2, 4, 8, 9, 10}) {
|
||||
|
|
@ -693,8 +693,8 @@ func TestBitmap_Flip_After(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_ArrayArray(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewSliceBitmap(0, 50000, 1000001, 1000002)
|
||||
bm0 := roaring.NewBitmap(0, 1, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewBitmap(0, 50000, 1000001, 1000002)
|
||||
|
||||
if n := bm0.IntersectionCount(bm1); n != 3 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -705,8 +705,8 @@ func TestBitmap_IntersectionCount_ArrayArray(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_ArrayRun(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm0 := roaring.NewBitmap(0, 1000001, 1000002, 1000003)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm1.Optimize() // convert to runs
|
||||
|
||||
if n := bm0.IntersectionCount(bm1); n != 3 {
|
||||
|
|
@ -718,9 +718,9 @@ func TestBitmap_IntersectionCount_ArrayRun(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_RunRun(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(3, 4, 5, 6, 7, 8, 1000001, 1000002, 1000003, 1000004)
|
||||
bm0 := roaring.NewBitmap(3, 4, 5, 6, 7, 8, 1000001, 1000002, 1000003, 1000004)
|
||||
bm0.Optimize() // convert to runs
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm1.Optimize() // convert to runs
|
||||
|
||||
if n := bm0.IntersectionCount(bm1); n != 6 {
|
||||
|
|
@ -732,11 +732,11 @@ func TestBitmap_IntersectionCount_RunRun(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_BitmapRun(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap()
|
||||
for i := uint64(3); i <= 1000006; i += 2 {
|
||||
bm0.Add(i)
|
||||
}
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 1000000, 1000002, 1000003, 1000004, 1000005, 1000006)
|
||||
bm1.Optimize() // convert to runs
|
||||
|
||||
if n := bm0.IntersectionCount(bm1); n != 4 {
|
||||
|
|
@ -748,8 +748,8 @@ func TestBitmap_IntersectionCount_BitmapRun(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_ArrayBitmap(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap(1, 70, 200, 4097, 4098)
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap(1, 70, 200, 4097, 4098)
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(0); i <= 10000; i += 2 {
|
||||
bm1.Add(i)
|
||||
}
|
||||
|
|
@ -763,8 +763,8 @@ func TestBitmap_IntersectionCount_ArrayBitmap(t *testing.T) {
|
|||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_BitmapBitmap(t *testing.T) {
|
||||
bm0 := roaring.NewSliceBitmap()
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm0 := roaring.NewBitmap()
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(0); i <= 10000; i += 2 {
|
||||
bm0.Add(i)
|
||||
bm1.Add(i + 1)
|
||||
|
|
@ -784,8 +784,8 @@ func TestBitmap_IntersectionCount_BitmapBitmap(t *testing.T) {
|
|||
}
|
||||
func TestBitmap_IntersectionCount_Mixed(t *testing.T) {
|
||||
bm0 := testBM()
|
||||
bm1 := roaring.NewSliceBitmap(0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 65536)
|
||||
bm3 := roaring.NewSliceBitmap(131072)
|
||||
bm1 := roaring.NewBitmap(0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 65536)
|
||||
bm3 := roaring.NewBitmap(131072)
|
||||
|
||||
if n := bm0.IntersectionCount(bm0); n != bm0.Count() {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
|
|
@ -807,7 +807,7 @@ func TestBitmap_Quick_LargeValue(t *testing.T) { testBitmapQuick(t, 10000, 0, ma
|
|||
// Ensure a bitmap can perform basic operations on randomly generated values.
|
||||
func testBitmapQuick(t *testing.T, n int, min, max uint64) {
|
||||
quick.Check(func(a []uint64) bool {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
m := make(map[uint64]struct{})
|
||||
|
||||
// Add values to the bitmap and set.
|
||||
|
|
@ -894,7 +894,7 @@ func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64, sorted bool) {
|
|||
|
||||
quick.Check(func(a0, a1 []uint64) bool {
|
||||
// Create bitmap with initial values set.
|
||||
bm := roaring.NewSliceBitmap(a0...)
|
||||
bm := roaring.NewBitmap(a0...)
|
||||
|
||||
set := make(map[uint64]struct{})
|
||||
for _, v := range a0 {
|
||||
|
|
@ -923,7 +923,7 @@ func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64, sorted bool) {
|
|||
data := buf.Bytes()
|
||||
|
||||
// Create new bitmap from ops log data.
|
||||
bm2 := roaring.NewSliceBitmap()
|
||||
bm2 := roaring.NewBitmap()
|
||||
if err := bm2.UnmarshalBinary(data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -952,7 +952,7 @@ func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64, sorted bool) {
|
|||
// TODO duplicate for all container types
|
||||
func TestIterator(t *testing.T) {
|
||||
t.Run("bitmap", func(t *testing.T) {
|
||||
itr := roaring.NewSliceBitmap(1, 2, 3).Iterator()
|
||||
itr := roaring.NewBitmap(1, 2, 3).Iterator()
|
||||
itr.Seek(0)
|
||||
|
||||
var a []uint64
|
||||
|
|
@ -966,13 +966,13 @@ func TestIterator(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("run", func(t *testing.T) {
|
||||
bm1 := roaring.NewSliceBitmap()
|
||||
bm1 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 11; i += 1 {
|
||||
bm1.Add(i)
|
||||
}
|
||||
bm1.Optimize()
|
||||
|
||||
bm2 := roaring.NewSliceBitmap()
|
||||
bm2 := roaring.NewBitmap()
|
||||
for i := uint64(0); i < 12; i += 1 {
|
||||
bm2.Add(i)
|
||||
}
|
||||
|
|
@ -1005,7 +1005,7 @@ func TestIterator(t *testing.T) {
|
|||
// testBM creates a bitmap with 3 containers: array, bitmap, and run.
|
||||
func testBM() *roaring.Bitmap {
|
||||
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
//the array
|
||||
for i := uint64(0); i < 1024; i += 4 {
|
||||
bm.Add((1 << 16) + i)
|
||||
|
|
@ -1068,19 +1068,19 @@ func getBenchData() *struct{ a, b, r *roaring.Bitmap } {
|
|||
const max = (1 << 24) / 64
|
||||
|
||||
// Build bitmap with array container.
|
||||
data.a = roaring.NewSliceBitmap()
|
||||
data.a = roaring.NewBitmap()
|
||||
for i, n := 0, 2*roaring.ArrayMaxSize/3; i < n; i++ {
|
||||
data.a.Add(uint64(rand.Intn(max)))
|
||||
}
|
||||
|
||||
// Build bitmap with bitmap container.
|
||||
data.b = roaring.NewSliceBitmap()
|
||||
data.b = roaring.NewBitmap()
|
||||
for i, n := 0, MaxContainerVal/3; i < n; i++ {
|
||||
data.b.Add(uint64(i * 3))
|
||||
}
|
||||
|
||||
// build bitmap with run container
|
||||
data.r = roaring.NewSliceBitmap()
|
||||
data.r = roaring.NewBitmap()
|
||||
for i, n := 0, MaxContainerVal; i < n; i++ {
|
||||
data.r.Add(uint64(i))
|
||||
}
|
||||
|
|
@ -1176,7 +1176,7 @@ const (
|
|||
func BenchmarkContainerLinear(b *testing.B) {
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewBTreeBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for row := uint64(1); row < NumRows; row++ {
|
||||
for col := uint64(1); col < NumColums; col++ {
|
||||
bm.Add(row*pilosa.SliceWidth + (col * MaxContainerVal))
|
||||
|
|
@ -1187,7 +1187,7 @@ func BenchmarkContainerLinear(b *testing.B) {
|
|||
|
||||
func BenchmarkContainerReverse(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewBTreeBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for row := NumRows - 1; row >= 1; row-- {
|
||||
for col := NumColums - 1; col >= 1; col-- {
|
||||
bm.Add(row*pilosa.SliceWidth + (col * MaxContainerVal))
|
||||
|
|
@ -1198,7 +1198,7 @@ func BenchmarkContainerReverse(b *testing.B) {
|
|||
|
||||
func BenchmarkContainerColumn(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewBTreeBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for col := uint64(1); col < NumColums; col++ {
|
||||
for row := uint64(1); row < NumRows; row++ {
|
||||
bm.Add(row*pilosa.SliceWidth + (col * MaxContainerVal))
|
||||
|
|
@ -1210,7 +1210,7 @@ func BenchmarkContainerColumn(b *testing.B) {
|
|||
func BenchmarkContainerOutsideIn(b *testing.B) {
|
||||
middle := NumRows / uint64(2)
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewBTreeBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
|
||||
for col := uint64(1); col < NumColums; col++ {
|
||||
for row := uint64(1); row < middle; row++ {
|
||||
|
|
@ -1224,7 +1224,7 @@ func BenchmarkContainerOutsideIn(b *testing.B) {
|
|||
func BenchmarkContainerInsideOut(b *testing.B) {
|
||||
middle := NumRows / uint64(2)
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewBTreeBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for col := uint64(1); col < NumColums; col++ {
|
||||
for row := uint64(1); row <= middle; row++ {
|
||||
bm.Add((middle+row)*pilosa.SliceWidth + (col * MaxContainerVal))
|
||||
|
|
@ -1236,7 +1236,7 @@ func BenchmarkContainerInsideOut(b *testing.B) {
|
|||
|
||||
func BenchmarkSliceAscending(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for col := uint64(0); col < pilosa.SliceWidth; col++ {
|
||||
bm.Add(col)
|
||||
}
|
||||
|
|
@ -1245,7 +1245,7 @@ func BenchmarkSliceAscending(b *testing.B) {
|
|||
|
||||
func BenchmarkSliceDescending(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
bm := roaring.NewSliceBitmap()
|
||||
bm := roaring.NewBitmap()
|
||||
for col := uint64(pilosa.SliceWidth); col > uint64(0); col-- {
|
||||
bm.Add(col)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue