mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-10-07 11:27:50 +00:00
switch to bitmap repairs for inplace algo
This commit is contained in:
parent
339a78d88d
commit
b47292aa26
1 changed files with 39 additions and 6 deletions
|
|
@ -544,6 +544,19 @@ func (b *Bitmap) unionIntoTarget(target *Bitmap, others ...*Bitmap) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Repair bitmaps after the fact
|
||||
iter, _ := target.Containers.Iterator(0)
|
||||
for iter.Next() {
|
||||
_, container := iter.Value()
|
||||
if container.isBitmap() {
|
||||
n := int32(0)
|
||||
for i := 0; i < bitmapN; i++ {
|
||||
n += int32(popcount(container.bitmap[i]))
|
||||
}
|
||||
container.n = n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Difference returns the difference of b and other.
|
||||
|
|
@ -2539,10 +2552,12 @@ func unionBitmapRun(a, b *Container) *Container {
|
|||
return output
|
||||
}
|
||||
|
||||
// unions the run b into the bitmap a, mutating a in place. The n value of
|
||||
// a will need to be repaired after the fact.
|
||||
func unionBitmapRunInPlace(a, b *Container) {
|
||||
statsHit("union/BitmapRun")
|
||||
for j := 0; j < len(b.runs); j++ {
|
||||
a.bitmapSetRange(uint64(b.runs[j].start), uint64(b.runs[j].last)+1)
|
||||
a.bitmapSetRangeIgnoreN(uint64(b.runs[j].start), uint64(b.runs[j].last)+1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2571,6 +2586,25 @@ func (c *Container) bitmapSetRange(i, j uint64) {
|
|||
}
|
||||
}
|
||||
|
||||
// sets all bits in [i, j) (c must be a bitmap container) without updating
|
||||
// the value of n, meaning it will need to be repaired after the fact.
|
||||
func (c *Container) bitmapSetRangeIgnoreN(i, j uint64) {
|
||||
x := i >> 6
|
||||
y := (j - 1) >> 6
|
||||
var X uint64 = maxBitmap << (i % 64)
|
||||
var Y uint64 = maxBitmap >> (63 - ((j - 1) % 64))
|
||||
|
||||
if x == y {
|
||||
c.bitmap[x] |= (X & Y)
|
||||
} else {
|
||||
c.bitmap[x] |= X
|
||||
for i := x + 1; i < y; i++ {
|
||||
c.bitmap[i] = maxBitmap
|
||||
}
|
||||
c.bitmap[y] |= Y
|
||||
}
|
||||
}
|
||||
|
||||
// xor's all bits in [i, j) with all true (c must be a bitmap container).
|
||||
func (c *Container) bitmapXorRange(i, j uint64) {
|
||||
x := i >> 6
|
||||
|
|
@ -2665,6 +2699,8 @@ func unionArrayBitmap(a, b *Container) *Container {
|
|||
return output
|
||||
}
|
||||
|
||||
// unions array b into bitmap a, mutating a in place. The n value
|
||||
// of a will need to be repaired after the fact.
|
||||
func unionBitmapArrayInPlace(a, b *Container) {
|
||||
for _, v := range b.array {
|
||||
if !a.bitmapContains(v) {
|
||||
|
|
@ -2700,6 +2736,8 @@ func unionBitmapBitmap(a, b *Container) *Container {
|
|||
return output
|
||||
}
|
||||
|
||||
// unions bitmap b into bitmap a, mutating a in place. The n value of
|
||||
// a will need to be repaired after the fact.
|
||||
func unionBitmapBitmapInPlace(a, b *Container) {
|
||||
// local variables added to prevent BCE checks in loop
|
||||
// see https://go101.org/article/bounds-check-elimination.html
|
||||
|
|
@ -2707,16 +2745,11 @@ func unionBitmapBitmapInPlace(a, b *Container) {
|
|||
var (
|
||||
ab = a.bitmap[:bitmapN]
|
||||
bb = b.bitmap[:bitmapN]
|
||||
|
||||
n int32
|
||||
)
|
||||
|
||||
for i := 0; i < bitmapN; i++ {
|
||||
ab[i] = ab[i] | bb[i]
|
||||
n += int32(popcount(ab[i]))
|
||||
}
|
||||
|
||||
a.n = n
|
||||
}
|
||||
|
||||
func difference(a, b *Container) *Container {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue