Skip to content

Commit d425bcd

Browse files
authored
Fix roaring64_bitmap_remove_many when removing a container (#751)
When we remove a container we need to reset the leaf in the context, as it is no longer valid.
1 parent 45c56a1 commit d425bcd

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

src/roaring64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ void roaring64_bitmap_remove_bulk(roaring64_bitmap_t *r,
757757
assert(erased);
758758
(void)erased;
759759
remove_container(r, leaf);
760+
context->leaf = NULL;
760761
}
761762
} else {
762763
// We're not positioned anywhere yet or the high bits of the key

tests/roaring64_unit.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -634,17 +634,47 @@ DEFINE_TEST(test_remove_bulk) {
634634
}
635635

636636
DEFINE_TEST(test_remove_many) {
637-
roaring64_bitmap_t* r = roaring64_bitmap_create();
638-
std::array<uint64_t, 1000> vals;
639-
std::iota(vals.begin(), vals.end(), 0);
637+
{
638+
// Remove all values until empty, across multiple containers.
639+
roaring64_bitmap_t* r = roaring64_bitmap_create();
640+
std::array<uint64_t, 1000> vals;
641+
std::iota(vals.begin(), vals.end(), 0);
640642

641-
roaring64_bitmap_add_many(r, vals.size(), vals.data());
642-
roaring64_bitmap_remove_many(r, vals.size(), vals.data());
643-
assert_r64_valid(r);
644-
for (uint64_t i = 0; i < 1000; ++i) {
645-
assert_false(roaring64_bitmap_contains(r, vals[i]));
643+
roaring64_bitmap_add_many(r, vals.size(), vals.data());
644+
roaring64_bitmap_remove_many(r, vals.size(), vals.data());
645+
assert_r64_valid(r);
646+
for (uint64_t i = 0; i < 1000; ++i) {
647+
assert_false(roaring64_bitmap_contains(r, vals[i]));
648+
}
649+
assert_true(roaring64_bitmap_is_empty(r));
650+
roaring64_bitmap_free(r);
651+
}
652+
{
653+
// Remove values not present.
654+
roaring64_bitmap_t* r = roaring64_bitmap_from(123, 124);
655+
std::array<uint64_t, 1> vals = {125};
656+
roaring64_bitmap_remove_many(r, 1, vals.data());
657+
assert_r64_valid(r);
658+
roaring64_bitmap_free(r);
659+
}
660+
{
661+
// Remove all values in a container.
662+
roaring64_bitmap_t* r = roaring64_bitmap_from(123, 124);
663+
std::array<uint64_t, 3> vals = {123, 124, 125};
664+
roaring64_bitmap_remove_many(r, 3, vals.data());
665+
assert_true(roaring64_bitmap_is_empty(r));
666+
assert_r64_valid(r);
667+
roaring64_bitmap_free(r);
668+
}
669+
{
670+
// Remove a value multiple times.
671+
roaring64_bitmap_t* r = roaring64_bitmap_from(123, 124);
672+
std::array<uint64_t, 3> vals = {123, 124, 124};
673+
roaring64_bitmap_remove_many(r, 3, vals.data());
674+
assert_true(roaring64_bitmap_is_empty(r));
675+
assert_r64_valid(r);
676+
roaring64_bitmap_free(r);
646677
}
647-
roaring64_bitmap_free(r);
648678
}
649679

650680
DEFINE_TEST(test_remove_many_issue_742) {

0 commit comments

Comments
 (0)