snapshot of https://github.com/blevesearch/bleve.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-15 22:27:16 +05:00
commit f8d3d9f0cf
797 changed files with 159570 additions and 0 deletions

205
util/bitset_test.go Normal file
View File

@@ -0,0 +1,205 @@
// Copyright (c) 2026 Couchbase, Inc.
//
// 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 util
import (
"reflect"
"testing"
"github.com/RoaringBitmap/roaring/v2"
)
func TestBitsetAddContains(t *testing.T) {
b := NewBitset(100, nil)
// values not yet added must not be present
for _, v := range []int{0, 1, 63, 64, 65, 100} {
if b.Contains(v) {
t.Fatalf("expected %d to be absent from an empty bitset", v)
}
}
// exercise word boundaries explicitly: 63 is the last bit of word 0,
// 64 is the first bit of word 1, 65 the second
added := []int{0, 1, 63, 64, 65, 100}
for _, v := range added {
b.Add(v)
}
for _, v := range added {
if !b.Contains(v) {
t.Fatalf("expected %d to be present after Add", v)
}
}
// a value between two set bits must remain absent
if b.Contains(50) {
t.Fatalf("expected 50 to be absent")
}
}
func TestBitsetAddDuplicate(t *testing.T) {
b := NewBitset(100, nil)
b.Add(42)
b.Add(42)
if got := b.Count(); got != 1 {
t.Fatalf("expected duplicate Add to keep count at 1, got %d", got)
}
if !b.Contains(42) {
t.Fatalf("expected 42 to be present")
}
}
func TestBitsetRemove(t *testing.T) {
b := NewBitset(100, nil)
b.Add(10)
b.Add(64)
b.Remove(10)
if b.Contains(10) {
t.Fatalf("expected 10 to be absent after Remove")
}
if !b.Contains(64) {
t.Fatalf("expected 64 to still be present")
}
// removing an absent value must be a no-op
b.Remove(99)
if b.Count() != 1 {
t.Fatalf("expected count 1 after removing an absent value, got %d", b.Count())
}
}
func TestBitsetCountAndClear(t *testing.T) {
b := NewBitset(200, nil)
for _, v := range []int{0, 5, 63, 64, 128, 200} {
b.Add(v)
}
if got := b.Count(); got != 6 {
t.Fatalf("expected count 6, got %d", got)
}
b.Clear()
if got := b.Count(); got != 0 {
t.Fatalf("expected count 0 after Clear, got %d", got)
}
}
func TestBitsetIterateAscending(t *testing.T) {
b := NewBitset(200, nil)
// add out of order to confirm Iterate returns ascending order
for _, v := range []int{130, 0, 64, 63, 7} {
b.Add(v)
}
var got []int
b.Iterate(func(v int) {
got = append(got, v)
})
want := []int{0, 7, 63, 64, 130}
if !reflect.DeepEqual(got, want) {
t.Fatalf("expected Iterate to yield %v in ascending order, got %v", want, got)
}
}
func TestBitsetExcludeBlocksAdd(t *testing.T) {
exclude := roaring.New()
exclude.AddInt(5)
exclude.AddInt(70)
b := NewBitset(100, exclude)
b.Add(5) // excluded, must be ignored
b.Add(6) // allowed
b.Add(70) // excluded, must be ignored
if b.Contains(5) {
t.Fatalf("expected excluded value 5 to be blocked by Add")
}
if b.Contains(70) {
t.Fatalf("expected excluded value 70 to be blocked by Add")
}
if !b.Contains(6) {
t.Fatalf("expected non-excluded value 6 to be present")
}
}
func TestBitsetInvertRespectsNumBits(t *testing.T) {
// numDocs = 10 means the valid doc IDs are 0..9. NewBitset allocates a
// full 64-bit word, so bits 10..63 are unused and must never surface.
numDocs := 10
b := NewBitset(numDocs, nil)
b.Add(3)
b.Add(7)
b.Invert()
var got []int
b.Iterate(func(v int) {
got = append(got, v)
})
// after inverting, exactly the doc IDs in [0, 10) that were NOT set
// should be present - and nothing >= 10
want := []int{0, 1, 2, 4, 5, 6, 8, 9}
if !reflect.DeepEqual(got, want) {
t.Fatalf("expected inverted bitset to yield %v, got %v", want, got)
}
if got := b.Count(); got != len(want) {
t.Fatalf("expected inverted count %d, got %d", len(want), got)
}
}
func TestBitsetInvertWordBoundaries(t *testing.T) {
// exercise numBits at and around 64-bit word boundaries to make sure
// the trailing-bit mask is computed correctly
for _, numDocs := range []int{1, 63, 64, 65, 128, 129} {
b := NewBitset(numDocs, nil)
b.Invert()
max := -1
b.Iterate(func(v int) {
if v > max {
max = v
}
})
// every valid doc ID [0, numDocs) should be present after inverting
// an empty bitset, and none at or beyond numDocs
if got := b.Count(); got != numDocs {
t.Fatalf("numDocs=%d: expected inverted-empty count %d, got %d",
numDocs, numDocs, got)
}
if max >= numDocs {
t.Fatalf("numDocs=%d: Invert surfaced out-of-range value %d",
numDocs, max)
}
}
}
func TestBitsetInvertClearsExcluded(t *testing.T) {
// excluded docs must remain unset even after Invert, since they are
// never valid hits
exclude := roaring.New()
exclude.AddInt(2)
exclude.AddInt(8)
b := NewBitset(10, exclude)
b.Add(3)
b.Invert()
if b.Contains(2) || b.Contains(8) {
t.Fatalf("expected excluded docs to stay unset after Invert")
}
if b.Contains(3) {
t.Fatalf("expected the originally-set doc 3 to be cleared after Invert")
}
// a normal, non-excluded, originally-unset doc should now be set
if !b.Contains(0) {
t.Fatalf("expected doc 0 to be set after Invert")
}
}