Skip to content

Commit 6778b78

Browse files
committed
Add method remove_range
1 parent 5ba036b commit 6778b78

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

pyroaring/bitmap.pxi

+11
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,14 @@ cdef class BitMap(AbstractBitMap):
128128
BitMap([3, 10, 11, 13, 14])
129129
"""
130130
croaring.roaring_bitmap_flip_inplace(self._c_bitmap, start, end)
131+
132+
def remove_range(self, uint64_t range_start, uint64_t range_end):
133+
"""
134+
Remove a range of values from range_start (included) to range_end (excluded).
135+
136+
>>> bm = BitMap([5, 6, 7, 8, 9, 10])
137+
>>> bm.remove_range(6, 9)
138+
>>> bm
139+
BitMap([5, 9, 10])
140+
"""
141+
croaring.roaring_bitmap_remove_range(self._c_bitmap, range_start, range_end)

pyroaring/croaring.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ cdef extern from "roaring.h":
4040
void roaring_bitmap_add_many(roaring_bitmap_t *r, size_t n_args, const uint32_t *vals)
4141
void roaring_bitmap_add_range(roaring_bitmap_t *ra, uint64_t min, uint64_t max);
4242
void roaring_bitmap_remove(roaring_bitmap_t *r, uint32_t x)
43+
inline void roaring_bitmap_remove_range(roaring_bitmap_t *ra, uint64_t min, uint64_t max)
4344
bool roaring_bitmap_remove_checked(roaring_bitmap_t *r, uint32_t x)
4445
bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val)
4546
bool roaring_bitmap_contains_range(const roaring_bitmap_t *r, uint64_t range_start, uint64_t range_end)

test.py

+28
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ def test_intersect(self, cls1, cls2, values1, values2, cow):
395395
bm2 = cls2(values2, copy_on_write=cow)
396396
self.assertEqual(bm1.intersect(bm2), len(bm1 & bm2) > 0)
397397

398+
399+
class RangeTest(Util):
398400
@given(bitmap_cls, hyp_collection, st.booleans(), uint32, uint32)
399401
def test_contains_range_arbitrary(self, cls, values, cow, start, end):
400402
bm = cls(values)
@@ -422,6 +424,32 @@ def test_contains_range(self, cls, cow, start, end):
422424
self.assertTrue(bm.contains_range(start, middle))
423425
self.assertTrue(bm.contains_range(middle+1, end))
424426

427+
@given(hyp_collection, st.booleans(), uint32, uint32)
428+
def test_add_remove_range(self, values, cow, start, end):
429+
st.assume(start < end)
430+
bm = BitMap(values, copy_on_write=cow)
431+
# Empty range
432+
original = BitMap(bm)
433+
bm.update(range(end, start))
434+
self.assertEqual(bm, original)
435+
bm.remove_range(end, start)
436+
self.assertEqual(bm, original)
437+
# Adding the range
438+
bm.update(range(start, end))
439+
self.assertTrue(bm.contains_range(start, end))
440+
self.assertEqual(bm.intersection_cardinality(BitMap(range(start, end), copy_on_write=cow)),
441+
len(range(start, end)))
442+
# Empty range (again)
443+
original = BitMap(bm)
444+
bm.remove_range(end, start)
445+
self.assertEqual(bm, original)
446+
self.assertEqual(bm.intersection_cardinality(BitMap(range(start, end), copy_on_write=cow)),
447+
len(range(start, end)))
448+
# Removing the range
449+
bm.remove_range(start, end)
450+
self.assertFalse(bm.contains_range(start, end))
451+
self.assertEqual(bm.intersection_cardinality(BitMap(range(start, end), copy_on_write=cow)), 0)
452+
425453

426454
class CardinalityTest(Util):
427455

0 commit comments

Comments
 (0)