mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 17:15:56 +00:00
optimzed differenceRunBitmap
This commit is contained in:
parent
3f3cc60531
commit
de2f16b617
2 changed files with 51 additions and 11 deletions
|
|
@ -2531,15 +2531,46 @@ func differenceRunArray(a, b *container) *container {
|
|||
|
||||
// differenceRunBitmap computes the difference of an run from a bitmap.
|
||||
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)
|
||||
output := &container{container_type: ContainerRun}
|
||||
output.n = a.n
|
||||
for j := 0; j < len(a.runs); j++ {
|
||||
run := a.runs[j]
|
||||
for bit := a.runs[j].start; bit <= a.runs[j].last; bit++ {
|
||||
if b.bitmapContains(bit) {
|
||||
output.n--
|
||||
if run.start == bit {
|
||||
run.start++
|
||||
} else if bit == run.last {
|
||||
run.last--
|
||||
} else {
|
||||
run.last = bit - 1
|
||||
if run.last >= run.start {
|
||||
output.runs = append(output.runs, run)
|
||||
}
|
||||
run.start = bit + 1
|
||||
run.last = a.runs[j].last
|
||||
}
|
||||
if run.start > run.last {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if run.start <= run.last {
|
||||
output.runs = append(output.runs, run)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if output.n < ArrayMaxSize && int(len(output.runs)) > output.n/2 {
|
||||
output.runToArray()
|
||||
} else if len(output.runs) > RunMaxSize {
|
||||
output.runToBitmap()
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func differenceRunIterator(a *container, itr containerIterator) *container {
|
||||
|
|
|
|||
|
|
@ -1464,6 +1464,15 @@ func TestDifferenceRunArray(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
func MakeBitmap(start []uint64) []uint64 {
|
||||
|
||||
b := make([]uint64, bitmapN)
|
||||
for i, v := range start {
|
||||
b[i] = v
|
||||
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func TestDifferenceRunBitmap(t *testing.T) {
|
||||
a := &container{}
|
||||
|
|
@ -1475,32 +1484,32 @@ func TestDifferenceRunBitmap(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 63}},
|
||||
bitmap: []uint64{0x0000FFFF000000F0},
|
||||
bitmap: MakeBitmap([]uint64{0x0000FFFF000000F0}),
|
||||
exp: []interval16{{start: 0, last: 3}, {start: 8, last: 31}, {start: 48, last: 63}},
|
||||
},
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 63}},
|
||||
bitmap: []uint64{0x8000000000000000},
|
||||
bitmap: MakeBitmap([]uint64{0x8000000000000000}),
|
||||
exp: []interval16{{start: 0, last: 62}},
|
||||
},
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 63}},
|
||||
bitmap: []uint64{0x0000000000000001},
|
||||
bitmap: MakeBitmap([]uint64{0x0000000000000001}),
|
||||
exp: []interval16{{start: 1, last: 63}},
|
||||
},
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 63}},
|
||||
bitmap: []uint64{0x0, 0x0000000000000001},
|
||||
bitmap: MakeBitmap([]uint64{0x0, 0x0000000000000001}),
|
||||
exp: []interval16{{start: 0, last: 63}},
|
||||
},
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 65}},
|
||||
bitmap: []uint64{0x0, 0x0000000000000001},
|
||||
bitmap: MakeBitmap([]uint64{0x0, 0x0000000000000001}),
|
||||
exp: []interval16{{start: 0, last: 63}, {start: 65, last: 65}},
|
||||
},
|
||||
{
|
||||
runs: []interval16{{start: 0, last: 65}},
|
||||
bitmap: []uint64{0x0, 0x8000000000000000},
|
||||
bitmap: MakeBitmap([]uint64{0x0, 0x8000000000000000}),
|
||||
exp: []interval16{{start: 0, last: 65}},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue