fix a bug in the "less than" logic

This commit is contained in:
Matt Jaffee 2019-10-29 14:00:33 -05:00
parent 5dcabfcc7f
commit a9a4d244ef
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
2 changed files with 30 additions and 0 deletions

View file

@ -26,6 +26,7 @@ import (
"io"
"io/ioutil"
"math"
"math/bits"
"os"
"sort"
"strings"
@ -1353,10 +1354,24 @@ func (f *fragment) rangeLT(bitDepth uint, predicate int64, allowEquality bool) (
return f.rangeGTUnsigned(b.Intersect(f.row(bsiSignBit)), bitDepth, upredicate, allowEquality)
}
// msb gives the 1-indexed position (counting from lsb) of the most
// significant bit. E.G. for 1 it would return 1, for 2 2, for 3 2,
// for 4 3, for 8 4, etc.
func msb(x uint64) uint {
lz := bits.LeadingZeros64(x)
return 64 - uint(lz)
}
// rangeLTUnsigned returns all bits LT/LTE the predicate without considering the sign bit.
func (f *fragment) rangeLTUnsigned(filter *Row, bitDepth uint, predicate uint64, allowEquality bool) (*Row, error) {
keep := NewRow()
// if the predicate is larger than all representable numbers given
// our bitDepth... then just return everything.
if msb(predicate) >= bitDepth {
return filter, nil
}
// Filter any bits that don't match the current bit value.
leadingZeros := true
for i := int(bitDepth - 1); i >= 0; i-- {

View file

@ -596,6 +596,21 @@ func TestFragment_Range(t *testing.T) {
}
})
t.Run("LTRegression", func(t *testing.T) {
f := mustOpenFragment("i", "f", viewStandard, 0, "")
defer f.Clean(t)
if _, err := f.setValue(1, 1, 1); err != nil {
t.Fatal(err)
}
if b, err := f.rangeOp(pql.LT, 1, 2); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual(b.Columns(), []uint64{1}) {
t.Fatalf("unepxected coulmns: %+v", b.Columns())
}
})
t.Run("GT", func(t *testing.T) {
f := mustOpenFragment("i", "f", viewStandard, 0, "")
defer f.Clean(t)