diff --git a/roaring/roaring.go b/roaring/roaring.go index 2de26d812..3d666056d 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -1340,9 +1340,9 @@ func (c *container) bitmapContains(v uint32) bool { return (c.bitmap[v/64] & (1 << uint64(v%64))) != 0 } -//runBinSearch uses a binary search of the runs and returns the index of nearest -//run. -func binSearchRuns(v uint32, a []interval32) (int, bool) { +// runBinSearch returns the index of the run containing v, and true, when v is contained; +// or the index of the next run starting after v, and false, when v is not contained. +func runBinSearch(v uint32, a []interval32) (int, bool) { i := sort.Search(len(a), func(i int) bool { return a[i].last >= v }) if i < len(a) { diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 400f99b66..0c4bf8e0d 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -1692,3 +1692,67 @@ func TestRunBinSearchContains(t *testing.T) { } } } + +func TestRunBinSearch(t *testing.T) { + tests := []struct { + runs []interval32 + search uint32 + exp bool + expi int + }{ + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 1, + exp: false, + expi: 0, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 2, + exp: true, + expi: 0, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 5, + exp: true, + expi: 0, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 10, + exp: true, + expi: 0, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 20, + exp: false, + expi: 1, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 55, + exp: true, + expi: 1, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 70, + exp: false, + expi: 2, + }, + { + runs: []interval32{{2, 10}, {50, 60}, {80, 90}}, + search: 100, + exp: false, + expi: 3, + }, + } + for i, test := range tests { + idx, contains := runBinSearch(test.search, test.runs) + if !(test.exp == contains && test.expi == idx) { + t.Fatalf("test #%v expected (%v, %v) but got (%v, %v)", i, test.exp, test.expi, contains, idx) + } + } +}