From 2322201bf4a81ccc9b80d101b793a2d95217533d Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Thu, 13 Oct 2016 10:54:40 -0600 Subject: [PATCH] Add slice to BitmapSegment operations. Previously the `slice` was not copied to each new segment when `Intersect()`, `Union()`, and `Difference()` operations were performed. This causes issues when those bitmaps were then operated on later such as performing a `TopN()` on a source bitmap. --- bitmap.go | 36 +++++++++++++++++++----------------- cache.go | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/bitmap.go b/bitmap.go index ee2b4421c..601e1e8b2 100644 --- a/bitmap.go +++ b/bitmap.go @@ -266,8 +266,9 @@ func (s *BitmapSegment) Intersect(other *BitmapSegment) *BitmapSegment { data := s.data.Intersect(&other.data) return &BitmapSegment{ - data: *data, - n: data.Count(), + data: *data, + slice: s.slice, + n: data.Count(), } } @@ -276,8 +277,9 @@ func (s *BitmapSegment) Union(other *BitmapSegment) *BitmapSegment { data := s.data.Union(&other.data) return &BitmapSegment{ - data: *data, - n: data.Count(), + data: *data, + slice: s.slice, + n: data.Count(), } } @@ -286,8 +288,9 @@ func (s *BitmapSegment) Difference(other *BitmapSegment) *BitmapSegment { data := s.data.Difference(&other.data) return &BitmapSegment{ - data: *data, - n: data.Count(), + data: *data, + slice: s.slice, + n: data.Count(), } } @@ -344,7 +347,6 @@ func (s *BitmapSegment) ensureWritable() { // mergeSegmentIterator produces an iterator that loops through two sets of segments. type mergeSegmentIterator struct { a0, a1 []BitmapSegment - i0, i1 int } // newMergeSegmentIterator returns a new instance of mergeSegmentIterator. @@ -355,34 +357,34 @@ func newMergeSegmentIterator(a0, a1 []BitmapSegment) mergeSegmentIterator { // next returns the next set of segments. func (itr *mergeSegmentIterator) next() (s0, s1 *BitmapSegment) { // Find current segments. - if itr.i0 < len(itr.a0) { - s0 = &itr.a0[itr.i0] + if len(itr.a0) > 0 { + s0 = &itr.a0[0] } - if itr.i1 < len(itr.a1) { - s1 = &itr.a1[itr.i1] + if len(itr.a1) > 0 { + s1 = &itr.a1[0] } // Return if either or both are nil. if s0 == nil && s1 == nil { return } else if s0 == nil { - itr.i1++ + itr.a1 = itr.a1[1:] return } else if s1 == nil { - itr.i0++ + itr.a0 = itr.a0[1:] return } // Otherwise determine which is first. if s0.slice < s1.slice { - itr.i0++ + itr.a0 = itr.a0[1:] return s0, nil } else if s0.slice > s1.slice { - itr.i1++ + itr.a1 = itr.a1[1:] return s1, nil } // Return both if slices are equal. - itr.i0, itr.i1 = itr.i0+1, itr.i1+1 - return + itr.a0, itr.a1 = itr.a0[1:], itr.a1[1:] + return s0, s1 } diff --git a/cache.go b/cache.go index 2ff5f60ce..803aac078 100644 --- a/cache.go +++ b/cache.go @@ -1,6 +1,8 @@ package pilosa import ( + "bytes" + "fmt" "io" "sort" "time" @@ -262,6 +264,19 @@ func (p Pairs) Keys() []uint64 { return a } +func (p Pairs) String() string { + var buf bytes.Buffer + buf.WriteString("Pairs(") + for i := range p { + fmt.Fprintf(&buf, "%d/%d", p[i].Key, p[i].Count) + if i < len(p)-1 { + buf.WriteString(", ") + } + } + buf.WriteString(")") + return buf.String() +} + func encodePairs(a Pairs) []*internal.Pair { other := make([]*internal.Pair, len(a)) for i := range a {