Skip to content

Commit 5b52afd

Browse files
committed
Upgrade.
1 parent cd4303b commit 5b52afd

File tree

5 files changed

+958
-208
lines changed

5 files changed

+958
-208
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ func main() {
6666
rb3 := gocroaring.New(1, 5)
6767
rb3.Or(rb1)
6868

69+
// prints 1, 3, 4, 5, 1000
70+
i := rb3.Iterator()
71+
for i.HasNext() {
72+
fmt.Println(i.Next())
73+
}
74+
fmt.Println()
75+
6976
fmt.Println(rb3.ToArray())
7077
fmt.Println(rb3)
7178

gocroaring.go

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ import "C"
1212
import (
1313
"bytes"
1414
"errors"
15-
"strconv"
1615
"runtime"
16+
"strconv"
17+
"unsafe"
1718
)
1819

19-
import "unsafe"
20-
2120
const CRoaringMajor = C.ROARING_VERSION_MAJOR
2221
const CRoaringMinor = C.ROARING_VERSION_MINOR
2322
const CRoaringRevision = C.ROARING_VERSION_REVISION
@@ -185,6 +184,53 @@ func (rb *Bitmap) SerializedSizeInBytes() int {
185184
return int(C.roaring_bitmap_portable_size_in_bytes(rb.cpointer))
186185
}
187186

187+
// IntIterable allows you to iterate over the values in a Bitmap
188+
type IntIterable interface {
189+
HasNext() bool
190+
Next() uint32
191+
}
192+
193+
type intIterator struct {
194+
pointertonext *C.roaring_uint32_iterator_t
195+
current uint32
196+
has_next bool
197+
}
198+
199+
// Iterator creates a new IntIterable to iterate over the integers contained in the bitmap, in sorted order
200+
func (rb *Bitmap) Iterator() IntIterable {
201+
return newIntIterator(rb)
202+
}
203+
204+
// HasNext returns true if there are more integers to iterate over
205+
func (ii *intIterator) HasNext() bool {
206+
return ii.has_next
207+
}
208+
209+
// Next returns the next integer
210+
func (ii *intIterator) Next() uint32 {
211+
answer := ii.current
212+
ii.has_next = bool(ii.pointertonext.has_value)
213+
ii.current = uint32(ii.pointertonext.current_value)
214+
C.roaring_advance_uint32_iterator(ii.pointertonext)
215+
return answer
216+
}
217+
218+
func freeIntIterator(a *intIterator) {
219+
C.roaring_free_uint32_iterator(a.pointertonext)
220+
}
221+
222+
func newIntIterator(a *Bitmap) *intIterator {
223+
p := new(intIterator)
224+
p.pointertonext = C.roaring_create_iterator(a.cpointer)
225+
p.has_next = bool(p.pointertonext.has_value)
226+
p.current = uint32(p.pointertonext.current_value)
227+
if p.has_next {
228+
C.roaring_advance_uint32_iterator(p.pointertonext)
229+
}
230+
runtime.SetFinalizer(p, freeIntIterator)
231+
return p
232+
}
233+
188234
// Write writes a serialized version of this bitmap to stream (you should have enough space)
189235
func (rb *Bitmap) Write(b []byte) error {
190236
if len(b) < rb.SerializedSizeInBytes() {
@@ -204,19 +250,19 @@ func (rb *Bitmap) ToArray() []uint32 {
204250

205251
// String creates a string representation of the Bitmap
206252
func (rb *Bitmap) String() string {
207-
arr := rb.ToArray() // todo: replace with an iterator
208-
var buffer bytes.Buffer
253+
arr := rb.ToArray() // todo: replace with an iterator
254+
var buffer bytes.Buffer
209255
start := []byte("{")
210256
buffer.Write(start)
211-
l := len(arr)
212-
for counter,i := range arr {
257+
l := len(arr)
258+
for counter, i := range arr {
213259
// to avoid exhausting the memory
214260
if counter > 0x40000 {
215261
buffer.WriteString("...")
216262
break
217263
}
218264
buffer.WriteString(strconv.FormatInt(int64(i), 10))
219-
if counter + 1 < l { // there is more
265+
if counter+1 < l { // there is more
220266
buffer.WriteString(",")
221267
}
222268
}

gocroaring_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
)
77

88
func TestDisplayVersion(t *testing.T) {
9-
fmt.Printf("CRoaring %v.%v.%v\n", CRoaringMajor, CRoaringMinor, CRoaringRevision)
9+
fmt.Printf("CRoaring %v.%v.%v\n", CRoaringMajor, CRoaringMinor, CRoaringRevision)
1010
}
1111

1212
// go test -run MemoryUsage
@@ -16,7 +16,7 @@ func TestMemoryUsage(t *testing.T) {
1616
bitmap.Add(uint32(i) * 10)
1717
}
1818
sb := bitmap.SerializedSizeInBytes()
19-
memoryAlloc := 8 * 1024 * 1024
19+
memoryAlloc := 8 * 1024 * 1024
2020
howmany := (memoryAlloc + sb - 1) / sb
2121
fmt.Println("size in kB of one bitmap ", sb/(1024), "; number of copies = ", howmany, "; total alloc: ", howmany*sb/(1024), "kB")
2222
for i := 0; i < howmany; i++ {
@@ -96,6 +96,12 @@ func TestFancier(t *testing.T) {
9696
fmt.Println(rb1)
9797
rb3.Add(5)
9898
rb3.Or(rb1)
99+
// prints 3, 4, 5, 1000
100+
i := rb3.Iterator()
101+
for i.HasNext() {
102+
fmt.Println(i.Next())
103+
}
104+
fmt.Println()
99105
fmt.Println(rb3.ToArray())
100106
fmt.Println(rb3)
101107
rb4 := FastOr(rb1, rb2, rb3)
@@ -112,8 +118,8 @@ func TestFancier(t *testing.T) {
112118
}
113119

114120
func TestString(t *testing.T) {
115-
ans := New(1,2,3).String()
116-
fmt.Println(ans)
121+
ans := New(1, 2, 3).String()
122+
fmt.Println(ans)
117123
if ans != "{1,2,3}" {
118124
t.Errorf("bad string ")
119125
}

0 commit comments

Comments
 (0)