Skip to content

Commit 8792d39

Browse files
committed
feat: implement roaring64_bitmap_remove_run_compression
1 parent 4c21998 commit 8792d39

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

include/roaring/roaring64.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ uint64_t roaring64_bitmap_minimum(const roaring64_bitmap_t *r);
310310
*/
311311
uint64_t roaring64_bitmap_maximum(const roaring64_bitmap_t *r);
312312

313+
/**
314+
* Remove run-length encoding even when it is more space efficient.
315+
* Return whether a change was applied.
316+
*/
317+
bool roaring64_bitmap_remove_run_compression(roaring64_bitmap_t *r);
318+
313319
/**
314320
* Returns true if the result has at least one run container.
315321
*/

src/roaring64.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,26 @@ uint64_t roaring64_bitmap_maximum(const roaring64_bitmap_t *r) {
941941
it.key, container_maximum(get_container(r, leaf), get_typecode(leaf)));
942942
}
943943

944+
bool roaring64_bitmap_remove_run_compression(roaring64_bitmap_t *r) {
945+
art_iterator_t it = art_init_iterator(&r->art, /*first=*/true);
946+
bool removed = false;
947+
while (it.value != NULL) {
948+
leaf_t *leaf = (leaf_t *)it.value;
949+
if (get_typecode(*leaf) == RUN_CONTAINER_TYPE) {
950+
run_container_t *run = CAST_run(get_container(r, *leaf));
951+
int32_t card = run_container_cardinality(run);
952+
uint8_t new_typecode;
953+
container_t *new_container =
954+
convert_to_bitset_or_array_container(run, card, &new_typecode);
955+
run_container_free(run);
956+
replace_container(r, leaf, new_container, new_typecode);
957+
removed = true;
958+
}
959+
art_iterator_next(&it);
960+
}
961+
return removed;
962+
}
963+
944964
bool roaring64_bitmap_run_optimize(roaring64_bitmap_t *r) {
945965
art_iterator_t it = art_init_iterator(&r->art, /*first=*/true);
946966
bool has_run_container = false;

tests/roaring64_unit.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,27 @@ DEFINE_TEST(test_maximum) {
931931
roaring64_bitmap_free(r);
932932
}
933933

934+
DEFINE_TEST(test_remove_run_compression) {
935+
roaring64_bitmap_t* r = roaring64_bitmap_create();
936+
937+
for (uint64_t i = 0; i < 30000; ++i) {
938+
roaring64_bitmap_add(r, i);
939+
}
940+
assert_true(roaring64_bitmap_run_optimize(r));
941+
assert_r64_valid(r);
942+
943+
assert_true(roaring64_bitmap_remove_run_compression(r));
944+
assert_r64_valid(r);
945+
946+
assert_false(roaring64_bitmap_remove_run_compression(r));
947+
assert_r64_valid(r);
948+
949+
assert_true(roaring64_bitmap_run_optimize(r));
950+
assert_r64_valid(r);
951+
952+
roaring64_bitmap_free(r);
953+
}
954+
934955
DEFINE_TEST(test_run_optimize) {
935956
roaring64_bitmap_t* r = roaring64_bitmap_create();
936957

@@ -2078,6 +2099,7 @@ int main() {
20782099
cmocka_unit_test(test_is_empty),
20792100
cmocka_unit_test(test_minimum),
20802101
cmocka_unit_test(test_maximum),
2102+
cmocka_unit_test(test_remove_run_compression),
20812103
cmocka_unit_test(test_run_optimize),
20822104
cmocka_unit_test(test_equals),
20832105
cmocka_unit_test(test_is_subset),

0 commit comments

Comments
 (0)