renamed pilosa.Bitmap to Row

This commit is contained in:
Todd Gruben 2018-05-21 09:12:42 -05:00
parent 8e071df0c2
commit 575e199ad8
11 changed files with 116 additions and 116 deletions

2
api.go
View file

@ -114,7 +114,7 @@ func (api *API) Query(ctx context.Context, req *QueryRequest) (QueryResponse, er
// Consolidate all column ids across all calls.
var columnIDs []uint64
for _, result := range results {
bm, ok := result.(*Bitmap)
bm, ok := result.(*Row)
if !ok {
continue
}

View file

@ -22,8 +22,8 @@ import (
"github.com/pilosa/pilosa/roaring"
)
// Bitmap represents a set of bits.
type Bitmap struct {
// Row represents a set of bits.
type Row struct {
segments []BitmapSegment
// Attributes associated with the bitmap.
@ -31,8 +31,8 @@ type Bitmap struct {
}
// NewBitmap returns a new instance of Bitmap.
func NewBitmap(bits ...uint64) *Bitmap {
bm := &Bitmap{}
func NewBitmap(bits ...uint64) *Row {
bm := &Row{}
for _, i := range bits {
bm.SetBit(i)
}
@ -40,7 +40,7 @@ func NewBitmap(bits ...uint64) *Bitmap {
}
// Merge merges data from other into b.
func (b *Bitmap) Merge(other *Bitmap) {
func (b *Row) Merge(other *Row) {
var segments []BitmapSegment
itr := newMergeSegmentIterator(b.segments, other.segments)
@ -64,7 +64,7 @@ func (b *Bitmap) Merge(other *Bitmap) {
}
// IntersectionCount returns the number of intersections between b and other.
func (b *Bitmap) IntersectionCount(other *Bitmap) uint64 {
func (b *Row) IntersectionCount(other *Row) uint64 {
var n uint64
itr := newMergeSegmentIterator(b.segments, other.segments)
@ -80,7 +80,7 @@ func (b *Bitmap) IntersectionCount(other *Bitmap) uint64 {
}
// Intersect returns the itersection of b and other.
func (b *Bitmap) Intersect(other *Bitmap) *Bitmap {
func (b *Row) Intersect(other *Row) *Row {
var segments []BitmapSegment
itr := newMergeSegmentIterator(b.segments, other.segments)
@ -92,11 +92,11 @@ func (b *Bitmap) Intersect(other *Bitmap) *Bitmap {
segments = append(segments, *s0.Intersect(s1))
}
return &Bitmap{segments: segments}
return &Row{segments: segments}
}
// Xor returns the xor of b and other.
func (b *Bitmap) Xor(other *Bitmap) *Bitmap {
func (b *Row) Xor(other *Row) *Row {
var segments []BitmapSegment
itr := newMergeSegmentIterator(b.segments, other.segments)
@ -112,11 +112,11 @@ func (b *Bitmap) Xor(other *Bitmap) *Bitmap {
segments = append(segments, *s0.Xor(s1))
}
return &Bitmap{segments: segments}
return &Row{segments: segments}
}
// Union returns the bitwise union of b and other.
func (b *Bitmap) Union(other *Bitmap) *Bitmap {
func (b *Row) Union(other *Row) *Row {
var segments []BitmapSegment
itr := newMergeSegmentIterator(b.segments, other.segments)
for s0, s1 := itr.next(); s0 != nil || s1 != nil; s0, s1 = itr.next() {
@ -130,11 +130,11 @@ func (b *Bitmap) Union(other *Bitmap) *Bitmap {
segments = append(segments, *s0.Union(s1))
}
return &Bitmap{segments: segments}
return &Row{segments: segments}
}
// Difference returns the diff of b and other.
func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
func (b *Row) Difference(other *Row) *Row {
var segments []BitmapSegment
itr := newMergeSegmentIterator(b.segments, other.segments)
@ -148,16 +148,16 @@ func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
segments = append(segments, *s0.Difference(s1))
}
return &Bitmap{segments: segments}
return &Row{segments: segments}
}
// SetBit sets the i-th bit of the bitmap.
func (b *Bitmap) SetBit(i uint64) (changed bool) {
func (b *Row) SetBit(i uint64) (changed bool) {
return b.createSegmentIfNotExists(i / SliceWidth).SetBit(i)
}
// ClearBit clears the i-th bit of the bitmap.
func (b *Bitmap) ClearBit(i uint64) (changed bool) {
func (b *Row) ClearBit(i uint64) (changed bool) {
s := b.segment(i / SliceWidth)
if s == nil {
return false
@ -167,7 +167,7 @@ func (b *Bitmap) ClearBit(i uint64) (changed bool) {
// segment returns a segment for a given slice.
// Returns nil if segment does not exist.
func (b *Bitmap) segment(slice uint64) *BitmapSegment {
func (b *Row) segment(slice uint64) *BitmapSegment {
if i := sort.Search(len(b.segments), func(i int) bool {
return b.segments[i].slice >= slice
}); i < len(b.segments) && b.segments[i].slice == slice {
@ -176,7 +176,7 @@ func (b *Bitmap) segment(slice uint64) *BitmapSegment {
return nil
}
func (b *Bitmap) createSegmentIfNotExists(slice uint64) *BitmapSegment {
func (b *Row) createSegmentIfNotExists(slice uint64) *BitmapSegment {
i := sort.Search(len(b.segments), func(i int) bool {
return b.segments[i].slice >= slice
})
@ -201,14 +201,14 @@ func (b *Bitmap) createSegmentIfNotExists(slice uint64) *BitmapSegment {
}
// InvalidateCount updates the cached count in the bitmap.
func (b *Bitmap) InvalidateCount() {
func (b *Row) InvalidateCount() {
for i := range b.segments {
b.segments[i].InvalidateCount()
}
}
// IncrementCount increments the bitmap cached counter, note this is an optimization that assumes that the caller is aware the size increased.
func (b *Bitmap) IncrementCount(i uint64) {
func (b *Row) IncrementCount(i uint64) {
seg := b.segment(i / SliceWidth)
if seg != nil {
seg.n++
@ -217,7 +217,7 @@ func (b *Bitmap) IncrementCount(i uint64) {
}
// DecrementCount decrements the bitmap cached counter.
func (b *Bitmap) DecrementCount(i uint64) {
func (b *Row) DecrementCount(i uint64) {
seg := b.segment(i / SliceWidth)
if seg != nil {
if seg.n > 0 {
@ -227,7 +227,7 @@ func (b *Bitmap) DecrementCount(i uint64) {
}
// Count returns the number of set bits in the bitmap.
func (b *Bitmap) Count() uint64 {
func (b *Row) Count() uint64 {
var n uint64
for i := range b.segments {
n += b.segments[i].Count()
@ -236,7 +236,7 @@ func (b *Bitmap) Count() uint64 {
}
// MarshalJSON returns a JSON-encoded byte slice of b.
func (b *Bitmap) MarshalJSON() ([]byte, error) {
func (b *Row) MarshalJSON() ([]byte, error) {
var o struct {
Attrs map[string]interface{} `json:"attrs"`
Bits []uint64 `json:"bits"`
@ -252,7 +252,7 @@ func (b *Bitmap) MarshalJSON() ([]byte, error) {
}
// Bits returns the bits in b as a slice of ints.
func (b *Bitmap) Bits() []uint64 {
func (b *Row) Bits() []uint64 {
a := make([]uint64, 0, b.Count())
for i := range b.segments {
a = append(a, b.segments[i].Bits()...)
@ -261,7 +261,7 @@ func (b *Bitmap) Bits() []uint64 {
}
// encodeBitmap converts b into its internal representation.
func encodeBitmap(b *Bitmap) *internal.Bitmap {
func encodeBitmap(b *Row) *internal.Bitmap {
if b == nil {
return nil
}
@ -273,7 +273,7 @@ func encodeBitmap(b *Bitmap) *internal.Bitmap {
}
// decodeBitmap converts b from its internal representation.
func decodeBitmap(pb *internal.Bitmap) *Bitmap {
func decodeBitmap(pb *internal.Bitmap) *Row {
if pb == nil {
return nil
}
@ -287,7 +287,7 @@ func decodeBitmap(pb *internal.Bitmap) *Bitmap {
}
// Union performs a union on a slice of bitmaps.
func Union(bitmaps []*Bitmap) *Bitmap {
func Union(bitmaps []*Row) *Row {
other := bitmaps[0]
for _, bm := range bitmaps[1:] {
other = other.Union(bm)

View file

@ -25,8 +25,8 @@ import (
// Ensure a bitmap can be merged
func TestBitmap_Merge(t *testing.T) {
tests := []struct {
bm1 *pilosa.Bitmap
bm2 *pilosa.Bitmap
bm1 *pilosa.Row
bm2 *pilosa.Row
exp uint64
}{
{

View file

@ -463,8 +463,8 @@ func (p uint64Slice) merge(other []uint64) []uint64 {
// BitmapCache provides an interface for caching full bitmaps.
type BitmapCache interface {
Fetch(id uint64) (*Bitmap, bool)
Add(id uint64, b *Bitmap)
Fetch(id uint64) (*Row, bool)
Add(id uint64, b *Row)
}
// SimpleCache implements BitmapCache
@ -473,17 +473,17 @@ type BitmapCache interface {
// A read-heavy use case would cause the cache to get bigger, potentially causing the
// node to run out of memory.
type SimpleCache struct {
cache map[uint64]*Bitmap
cache map[uint64]*Row
}
// Fetch retrieves the bitmap at the id in the cache.
func (s *SimpleCache) Fetch(id uint64) (*Bitmap, bool) {
func (s *SimpleCache) Fetch(id uint64) (*Row, bool) {
m, ok := s.cache[id]
return m, ok
}
// Add adds the bitmap to the cache, keyed on the id.
func (s *SimpleCache) Add(id uint64, b *Bitmap) {
func (s *SimpleCache) Add(id uint64, b *Row) {
s.cache[id] = b
}

View file

@ -310,7 +310,7 @@ func (e *Executor) executeFieldMax(ctx context.Context, index string, c *pql.Cal
}
// executeBitmapCall executes a call that returns a bitmap.
func (e *Executor) executeBitmapCall(ctx context.Context, index string, c *pql.Call, slices []uint64, opt *ExecOptions) (*Bitmap, error) {
func (e *Executor) executeBitmapCall(ctx context.Context, index string, c *pql.Call, slices []uint64, opt *ExecOptions) (*Row, error) {
// Execute calls in bulk on each remote node and merge.
mapFn := func(slice uint64) (interface{}, error) {
return e.executeBitmapCallSlice(ctx, index, c, slice)
@ -318,11 +318,11 @@ func (e *Executor) executeBitmapCall(ctx context.Context, index string, c *pql.C
// Merge returned results at coordinating node.
reduceFn := func(prev, v interface{}) interface{} {
other, _ := prev.(*Bitmap)
other, _ := prev.(*Row)
if other == nil {
other = NewBitmap()
}
other.Merge(v.(*Bitmap))
other.Merge(v.(*Row))
return other
}
@ -334,7 +334,7 @@ func (e *Executor) executeBitmapCall(ctx context.Context, index string, c *pql.C
// Attach attributes for Bitmap() calls.
// If the column label is used then return column attributes.
// If the row label is used then return bitmap attributes.
bm, _ := other.(*Bitmap)
bm, _ := other.(*Row)
if c.Name == "Bitmap" {
if opt.ExcludeAttrs {
bm.Attrs = map[string]interface{}{}
@ -375,7 +375,7 @@ func (e *Executor) executeBitmapCall(ctx context.Context, index string, c *pql.C
}
// executeBitmapCallSlice executes a bitmap call for a single slice.
func (e *Executor) executeBitmapCallSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeBitmapCallSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
switch c.Name {
case "Bitmap":
return e.executeBitmapSlice(ctx, index, c, slice)
@ -396,7 +396,7 @@ func (e *Executor) executeBitmapCallSlice(ctx context.Context, index string, c *
// executeSumCountSlice calculates the sum and count for fields on a slice.
func (e *Executor) executeSumCountSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (ValCount, error) {
var filter *Bitmap
var filter *Row
if len(c.Children) == 1 {
bm, err := e.executeBitmapCallSlice(ctx, index, c.Children[0], slice)
if err != nil {
@ -435,7 +435,7 @@ func (e *Executor) executeSumCountSlice(ctx context.Context, index string, c *pq
// executeFieldMinSlice calculates the min for fields on a slice.
func (e *Executor) executeFieldMinSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (ValCount, error) {
var filter *Bitmap
var filter *Row
if len(c.Children) == 1 {
bm, err := e.executeBitmapCallSlice(ctx, index, c.Children[0], slice)
if err != nil {
@ -474,7 +474,7 @@ func (e *Executor) executeFieldMinSlice(ctx context.Context, index string, c *pq
// executeFieldMaxSlice calculates the max for fields on a slice.
func (e *Executor) executeFieldMaxSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (ValCount, error) {
var filter *Bitmap
var filter *Row
if len(c.Children) == 1 {
bm, err := e.executeBitmapCallSlice(ctx, index, c.Children[0], slice)
if err != nil {
@ -601,7 +601,7 @@ func (e *Executor) executeTopNSlice(ctx context.Context, index string, c *pql.Ca
}
// Retrieve bitmap used to intersect.
var src *Bitmap
var src *Row
if len(c.Children) == 1 {
bm, err := e.executeBitmapCallSlice(ctx, index, c.Children[0], slice)
if err != nil {
@ -647,8 +647,8 @@ func (e *Executor) executeTopNSlice(ctx context.Context, index string, c *pql.Ca
}
// executeDifferenceSlice executes a difference() call for a local slice.
func (e *Executor) executeDifferenceSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
var other *Bitmap
func (e *Executor) executeDifferenceSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
var other *Row
if len(c.Children) == 0 {
return nil, fmt.Errorf("empty Difference query is currently not supported")
}
@ -668,7 +668,7 @@ func (e *Executor) executeDifferenceSlice(ctx context.Context, index string, c *
return other, nil
}
func (e *Executor) executeBitmapSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeBitmapSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
// Fetch column label from index.
idx := e.Holder.Index(index)
if idx == nil {
@ -714,8 +714,8 @@ func (e *Executor) executeBitmapSlice(ctx context.Context, index string, c *pql.
}
// executeIntersectSlice executes a intersect() call for a local slice.
func (e *Executor) executeIntersectSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
var other *Bitmap
func (e *Executor) executeIntersectSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
var other *Row
if len(c.Children) == 0 {
return nil, fmt.Errorf("empty Intersect query is currently not supported")
}
@ -736,7 +736,7 @@ func (e *Executor) executeIntersectSlice(ctx context.Context, index string, c *p
}
// executeRangeSlice executes a range() call for a local slice.
func (e *Executor) executeRangeSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeRangeSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
// Handle field ranges differently.
if c.HasConditionArg() {
return e.executeFieldRangeSlice(ctx, index, c, slice)
@ -806,11 +806,11 @@ func (e *Executor) executeRangeSlice(ctx context.Context, index string, c *pql.C
// If no quantum exists then return an empty bitmap.
q := f.TimeQuantum()
if q == "" {
return &Bitmap{}, nil
return &Row{}, nil
}
// Union bitmaps across all time-based subframes.
bm := &Bitmap{}
bm := &Row{}
for _, view := range ViewsByTimeRange(viewName, startTime, endTime, q) {
f := e.Holder.Fragment(index, frame, view, slice)
if f == nil {
@ -823,7 +823,7 @@ func (e *Executor) executeRangeSlice(ctx context.Context, index string, c *pql.C
}
// executeFieldRangeSlice executes a range(field) call for a local slice.
func (e *Executor) executeFieldRangeSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeFieldRangeSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
// Parse frame, use default if unset.
frame, _ := c.Args["frame"].(string)
if frame == "" {
@ -962,7 +962,7 @@ func (e *Executor) executeFieldRangeSlice(ctx context.Context, index string, c *
}
// executeUnionSlice executes a union() call for a local slice.
func (e *Executor) executeUnionSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeUnionSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
other := NewBitmap()
for i, input := range c.Children {
bm, err := e.executeBitmapCallSlice(ctx, index, input, slice)
@ -981,7 +981,7 @@ func (e *Executor) executeUnionSlice(ctx context.Context, index string, c *pql.C
}
// executeXorSlice executes a xor() call for a local slice.
func (e *Executor) executeXorSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Bitmap, error) {
func (e *Executor) executeXorSlice(ctx context.Context, index string, c *pql.Call, slice uint64) (*Row, error) {
other := NewBitmap()
for i, input := range c.Children {
bm, err := e.executeBitmapCallSlice(ctx, index, input, slice)

View file

@ -54,27 +54,27 @@ func TestExecutor_Execute_Bitmap(t *testing.T) {
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Bitmap(row=10, frame=f)`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{3, SliceWidth + 1}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{3, SliceWidth + 1}) {
t.Fatalf("unexpected bits: %+v", bits)
} else if attrs := res[0].(*pilosa.Bitmap).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
} else if attrs := res[0].(*pilosa.Row).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
t.Fatalf("unexpected attrs: %s", spew.Sdump(attrs))
}
// Inhibit bits.
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Bitmap(row=10, frame=f)`), nil, &pilosa.ExecOptions{ExcludeBits: true}); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{}) {
t.Fatalf("unexpected bits: %+v", bits)
} else if attrs := res[0].(*pilosa.Bitmap).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
} else if attrs := res[0].(*pilosa.Row).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
t.Fatalf("unexpected attrs: %s", spew.Sdump(attrs))
}
// Inhibit attributes.
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Bitmap(row=10, frame=f)`), nil, &pilosa.ExecOptions{ExcludeAttrs: true}); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{3, SliceWidth + 1}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{3, SliceWidth + 1}) {
t.Fatalf("unexpected bits: %+v", bits)
} else if attrs := res[0].(*pilosa.Bitmap).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{}) {
} else if attrs := res[0].(*pilosa.Row).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{}) {
t.Fatalf("unexpected attrs: %s", spew.Sdump(attrs))
}
})
@ -103,9 +103,9 @@ func TestExecutor_Execute_Bitmap(t *testing.T) {
if res, err := e.Execute(context.Background(), "i", test.MustParse(fmt.Sprintf(`Bitmap(col=%d, frame=f)`, SliceWidth+1)), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{10, 20}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{10, 20}) {
t.Fatalf("unexpected bits: %+v", bits)
} else if attrs := res[0].(*pilosa.Bitmap).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
} else if attrs := res[0].(*pilosa.Row).Attrs; !reflect.DeepEqual(attrs, map[string]interface{}{"foo": "bar", "baz": int64(123)}) {
t.Fatalf("unexpected attrs: %s", spew.Sdump(attrs))
}
})
@ -124,7 +124,7 @@ func TestExecutor_Execute_Difference(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Difference(Bitmap(row=10), Bitmap(row=11))`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{1, 3}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{1, 3}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}
@ -156,7 +156,7 @@ func TestExecutor_Execute_Intersect(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Intersect(Bitmap(row=10), Bitmap(row=11))`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{1, SliceWidth + 2}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{1, SliceWidth + 2}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}
@ -186,7 +186,7 @@ func TestExecutor_Execute_Union(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Union(Bitmap(row=10), Bitmap(row=11))`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{0, 2, SliceWidth + 1, SliceWidth + 2}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{0, 2, SliceWidth + 1, SliceWidth + 2}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}
@ -200,7 +200,7 @@ func TestExecutor_Execute_Empty_Union(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Union()`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}
@ -219,7 +219,7 @@ func TestExecutor_Execute_Xor(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Xor(Bitmap(row=10), Bitmap(row=11))`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{0, 2, SliceWidth + 1}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{0, 2, SliceWidth + 1}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}
@ -784,7 +784,7 @@ func TestExecutor_Execute_Range(t *testing.T) {
t.Run("Standard", func(t *testing.T) {
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Range(row=1, frame=f, start="1999-12-31T00:00", end="2002-01-01T03:00")`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{2, 3, 4, 5, 6, 7}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{2, 3, 4, 5, 6, 7}) {
t.Fatalf("unexpected bits: %+v", bits)
}
})
@ -793,7 +793,7 @@ func TestExecutor_Execute_Range(t *testing.T) {
e := test.NewExecutor(hldr.Holder, test.NewCluster(1))
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Range(col=2, frame=f, start="1999-01-01T00:00", end="2003-01-01T00:00")`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{1, 10}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{1, 10}) {
t.Fatalf("unexpected bits: %+v", bits)
}
})
@ -854,7 +854,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("EQ", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{50, (5 * SliceWidth) + 100}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{50, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -863,28 +863,28 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
// NEQ null
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo != null)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
// NEQ <int>
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo != 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1, SliceWidth + 2}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1, SliceWidth + 2}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
// NEQ -<int>
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo != -20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Bits()) {
//t.Fatalf("unexpected result: %s", spew.Sdump(result))
t.Fatalf("unexpected result: %v", result[0].(*pilosa.Bitmap).Bits())
t.Fatalf("unexpected result: %v", result[0].(*pilosa.Row).Bits())
}
})
t.Run("LT", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo < 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{SliceWidth + 2}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{SliceWidth + 2}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -892,7 +892,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("LTE", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo <= 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{50, SliceWidth + 2, (5 * SliceWidth) + 100}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{50, SliceWidth + 2, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -900,7 +900,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("GT", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo > 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{SliceWidth, SliceWidth + 1}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -908,7 +908,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("GTE", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo >= 20)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{50, SliceWidth, SliceWidth + 1, (5 * SliceWidth) + 100}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{50, SliceWidth, SliceWidth + 1, (5 * SliceWidth) + 100}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -916,7 +916,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("BETWEEN", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo >< [1, 1000])`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -925,7 +925,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("FieldNotNull", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo >< [0, 1000])`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -933,7 +933,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("BelowMin", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 0)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -941,7 +941,7 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("AboveMax", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo == 200)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Bitmap).Bits()) {
} else if !reflect.DeepEqual([]uint64{}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result))
}
})
@ -949,16 +949,16 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
t.Run("LTAboveMax", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, foo < 200)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Bitmap).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Bitmap).Bits()))
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Row).Bits()))
}
})
t.Run("GTBelowMin", func(t *testing.T) {
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=edge, foo > -200)`), nil, nil); err != nil {
t.Fatal(err)
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Bitmap).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Bitmap).Bits()))
} else if !reflect.DeepEqual([]uint64{0, 1}, result[0].(*pilosa.Row).Bits()) {
t.Fatalf("unexpected result: %s", spew.Sdump(result[0].(*pilosa.Row).Bits()))
}
})
@ -1018,7 +1018,7 @@ func TestExecutor_Execute_Remote_Bitmap(t *testing.T) {
e := test.NewExecutor(hldr.Holder, c)
if res, err := e.Execute(context.Background(), "i", test.MustParse(`Bitmap(row=10, frame=f)`), nil, nil); err != nil {
t.Fatal(err)
} else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{1, 2, 2*SliceWidth + 4}) {
} else if bits := res[0].(*pilosa.Row).Bits(); !reflect.DeepEqual(bits, []uint64{1, 2, 2*SliceWidth + 4}) {
t.Fatalf("unexpected bits: %+v", bits)
}
}

View file

@ -239,7 +239,7 @@ func (f *Fragment) openStorage() error {
// Attach the file to the bitmap to act as a write-ahead log.
f.storage.OpWriter = f.file
f.rowCache = &SimpleCache{make(map[uint64]*Bitmap)}
f.rowCache = &SimpleCache{make(map[uint64]*Row)}
return nil
@ -343,13 +343,13 @@ func (f *Fragment) closeStorage() error {
}
// Row returns a row by ID.
func (f *Fragment) Row(rowID uint64) *Bitmap {
func (f *Fragment) Row(rowID uint64) *Row {
f.mu.Lock()
defer f.mu.Unlock()
return f.row(rowID, true, true)
}
func (f *Fragment) row(rowID uint64, checkRowCache bool, updateRowCache bool) *Bitmap {
func (f *Fragment) row(rowID uint64, checkRowCache bool, updateRowCache bool) *Row {
if checkRowCache {
r, ok := f.rowCache.Fetch(rowID)
if ok && r != nil {
@ -364,7 +364,7 @@ func (f *Fragment) row(rowID uint64, checkRowCache bool, updateRowCache bool) *B
// Reference bitmap subrange in storage.
// We Clone() data because otherwise bm will contains pointers to containers in storage.
// This causes unexpected results when we cache the row and try to use it later.
bm := &Bitmap{
bm := &Row{
segments: []BitmapSegment{{
data: *data.Clone(),
slice: f.slice,
@ -584,7 +584,7 @@ func (f *Fragment) importSetFieldValue(columnID uint64, bitDepth uint, value uin
// FieldSum returns the sum of a given field as well as the number of columns involved.
// A bitmap can be passed in to optionally filter the computed columns.
func (f *Fragment) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, err error) {
func (f *Fragment) FieldSum(filter *Row, bitDepth uint) (sum, count uint64, err error) {
// Compute count based on the existence bit.
row := f.Row(uint64(bitDepth))
if filter != nil {
@ -616,7 +616,7 @@ func (f *Fragment) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, e
// FieldMin returns the min of a given field as well as the number of columns involved.
// A bitmap can be passed in to optionally filter the computed columns.
func (f *Fragment) FieldMin(filter *Bitmap, bitDepth uint) (min, count uint64, err error) {
func (f *Fragment) FieldMin(filter *Row, bitDepth uint) (min, count uint64, err error) {
consider := f.Row(uint64(bitDepth))
if filter != nil {
@ -649,7 +649,7 @@ func (f *Fragment) FieldMin(filter *Bitmap, bitDepth uint) (min, count uint64, e
// FieldMax returns the max of a given field as well as the number of columns involved.
// A bitmap can be passed in to optionally filter the computed columns.
func (f *Fragment) FieldMax(filter *Bitmap, bitDepth uint) (max, count uint64, err error) {
func (f *Fragment) FieldMax(filter *Row, bitDepth uint) (max, count uint64, err error) {
consider := f.Row(uint64(bitDepth))
if filter != nil {
@ -679,7 +679,7 @@ func (f *Fragment) FieldMax(filter *Bitmap, bitDepth uint) (max, count uint64, e
}
// FieldRange returns bitmaps with a field value encoding matching the predicate.
func (f *Fragment) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Bitmap, error) {
func (f *Fragment) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Row, error) {
switch op {
case pql.EQ:
return f.fieldRangeEQ(bitDepth, predicate)
@ -694,7 +694,7 @@ func (f *Fragment) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*B
}
}
func (f *Fragment) fieldRangeEQ(bitDepth uint, predicate uint64) (*Bitmap, error) {
func (f *Fragment) fieldRangeEQ(bitDepth uint, predicate uint64) (*Row, error) {
// Start with set of columns with values set.
b := f.Row(uint64(bitDepth))
@ -713,7 +713,7 @@ func (f *Fragment) fieldRangeEQ(bitDepth uint, predicate uint64) (*Bitmap, error
return b, nil
}
func (f *Fragment) fieldRangeNEQ(bitDepth uint, predicate uint64) (*Bitmap, error) {
func (f *Fragment) fieldRangeNEQ(bitDepth uint, predicate uint64) (*Row, error) {
// Start with set of columns with values set.
b := f.Row(uint64(bitDepth))
@ -729,7 +729,7 @@ func (f *Fragment) fieldRangeNEQ(bitDepth uint, predicate uint64) (*Bitmap, erro
return b, nil
}
func (f *Fragment) fieldRangeLT(bitDepth uint, predicate uint64, allowEquality bool) (*Bitmap, error) {
func (f *Fragment) fieldRangeLT(bitDepth uint, predicate uint64, allowEquality bool) (*Row, error) {
keep := NewBitmap()
// Start with set of columns with values set.
@ -777,7 +777,7 @@ func (f *Fragment) fieldRangeLT(bitDepth uint, predicate uint64, allowEquality b
return b, nil
}
func (f *Fragment) fieldRangeGT(bitDepth uint, predicate uint64, allowEquality bool) (*Bitmap, error) {
func (f *Fragment) fieldRangeGT(bitDepth uint, predicate uint64, allowEquality bool) (*Row, error) {
b := f.Row(uint64(bitDepth))
keep := NewBitmap()
@ -813,12 +813,12 @@ func (f *Fragment) fieldRangeGT(bitDepth uint, predicate uint64, allowEquality b
}
// FieldNotNull returns the not-null row (stored at bitDepth).
func (f *Fragment) FieldNotNull(bitDepth uint) (*Bitmap, error) {
func (f *Fragment) FieldNotNull(bitDepth uint) (*Row, error) {
return f.Row(uint64(bitDepth)), nil
}
// FieldRangeBetween returns bitmaps with a field value encoding matching any value between predicateMin and predicateMax.
func (f *Fragment) FieldRangeBetween(bitDepth uint, predicateMin, predicateMax uint64) (*Bitmap, error) {
func (f *Fragment) FieldRangeBetween(bitDepth uint, predicateMin, predicateMax uint64) (*Row, error) {
b := f.Row(uint64(bitDepth))
keep1 := NewBitmap() // GTE
keep2 := NewBitmap() // LTE
@ -1067,7 +1067,7 @@ type TopOptions struct {
N int
// Bitmap to intersect with.
Src *Bitmap
Src *Row
// Specific rows to filter against.
RowIDs []uint64

View file

@ -284,7 +284,7 @@ func TestFragment_FieldMinMax(t *testing.T) {
t.Run("Min", func(t *testing.T) {
tests := []struct {
filter *pilosa.Bitmap
filter *pilosa.Row
exp uint64
cnt uint64
}{
@ -308,7 +308,7 @@ func TestFragment_FieldMinMax(t *testing.T) {
t.Run("Max", func(t *testing.T) {
tests := []struct {
filter *pilosa.Bitmap
filter *pilosa.Row
exp uint64
cnt uint64
}{

View file

@ -719,7 +719,7 @@ func (f *Frame) SetFieldValue(columnID uint64, name string, value int64) (change
// FieldSum returns the sum and count for a field.
// An optional filtering bitmap can be provided.
func (f *Frame) FieldSum(filter *Bitmap, name string) (sum, count int64, err error) {
func (f *Frame) FieldSum(filter *Row, name string) (sum, count int64, err error) {
field := f.Field(name)
if field == nil {
return 0, 0, ErrFieldNotFound
@ -739,7 +739,7 @@ func (f *Frame) FieldSum(filter *Bitmap, name string) (sum, count int64, err err
// FieldMin returns the min for a field.
// An optional filtering bitmap can be provided.
func (f *Frame) FieldMin(filter *Bitmap, name string) (min, count int64, err error) {
func (f *Frame) FieldMin(filter *Row, name string) (min, count int64, err error) {
field := f.Field(name)
if field == nil {
return 0, 0, ErrFieldNotFound
@ -759,7 +759,7 @@ func (f *Frame) FieldMin(filter *Bitmap, name string) (min, count int64, err err
// FieldMax returns the max for a field.
// An optional filtering bitmap can be provided.
func (f *Frame) FieldMax(filter *Bitmap, name string) (max, count int64, err error) {
func (f *Frame) FieldMax(filter *Row, name string) (max, count int64, err error) {
field := f.Field(name)
if field == nil {
return 0, 0, ErrFieldNotFound
@ -777,7 +777,7 @@ func (f *Frame) FieldMax(filter *Bitmap, name string) (max, count int64, err err
return int64(vmax) + field.Min, int64(vcount), nil
}
func (f *Frame) FieldRange(name string, op pql.Token, predicate int64) (*Bitmap, error) {
func (f *Frame) FieldRange(name string, op pql.Token, predicate int64) (*Row, error) {
// Retrieve and validate field.
field := f.Field(name)
if field == nil {
@ -800,7 +800,7 @@ func (f *Frame) FieldRange(name string, op pql.Token, predicate int64) (*Bitmap,
return view.FieldRange(op, field.BitDepth(), baseValue)
}
func (f *Frame) FieldRangeBetween(name string, predicateMin, predicateMax int64) (*Bitmap, error) {
func (f *Frame) FieldRangeBetween(name string, predicateMin, predicateMax int64) (*Row, error) {
// Retrieve and validate field.
field := f.Field(name)
if field == nil {

View file

@ -1243,7 +1243,7 @@ func encodeQueryResponse(resp *QueryResponse) *internal.QueryResponse {
pb.Results[i] = &internal.QueryResult{}
switch result := resp.Results[i].(type) {
case *Bitmap:
case *Row:
pb.Results[i].Type = QueryResultTypeBitmap
pb.Results[i].Bitmap = encodeBitmap(result)
case []Pair:

10
view.go
View file

@ -346,7 +346,7 @@ func (v *View) SetFieldValue(columnID uint64, bitDepth uint, value uint64) (chan
}
// FieldSum returns the sum & count of a field.
func (v *View) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, err error) {
func (v *View) FieldSum(filter *Row, bitDepth uint) (sum, count uint64, err error) {
for _, f := range v.Fragments() {
fsum, fcount, err := f.FieldSum(filter, bitDepth)
if err != nil {
@ -359,7 +359,7 @@ func (v *View) FieldSum(filter *Bitmap, bitDepth uint) (sum, count uint64, err e
}
// FieldMin returns the min and count of a field.
func (v *View) FieldMin(filter *Bitmap, bitDepth uint) (min, count uint64, err error) {
func (v *View) FieldMin(filter *Row, bitDepth uint) (min, count uint64, err error) {
var minHasValue bool
for _, f := range v.Fragments() {
fmin, fcount, err := f.FieldMin(filter, bitDepth)
@ -387,7 +387,7 @@ func (v *View) FieldMin(filter *Bitmap, bitDepth uint) (min, count uint64, err e
}
// FieldMax returns the max and count of a field.
func (v *View) FieldMax(filter *Bitmap, bitDepth uint) (max, count uint64, err error) {
func (v *View) FieldMax(filter *Row, bitDepth uint) (max, count uint64, err error) {
for _, f := range v.Fragments() {
fmax, fcount, err := f.FieldMax(filter, bitDepth)
if err != nil {
@ -402,7 +402,7 @@ func (v *View) FieldMax(filter *Bitmap, bitDepth uint) (max, count uint64, err e
}
// FieldRange returns bitmaps with a field value encoding matching the predicate.
func (v *View) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Bitmap, error) {
func (v *View) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Row, error) {
bm := NewBitmap()
for _, frag := range v.Fragments() {
other, err := frag.FieldRange(op, bitDepth, predicate)
@ -416,7 +416,7 @@ func (v *View) FieldRange(op pql.Token, bitDepth uint, predicate uint64) (*Bitma
// FieldRangeBetween returns bitmaps with a field value encoding matching any
// value between predicateMin and predicateMax.
func (v *View) FieldRangeBetween(bitDepth uint, predicateMin, predicateMax uint64) (*Bitmap, error) {
func (v *View) FieldRangeBetween(bitDepth uint, predicateMin, predicateMax uint64) (*Row, error) {
bm := NewBitmap()
for _, frag := range v.Fragments() {
other, err := frag.FieldRangeBetween(bitDepth, predicateMin, predicateMax)