Skip to content

Commit 1d91ae5

Browse files
committed
making unset iterator 'closed'
1 parent e2c9e47 commit 1d91ae5

File tree

3 files changed

+48
-14
lines changed

3 files changed

+48
-14
lines changed

iter.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,31 @@ func Backward(b *Bitmap) func(func(uint32) bool) {
2828
}
2929
}
3030

31-
// Unset creates an iterator that yields values in the range [min, max] that are NOT contained in the bitmap.
31+
// UnsetClosed creates an iterator that yields values in the range [min, max] that are NOT contained in the bitmap.
3232
// The iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove).
33-
func Unset(b *Bitmap, min, max uint32) func(func(uint32) bool) {
33+
func UnsetClosed(b *Bitmap, min, max uint32) func(func(uint32) bool) {
3434
return func(yield func(uint32) bool) {
35-
it := b.UnsetIterator(min, max)
35+
it := b.UnsetIteratorClosed(min, max)
36+
for it.HasNext() {
37+
if !yield(it.Next()) {
38+
return
39+
}
40+
}
41+
}
42+
}
43+
44+
// Unset creates an iterator that yields values in the range [rangeStart, rangeEnd) that are NOT contained in the bitmap.
45+
// The iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove).
46+
func Unset(b *Bitmap, rangeStart, rangeEnd uint64) func(func(uint32) bool) {
47+
if rangeEnd > MaxUint32+1 {
48+
panic("rangeEnd > MaxUint32+1")
49+
}
50+
if rangeStart > MaxUint32+1 {
51+
panic("rangeStart > MaxUint32+1")
52+
}
53+
54+
return func(yield func(uint32) bool) {
55+
it := b.UnsetIterator(uint32(rangeStart), uint32(rangeEnd-1))
3656
for it.HasNext() {
3757
if !yield(it.Next()) {
3858
return

iter_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,13 @@ func TestUnset(t *testing.T) {
309309
})
310310
}
311311

312-
func TestUnsetIteratorPeekable(t *testing.T) {
312+
func TestUnsetIteratorClosedPeekable(t *testing.T) {
313313
t.Run("peek next", func(t *testing.T) {
314314
b := New()
315315
b.AddInt(5)
316316
b.AddInt(8)
317317

318-
it := b.UnsetIterator(3, 10)
318+
it := b.UnsetIteratorClosed(3, 10)
319319

320320
// First value should be 3
321321
assert.True(t, it.HasNext())
@@ -357,7 +357,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
357357
b.AddInt(8)
358358
b.AddInt(12)
359359

360-
it := b.UnsetIterator(1, 15)
360+
it := b.UnsetIteratorClosed(1, 15)
361361

362362
// Skip to values >= 7
363363
it.AdvanceIfNeeded(7)
@@ -394,7 +394,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
394394
b := New()
395395
b.AddInt(5)
396396

397-
it := b.UnsetIterator(10, 15)
397+
it := b.UnsetIteratorClosed(10, 15)
398398

399399
// Try to advance to a value before our range start
400400
it.AdvanceIfNeeded(5)
@@ -408,7 +408,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
408408
b := New()
409409
b.AddInt(5)
410410

411-
it := b.UnsetIterator(10, 15)
411+
it := b.UnsetIteratorClosed(10, 15)
412412

413413
// Advance beyond our range
414414
it.AdvanceIfNeeded(20)
@@ -420,7 +420,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
420420
t.Run("advance if needed on current value", func(t *testing.T) {
421421
b := New()
422422
b.AddRange(0, 0x10000)
423-
iter := b.UnsetIterator(0, 0x10002)
423+
iter := b.UnsetIteratorClosed(0, 0x10002)
424424
var got []uint32
425425
prev := uint32(0)
426426
for len(got) < 10 {
@@ -439,7 +439,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
439439
b := New()
440440
b.AddInt(5) // Set bit in middle of range
441441

442-
it := b.UnsetIterator(5, 5) // Range contains only the set bit
442+
it := b.UnsetIteratorClosed(5, 5) // Range contains only the set bit
443443

444444
// Should have no values
445445
assert.False(t, it.HasNext())
@@ -454,7 +454,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
454454
b := New()
455455
b.Add(4294967294) // Set the value before max
456456

457-
it := b.UnsetIterator(4294967294, 4294967295)
457+
it := b.UnsetIteratorClosed(4294967294, 4294967295)
458458

459459
// Should have 4294967295 (max uint32) as it's unset
460460
assert.True(t, it.HasNext())
@@ -469,7 +469,7 @@ func TestUnsetIteratorPeekable(t *testing.T) {
469469
b := New()
470470
b.Add(4294967295) // Set max uint32
471471

472-
it := b.UnsetIterator(4294967294, 4294967295)
472+
it := b.UnsetIteratorClosed(4294967294, 4294967295)
473473

474474
// Should have 4294967294 as it's unset, but not 4294967295
475475
assert.True(t, it.HasNext())

roaring.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,14 +915,28 @@ func (rb *Bitmap) ManyIterator() ManyIntIterable {
915915
return p
916916
}
917917

918-
// UnsetIterator creates a new IntPeekable to iterate over values in the range [min, max] that are NOT contained in the bitmap.
918+
// UnsetIteratorClosed creates a new IntPeekable to iterate over values in the range [min, max] that are NOT contained in the bitmap.
919919
// The iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove).
920-
func (rb *Bitmap) UnsetIterator(min, max uint32) IntPeekable {
920+
func (rb *Bitmap) UnsetIteratorClosed(min, max uint32) IntPeekable {
921921
p := new(unsetIterator)
922922
p.Initialize(rb, min, max)
923923
return p
924924
}
925925

926+
// UnsetIterator creates a new IntPeekable to iterate over values in the range [rangeStart, rangeEnd) that are NOT contained in the bitmap.
927+
// The iterator becomes invalid if the bitmap is modified (e.g., with Add or Remove).
928+
func (rb *Bitmap) UnsetIterator(rangeStart, rangeEnd uint64) IntPeekable {
929+
if rangeEnd > MaxUint32+1 {
930+
panic("rangeEnd > MaxUint32+1")
931+
}
932+
if rangeStart > MaxUint32+1 {
933+
panic("rangeStart > MaxUint32+1")
934+
}
935+
p := new(unsetIterator)
936+
p.Initialize(rb, uint32(rangeStart), uint32(rangeEnd-1))
937+
return p
938+
}
939+
926940
// Clone creates a copy of the Bitmap
927941
func (rb *Bitmap) Clone() *Bitmap {
928942
ptr := new(Bitmap)

0 commit comments

Comments
 (0)