diff --git a/roaring.go b/roaring.go index c7a91f16..2d689768 100644 --- a/roaring.go +++ b/roaring.go @@ -1935,13 +1935,14 @@ func (rb *Bitmap) PreviousValue(target uint32) int64 { } if rb.highlowcontainer.getKeyAtIndex(containerIndex) > originalKey { - return -1 + // target absent, key of first container after target too high + containerIndex-- } for containerIndex != -1 && prevValue == -1 { containerKey := rb.highlowcontainer.getKeyAtIndex(containerIndex) container := rb.highlowcontainer.getContainer(containerKey) - // if containerKey > orginalKey then we are past the container which mapped to the orignal key + // if containerKey > originalKey then we are past the container which mapped to the original key // in that case we can just return the minimum from that container var responseBit int if containerKey < originalKey { diff --git a/roaring_test.go b/roaring_test.go index 44d1da6d..859bb0e8 100644 --- a/roaring_test.go +++ b/roaring_test.go @@ -2973,6 +2973,17 @@ func TestNextAndPreviousValue(t *testing.T) { } }) + t.Run("Absent target container", func(t *testing.T) { + bmp := BitmapOf(2, 3, 131072, MaxUint32) + + assert.Equal(t, int64(3), bmp.PreviousValue(65536)) + assert.Equal(t, int64(131072), bmp.PreviousValue(MaxUint32>>1)) + assert.Equal(t, int64(131072), bmp.PreviousValue(MaxUint32-131071)) + + bmp = BitmapOf(131072) + assert.Equal(t, int64(-1), bmp.PreviousValue(65536)) + }) + t.Run("skipping with ranges", func(t *testing.T) { bmp := New() intervalEnd := 512