mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
Merge pull request #849 from travisturner/flip-bitmap
implement container.flipBitmap() to improve differenceRunBitmap()
This commit is contained in:
commit
6066c29ea7
2 changed files with 50 additions and 1 deletions
|
|
@ -965,7 +965,7 @@ const RunMaxSize = 2048
|
|||
// an array or RLE container is used, depending on the contents. For containers
|
||||
// with more than 4,096 values, the values are encoded into bitmaps.
|
||||
type container struct {
|
||||
container_type byte // number of integers in container
|
||||
container_type byte // array, bitmap, or run
|
||||
n int // number of integers in container
|
||||
array []uint16 // used for array containers
|
||||
bitmap []uint64 // used for bitmap containers
|
||||
|
|
@ -1625,6 +1625,19 @@ func (c *container) clone() *container {
|
|||
return other
|
||||
}
|
||||
|
||||
// flipBitmap returns a new bitmap containter containing the inverse of all
|
||||
// bits in c.
|
||||
func (c *container) flipBitmap() *container {
|
||||
other := &container{bitmap: make([]uint64, bitmapN), container_type: ContainerBitmap}
|
||||
|
||||
for i, bitmap := range c.bitmap {
|
||||
other.bitmap[i] = ^bitmap
|
||||
}
|
||||
|
||||
other.n = other.count()
|
||||
return other
|
||||
}
|
||||
|
||||
// WriteTo writes c to w.
|
||||
func (c *container) WriteTo(w io.Writer) (n int64, err error) {
|
||||
if c.isArray() {
|
||||
|
|
@ -2533,6 +2546,10 @@ func differenceRunBitmap(a, b *container) *container {
|
|||
if a.n == 0 || b.n == 0 {
|
||||
return a.clone()
|
||||
}
|
||||
// If a is full, difference is the flip of b.
|
||||
if a.runs[0].start == 0 && a.runs[0].last == 65535 {
|
||||
return b.flipBitmap()
|
||||
}
|
||||
itr := newBufBitmapIterator(newBitmapIterator(b.bitmap))
|
||||
return differenceRunIterator(a, itr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1869,6 +1869,38 @@ func TestXorRunRun(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBitmapFlip(t *testing.T) {
|
||||
c := &container{bitmap: make([]uint64, bitmapN), container_type: ContainerBitmap}
|
||||
|
||||
ttable := []struct {
|
||||
original uint64
|
||||
flipped uint64
|
||||
}{
|
||||
{0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
|
||||
{0xFFFFFFFFFFFFFFFF, 0x0000000000000000},
|
||||
{0xFFFFFFFFFFFFFFF0, 0x000000000000000F},
|
||||
{0xFFFFFFEFFFFFFFFF, 0x0000001000000000},
|
||||
{0x0000001000000000, 0xFFFFFFEFFFFFFFFF},
|
||||
}
|
||||
|
||||
expectedN := int(65536)
|
||||
for i, tt := range ttable {
|
||||
c.bitmap[i] = tt.original
|
||||
expectedN -= int(popcount(tt.original))
|
||||
}
|
||||
|
||||
o := c.flipBitmap()
|
||||
|
||||
for i, tt := range ttable {
|
||||
if o.bitmap[i] != tt.flipped {
|
||||
t.Fatalf("bitmapFlip calculation. expected %v, got %v", tt.flipped, o.bitmap[i])
|
||||
}
|
||||
}
|
||||
if o.n != expectedN {
|
||||
t.Fatalf("bitmapFlip calculation. expected count %v, got %v", expectedN, o.n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBitmapXorRange(t *testing.T) {
|
||||
c := &container{bitmap: make([]uint64, bitmapN), container_type: ContainerBitmap}
|
||||
tests := []struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue