mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-10 23:11:01 +00:00
more cardinality tracking and tests
This commit is contained in:
parent
88e0e4d5b6
commit
487a369c6d
2 changed files with 36 additions and 4 deletions
|
|
@ -1715,7 +1715,7 @@ func intersectRunRun(a, b *container) *container {
|
|||
i++
|
||||
}
|
||||
}
|
||||
if n < 4096 && len(output.runs) > n/2 {
|
||||
if output.n < 4096 && len(output.runs) > output.n/2 {
|
||||
output.runToArray()
|
||||
} else if len(output.runs) > RunMaxSize {
|
||||
output.runToBitmap()
|
||||
|
|
@ -1737,6 +1737,7 @@ func intersectBitmapRun(a, b *container) *container {
|
|||
}
|
||||
}
|
||||
}
|
||||
output.n = len(output.array)
|
||||
} else {
|
||||
// right now this iterates through the runs and sets integers in the
|
||||
// bitmap that are in the runs. alternately, we could zero out ranges in
|
||||
|
|
@ -1752,15 +1753,22 @@ func intersectBitmapRun(a, b *container) *container {
|
|||
for valast >= vb.start && vastart <= vb.last {
|
||||
if vastart >= vb.start && valast <= vb.last { // a within b
|
||||
output.bitmap[i] = a.bitmap[i]
|
||||
output.n += int(popcnt(a.bitmap[i]))
|
||||
} else if vb.start >= vastart && vb.last <= valast { // b within a
|
||||
var mask uint64 = ((1 << (vb.last - vb.start + 1)) - 1) << (vb.start - vastart)
|
||||
output.bitmap[i] |= a.bitmap[i] & mask
|
||||
bits := a.bitmap[i] & mask
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
} else if vastart < vb.start { // a overlaps front of b
|
||||
offset := 64 - (1 + valast - vb.start)
|
||||
output.bitmap[i] |= (a.bitmap[i] >> offset) << offset
|
||||
bits := (a.bitmap[i] >> offset) << offset
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
} else if vb.start < vastart { // b overlaps front of a
|
||||
offset := 64 - (1 + vb.last - vastart)
|
||||
output.bitmap[i] |= (a.bitmap[i] << offset) >> offset
|
||||
bits := (a.bitmap[i] << offset) >> offset
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
}
|
||||
// update loop vars
|
||||
i++
|
||||
|
|
@ -1768,6 +1776,9 @@ func intersectBitmapRun(a, b *container) *container {
|
|||
valast = vastart + 63
|
||||
}
|
||||
}
|
||||
if output.n < 4096 {
|
||||
output.bitmapToArray()
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
|
|
|||
|
|
@ -479,31 +479,37 @@ func TestIntersectBitmapRunBitmap(t *testing.T) {
|
|||
bitmap []uint64
|
||||
runs []interval32
|
||||
exp []uint64
|
||||
expN int
|
||||
}{
|
||||
{
|
||||
bitmap: []uint64{1},
|
||||
runs: []interval32{{start: 0, last: 0}, {start: 2, last: 5}, {start: 62, last: 71}, {start: 77, last: 4096}},
|
||||
exp: []uint64{1},
|
||||
expN: 1,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}},
|
||||
exp: []uint64{2},
|
||||
expN: 1,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}, {start: 10, last: 12}, {start: 61, last: 77}},
|
||||
exp: []uint64{0xe000000000001C02},
|
||||
expN: 7,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}, {start: 61, last: 77}},
|
||||
exp: []uint64{0xE000000000000002, 0x00000000000003FFF},
|
||||
expN: 18,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF, 1, 1, 1, 0xA, 1, 1, 0, 1},
|
||||
runs: []interval32{{start: 63, last: 10000}},
|
||||
exp: []uint64{0x8000000000000000, 1, 1, 1, 0xA, 1, 1, 0, 1},
|
||||
expN: 9,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
|
|
@ -517,9 +523,15 @@ func TestIntersectBitmapRunBitmap(t *testing.T) {
|
|||
exp[i] = v
|
||||
}
|
||||
ret := intersectBitmapRun(a, b)
|
||||
if ret.isArray() {
|
||||
ret.arrayToBitmap()
|
||||
}
|
||||
if !reflect.DeepEqual(ret.bitmap, exp) {
|
||||
t.Fatalf("test #%v expected %v, but got %v", i, exp, ret.bitmap)
|
||||
}
|
||||
if ret.n != test.expN {
|
||||
t.Fatalf("test #%v expected n to be %v, but got %v", i, test.expN, ret.n)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -531,31 +543,37 @@ func TestIntersectBitmapRunArray(t *testing.T) {
|
|||
bitmap []uint64
|
||||
runs []interval32
|
||||
exp []uint32
|
||||
expN int
|
||||
}{
|
||||
{
|
||||
bitmap: []uint64{1},
|
||||
runs: []interval32{{start: 0, last: 0}, {start: 2, last: 5}, {start: 62, last: 71}, {start: 77, last: 4096}},
|
||||
exp: []uint32{0},
|
||||
expN: 1,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}},
|
||||
exp: []uint32{1},
|
||||
expN: 1,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}, {start: 10, last: 12}, {start: 61, last: 77}},
|
||||
exp: []uint32{1, 10, 11, 12, 61, 62, 63},
|
||||
expN: 7,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
|
||||
runs: []interval32{{start: 1, last: 1}, {start: 61, last: 68}},
|
||||
exp: []uint32{1, 61, 62, 63, 64, 65, 66, 67, 68},
|
||||
expN: 9,
|
||||
},
|
||||
{
|
||||
bitmap: []uint64{0xFFFFFFFFFFFFFFFF, 1, 1, 1, 0xA, 1, 1, 0, 1},
|
||||
runs: []interval32{{start: 63, last: 10000}},
|
||||
exp: []uint32{63, 64, 128, 192, 257, 259, 320, 384, 512},
|
||||
expN: 9,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
|
|
@ -567,6 +585,9 @@ func TestIntersectBitmapRunArray(t *testing.T) {
|
|||
if !reflect.DeepEqual(ret.array, test.exp) {
|
||||
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
|
||||
}
|
||||
if ret.n != test.expN {
|
||||
t.Fatalf("test #%v expected n to be %v, but got %v", i, test.expN, ret.n)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue