rewrite intersectArrayBitmap for perf

This commit is contained in:
Matthew Jaffee 2017-09-15 15:34:59 -05:00 • committed by Travis
parent 1736a40b74
commit de6a25cb8d
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
2 changed files with 96 additions and 1 deletions

View file

@ -2089,7 +2089,7 @@ func intersectBitmapRun(a, b *container) *container {
return output
}
func intersectArrayBitmap(a, b *container) *container {
func intersectArrayBitmapOld(a, b *container) *container {
output := &container{container_type: ContainerArray}
itra := newArrayIterator(a.array)
itrb := newBitmapIterator(b.bitmap)
@ -2113,6 +2113,20 @@ func intersectArrayBitmap(a, b *container) *container {
return output
}
func intersectArrayBitmap(a, b *container) *container {
output := &container{container_type: ContainerArray}
for _, va := range a.array {
bmidx := va / 64
bidx := va % 64
mask := uint64(1) << bidx
b := b.bitmap[bmidx]
if b&mask > 0 {
output.array = append(output.array, va)
}
}
return output
}
func intersectBitmapBitmap(a, b *container) *container {
output := &container{bitmap: make([]uint64, bitmapN), container_type: ContainerBitmap}

View file

@ -2442,3 +2442,84 @@ func TestSearc64(t *testing.T) {
})
}
}
func TestIntersectArrayBitmap(t *testing.T) {
a, b := &container{}, &container{
bitmap: make([]uint64, bitmapN),
}
tests := []struct {
array []uint16
bitmap []uint64
exp []uint16
}{
{
array: []uint16{0},
bitmap: []uint64{1},
exp: []uint16{0},
},
{
array: []uint16{0, 1},
bitmap: []uint64{3},
exp: []uint16{0, 1},
},
{
array: []uint16{64, 128, 129, 2000},
bitmap: []uint64{932421, 2},
exp: []uint16{},
},
{
array: []uint16{0, 65, 130, 195},
bitmap: []uint64{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255},
exp: []uint16{0, 65, 130, 195},
},
{
array: []uint16{63, 120, 543, 639, 12000},
bitmap: []uint64{0x8000000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0x8000000000000000},
exp: []uint16{63, 639},
},
{
array: []uint16{0, 1, 63, 120, 543, 639, 12000, 65534, 65535},
bitmap: bitmapOdds(),
exp: []uint16{1, 63, 543, 639, 65535},
},
{
array: []uint16{0, 1, 63, 120, 543, 639, 12000, 65534, 65535},
bitmap: bitmapEvens(),
exp: []uint16{0, 120, 12000, 65534},
},
}
for i, test := range tests {
a.array = test.array
a.container_type = ContainerArray
for i, bmval := range test.bitmap {
b.bitmap[i] = bmval
}
b.container_type = ContainerBitmap
ret1 := intersectArrayBitmapOld(a, b).array
ret2 := intersectArrayBitmap(a, b).array
fmt.Println("ret1", ret1, "ret2", ret2, "test.exp", test.exp)
if len(ret1) == 0 && len(ret2) == 0 && len(test.exp) == 0 {
continue
}
if !reflect.DeepEqual(ret1, ret2) || !reflect.DeepEqual(ret2, test.exp) {
t.Fatalf("test #%v intersectArrayBitmap fail orig: %v new: %v exp: %v", i, ret1, ret2, test.exp)
}
}
}
func bitmapOdds() []uint64 {
bitmap := make([]uint64, bitmapN)
for i := 0; i < bitmapN; i++ {
bitmap[i] = 0xAAAAAAAAAAAAAAAA
}
return bitmap
}
func bitmapEvens() []uint64 {
bitmap := make([]uint64, bitmapN)
for i := 0; i < bitmapN; i++ {
bitmap[i] = 0x5555555555555555
}
return bitmap
}