compressedPostingList returns maxUInt32 at end of iteration
Added a test which picked up this corner case.
Change-Id: I776fb294b3aac5b812b9859da0d7b6c2485b732f
diff --git a/hititer.go b/hititer.go
index a4401ea..356c505 100644
--- a/hititer.go
+++ b/hititer.go
@@ -209,16 +209,15 @@
return
}
- if i._first <= limit && len(i.blob) == 0 {
- i._first = maxUInt32
- return
- }
-
for i._first <= limit && len(i.blob) > 0 {
delta, sz := binary.Uvarint(i.blob)
i._first += uint32(delta)
i.blob = i.blob[sz:]
}
+
+ if i._first <= limit && len(i.blob) == 0 {
+ i._first = maxUInt32
+ }
}
func (i *compressedPostingIterator) updateStats(s *Stats) {
diff --git a/hititer_test.go b/hititer_test.go
new file mode 100644
index 0000000..519a05e
--- /dev/null
+++ b/hititer_test.go
@@ -0,0 +1,57 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package zoekt
+
+import (
+ "reflect"
+ "sort"
+ "testing"
+ "testing/quick"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestCompressedPostingIterator_limit(t *testing.T) {
+ f := func(nums, limits []uint32) bool {
+ if len(nums) == 0 || len(limits) == 0 {
+ return true
+ }
+
+ nums = sortedUnique(nums)
+ sort.Slice(limits, func(i, j int) bool { return limits[i] < limits[j] })
+
+ want := doHitIterator(&inMemoryIterator{postings: nums}, limits)
+
+ it := newCompressedPostingIterator(toDeltas(nums), stringToNGram("abc"))
+ got := doHitIterator(it, limits)
+ if !reflect.DeepEqual(want, got) {
+ t.Log(cmp.Diff(want, got))
+ return false
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ t.Error(err)
+ }
+}
+
+func doHitIterator(it hitIterator, limits []uint32) []uint32 {
+ var nums []uint32
+ for _, limit := range limits {
+ it.next(limit)
+ nums = append(nums, it.first())
+ }
+ return nums
+}