Skip to content

Commit

Permalink
Add roaring64_bitmap_range_closed_cardinality
Browse files Browse the repository at this point in the history
The implementation was actually already written using an inclusive range
already.

See #549
  • Loading branch information
Dr-Emann committed May 23, 2024
1 parent 82f885a commit 2a9fafc
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
6 changes: 6 additions & 0 deletions include/roaring/roaring64.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ uint64_t roaring64_bitmap_get_cardinality(const roaring64_bitmap_t *r);
uint64_t roaring64_bitmap_range_cardinality(const roaring64_bitmap_t *r,
uint64_t min, uint64_t max);

/**
* Returns the number of elements in the range [min, max]
*/
uint64_t roaring64_bitmap_range_closed_cardinality(const roaring64_bitmap_t *r,
uint64_t min, uint64_t max);

/**
* Returns true if the bitmap is empty (cardinality is zero).
*/
Expand Down
12 changes: 11 additions & 1 deletion src/roaring64.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,17 @@ uint64_t roaring64_bitmap_range_cardinality(const roaring64_bitmap_t *r,
if (min >= max) {
return 0;
}
max--; // A closed range is easier to work with.
// Convert to a closed range
// No underflow here: passing the above condition implies min < max, so
// there is a number less than max
return roaring64_bitmap_range_closed_cardinality(r, min, max - 1);
}

uint64_t roaring64_bitmap_range_closed_cardinality(const roaring64_bitmap_t *r,
uint64_t min, uint64_t max) {
if (min > max) {
return 0;
}

uint64_t cardinality = 0;
uint8_t min_high48[ART_KEY_BYTES];
Expand Down
23 changes: 23 additions & 0 deletions tests/roaring64_unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,29 @@ DEFINE_TEST(test_range_cardinality) {
// range is exclusive, so UINT64_MAX is not included
assert_int_equal(
roaring64_bitmap_range_cardinality(r, start, UINT64_MAX), 4);
// With an inclusive range, UINT64_MAX _is_ included
assert_int_equal(
roaring64_bitmap_range_closed_cardinality(r, start, UINT64_MAX), 5);

roaring64_bitmap_free(r);
}
{
// Empty ranges always have zero cardinality
roaring64_bitmap_t* r =
roaring64_bitmap_from(0, 1, 2, 3, 4, 5, UINT64_MAX);

assert_int_equal(roaring64_bitmap_range_cardinality(r, 1, 1), 0);
assert_int_equal(roaring64_bitmap_range_cardinality(r, 1, 0), 0);
assert_int_equal(roaring64_bitmap_range_cardinality(r, UINT64_MAX, 0),
0);
assert_int_equal(
roaring64_bitmap_range_cardinality(r, UINT64_MAX, UINT64_MAX), 0);
assert_int_equal(roaring64_bitmap_range_closed_cardinality(r, 1, 0), 0);
assert_int_equal(
roaring64_bitmap_range_closed_cardinality(r, UINT64_MAX, 0), 0);
assert_int_equal(roaring64_bitmap_range_closed_cardinality(
r, UINT64_MAX, UINT64_MAX - 1),
0);

roaring64_bitmap_free(r);
}
Expand Down

0 comments on commit 2a9fafc

Please sign in to comment.