Skip to content

Commit

Permalink
Merge pull request #434 from bearrito/chore/code-coverage
Browse files Browse the repository at this point in the history
Code Coverage: Set Util
  • Loading branch information
lemire committed Jun 17, 2024
2 parents 7b8e1c3 + 3588165 commit 5aca967
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 54 deletions.
1 change: 1 addition & 0 deletions bitmapcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ func (bcmi *bitmapContainerManyIterator) nextMany(hs uint32, buf []uint32) int {
return n
}

// nextMany64 returns the number of values added to the buffer
func (bcmi *bitmapContainerManyIterator) nextMany64(hs uint64, buf []uint64) int {
n := 0
base := bcmi.base
Expand Down
31 changes: 31 additions & 0 deletions bitmapcontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,34 @@ func TestBitMapContainerValidate(t *testing.T) {

assert.Error(t, bc.validate())
}

func TestBitmapcontainerNextHasMany(t *testing.T) {
t.Run("Empty Bitmap", func(t *testing.T) {
bc := newBitmapContainer()
iterator := newBitmapContainerManyIterator(bc)
high := uint64(1024)
buf := []uint64{}
result := iterator.nextMany64(high, buf)
assert.Equal(t, 0, result)
})

t.Run("512 in iterator and buf size 512", func(t *testing.T) {
bc := newBitmapContainer()
bc.iaddRange(0, 512)
iterator := newBitmapContainerManyIterator(bc)
high := uint64(1024)
buf := make([]uint64, 512)
result := iterator.nextMany64(high, buf)
assert.Equal(t, 512, result)
})

t.Run("512 in iterator and buf size 256", func(t *testing.T) {
bc := newBitmapContainer()
bc.iaddRange(0, 512)
iterator := newBitmapContainerManyIterator(bc)
high := uint64(1024)
buf := make([]uint64, 256)
result := iterator.nextMany64(high, buf)
assert.Equal(t, 256, result)
})
}
42 changes: 42 additions & 0 deletions manyiterator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package roaring

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestManyIterator(t *testing.T) {
type searchTest struct {
name string
iterator shortIterator
high uint64
buf []uint64
expectedValue int
}

tests := []searchTest{
{
"no values",
shortIterator{},
uint64(1024),
[]uint64{},
0,
},
{
"1 value ",
shortIterator{[]uint16{uint16(1)}, 0},
uint64(1024),
make([]uint64, 1),
1,
},
}

for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
iterator := testCase.iterator
result := iterator.nextMany64(testCase.high, testCase.buf)
assert.Equal(t, testCase.expectedValue, result)
})
}
}
98 changes: 44 additions & 54 deletions setutil.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
package roaring

func equal(a, b []uint16) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}

func difference(set1 []uint16, set2 []uint16, buffer []uint16) int {
if 0 == len(set2) {
if len(set2) == 0 {
buffer = buffer[:len(set1)]
for k := 0; k < len(set1); k++ {
buffer[k] = set1[k]
}
copy(buffer, set1)
return len(set1)
}
if 0 == len(set1) {
if len(set1) == 0 {
return 0
}
pos := 0
Expand Down Expand Up @@ -134,6 +120,7 @@ func exclusiveUnion2by2(set1 []uint16, set2 []uint16, buffer []uint16) int {
return pos
}

// union2by2Cardinality computes the cardinality of the union
func union2by2Cardinality(set1 []uint16, set2 []uint16) int {
pos := 0
k1 := 0
Expand Down Expand Up @@ -196,6 +183,7 @@ func intersection2by2(
}
}

// intersection2by2Cardinality computes the cardinality of the intersection
func intersection2by2Cardinality(
set1 []uint16,
set2 []uint16,
Expand All @@ -209,41 +197,42 @@ func intersection2by2Cardinality(
}
}

// intersects2by2 computes whether the two sets intersect
func intersects2by2(
set1 []uint16,
set2 []uint16,
) bool {
// could be optimized if one set is much larger than the other one
if (0 == len(set1)) || (0 == len(set2)) {
if (len(set1) == 0) || (len(set2) == 0) {
return false
}
k1 := 0
k2 := 0
s1 := set1[k1]
s2 := set2[k2]
index1 := 0
index2 := 0
value1 := set1[index1]
value2 := set2[index2]
mainwhile:
for {

if s2 < s1 {
if value2 < value1 {
for {
k2++
if k2 == len(set2) {
index2++
if index2 == len(set2) {
break mainwhile
}
s2 = set2[k2]
if s2 >= s1 {
value2 = set2[index2]
if value2 >= value1 {
break
}
}
}
if s1 < s2 {
if value1 < value2 {
for {
k1++
if k1 == len(set1) {
index1++
if index1 == len(set1) {
break mainwhile
}
s1 = set1[k1]
if s1 >= s2 {
value1 = set1[index1]
if value1 >= value2 {
break
}
}
Expand All @@ -260,7 +249,7 @@ func localintersect2by2(
set2 []uint16,
buffer []uint16,
) int {
if (0 == len(set1)) || (0 == len(set2)) {
if (len(set1) == 0) || (len(set2) == 0) {
return 0
}
k1 := 0
Expand Down Expand Up @@ -313,56 +302,57 @@ mainwhile:
return pos
}

// / localintersect2by2Cardinality computes the cardinality of the intersection
func localintersect2by2Cardinality(
set1 []uint16,
set2 []uint16,
) int {
if (0 == len(set1)) || (0 == len(set2)) {
if (len(set1) == 0) || (len(set2) == 0) {
return 0
}
k1 := 0
k2 := 0
index1 := 0
index2 := 0
pos := 0
s1 := set1[k1]
s2 := set2[k2]
value1 := set1[index1]
value2 := set2[index2]
mainwhile:
for {
if s2 < s1 {
if value2 < value1 {
for {
k2++
if k2 == len(set2) {
index2++
if index2 == len(set2) {
break mainwhile
}
s2 = set2[k2]
if s2 >= s1 {
value2 = set2[index2]
if value2 >= value1 {
break
}
}
}
if s1 < s2 {
if value1 < value2 {
for {
k1++
if k1 == len(set1) {
index1++
if index1 == len(set1) {
break mainwhile
}
s1 = set1[k1]
if s1 >= s2 {
value1 = set1[index1]
if value1 >= value2 {
break
}
}
} else {
// (set2[k2] == set1[k1])
pos++
k1++
if k1 == len(set1) {
index1++
if index1 == len(set1) {
break
}
s1 = set1[k1]
k2++
if k2 == len(set2) {
value1 = set1[index1]
index2++
if index2 == len(set2) {
break
}
s2 = set2[k2]
value2 = set2[index2]
}
}
return pos
Expand Down
Loading

0 comments on commit 5aca967

Please sign in to comment.