Skip to content

Commit ff13598

Browse files
committed
Version v4.2.0 (with test fix)
1 parent 61df09d commit ff13598

File tree

4 files changed

+120
-35
lines changed

4 files changed

+120
-35
lines changed

pyroaring/croaring_version.pxi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__croaring_version__ = "v4.1.5"
1+
__croaring_version__ = "v4.2.0"

pyroaring/roaring.c

Lines changed: 72 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// !!! DO NOT EDIT - THIS IS AN AUTO-GENERATED FILE !!!
2-
// Created by amalgamation.sh on 2024-09-19T23:52:46Z
2+
// Created by amalgamation.sh on 2024-09-30T21:45:33Z
33

44
/*
55
* The CRoaring project is under a dual license (Apache/MIT).
@@ -11215,14 +11215,23 @@ bool bitset_inplace_union(bitset_t *CROARING_CBITSET_RESTRICT b1,
1121511215
return true;
1121611216
}
1121711217

11218+
bool bitset_empty(const bitset_t *bitset) {
11219+
for (size_t k = 0; k < bitset->arraysize; k++) {
11220+
if (bitset->array[k] != 0) {
11221+
return false;
11222+
}
11223+
}
11224+
return true;
11225+
}
11226+
1121811227
size_t bitset_minimum(const bitset_t *bitset) {
1121911228
for (size_t k = 0; k < bitset->arraysize; k++) {
1122011229
uint64_t w = bitset->array[k];
1122111230
if (w != 0) {
1122211231
return roaring_trailing_zeroes(w) + k * 64;
1122311232
}
1122411233
}
11225-
return 0;
11234+
return SIZE_MAX;
1122611235
}
1122711236

1122811237
bool bitset_grow(bitset_t *bitset, size_t newarraysize) {
@@ -19319,6 +19328,7 @@ void roaring_aligned_free(void* p) { global_memory_hook.aligned_free(p); }
1931919328
/* begin file src/roaring.c */
1932019329
#include <assert.h>
1932119330
#include <inttypes.h>
19331+
#include <limits.h>
1932219332
#include <stdarg.h>
1932319333
#include <stdint.h>
1932419334
#include <stdio.h>
@@ -20644,15 +20654,22 @@ uint64_t roaring_bitmap_get_cardinality(const roaring_bitmap_t *r) {
2064420654
uint64_t roaring_bitmap_range_cardinality(const roaring_bitmap_t *r,
2064520655
uint64_t range_start,
2064620656
uint64_t range_end) {
20657+
if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
20658+
return 0;
20659+
}
20660+
return roaring_bitmap_range_cardinality_closed(r, (uint32_t)range_start,
20661+
(uint32_t)(range_end - 1));
20662+
}
20663+
20664+
uint64_t roaring_bitmap_range_cardinality_closed(const roaring_bitmap_t *r,
20665+
uint32_t range_start,
20666+
uint32_t range_end) {
2064720667
const roaring_array_t *ra = &r->high_low_container;
2064820668

20649-
if (range_end > UINT32_MAX) {
20650-
range_end = UINT32_MAX + UINT64_C(1);
20651-
}
20652-
if (range_start >= range_end) {
20669+
if (range_start > range_end) {
2065320670
return 0;
2065420671
}
20655-
range_end--; // make range_end inclusive
20672+
2065620673
// now we have: 0 <= range_start <= range_end <= UINT32_MAX
2065720674

2065820675
uint16_t minhb = (uint16_t)(range_start >> 16);
@@ -21319,20 +21336,27 @@ static void inplace_fully_flip_container(roaring_array_t *x1_arr, uint16_t hb) {
2131921336
roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *x1,
2132021337
uint64_t range_start,
2132121338
uint64_t range_end) {
21322-
if (range_start >= range_end) {
21339+
if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
2132321340
return roaring_bitmap_copy(x1);
2132421341
}
21325-
if (range_end >= UINT64_C(0x100000000)) {
21326-
range_end = UINT64_C(0x100000000);
21342+
return roaring_bitmap_flip_closed(x1, (uint32_t)range_start,
21343+
(uint32_t)(range_end - 1));
21344+
}
21345+
21346+
roaring_bitmap_t *roaring_bitmap_flip_closed(const roaring_bitmap_t *x1,
21347+
uint32_t range_start,
21348+
uint32_t range_end) {
21349+
if (range_start > range_end) {
21350+
return roaring_bitmap_copy(x1);
2132721351
}
2132821352

2132921353
roaring_bitmap_t *ans = roaring_bitmap_create();
2133021354
roaring_bitmap_set_copy_on_write(ans, is_cow(x1));
2133121355

2133221356
uint16_t hb_start = (uint16_t)(range_start >> 16);
2133321357
const uint16_t lb_start = (uint16_t)range_start; // & 0xFFFF;
21334-
uint16_t hb_end = (uint16_t)((range_end - 1) >> 16);
21335-
const uint16_t lb_end = (uint16_t)(range_end - 1); // & 0xFFFF;
21358+
uint16_t hb_end = (uint16_t)(range_end >> 16);
21359+
const uint16_t lb_end = (uint16_t)range_end; // & 0xFFFF;
2133621360

2133721361
ra_append_copies_until(&ans->high_low_container, &x1->high_low_container,
2133821362
hb_start, is_cow(x1));
@@ -21373,17 +21397,24 @@ roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *x1,
2137321397

2137421398
void roaring_bitmap_flip_inplace(roaring_bitmap_t *x1, uint64_t range_start,
2137521399
uint64_t range_end) {
21376-
if (range_start >= range_end) {
21377-
return; // empty range
21400+
if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
21401+
return;
2137821402
}
21379-
if (range_end >= UINT64_C(0x100000000)) {
21380-
range_end = UINT64_C(0x100000000);
21403+
roaring_bitmap_flip_inplace_closed(x1, (uint32_t)range_start,
21404+
(uint32_t)(range_end - 1));
21405+
}
21406+
21407+
void roaring_bitmap_flip_inplace_closed(roaring_bitmap_t *x1,
21408+
uint32_t range_start,
21409+
uint32_t range_end) {
21410+
if (range_start > range_end) {
21411+
return; // empty range
2138121412
}
2138221413

2138321414
uint16_t hb_start = (uint16_t)(range_start >> 16);
2138421415
const uint16_t lb_start = (uint16_t)range_start;
21385-
uint16_t hb_end = (uint16_t)((range_end - 1) >> 16);
21386-
const uint16_t lb_end = (uint16_t)(range_end - 1);
21416+
uint16_t hb_end = (uint16_t)(range_end >> 16);
21417+
const uint16_t lb_end = (uint16_t)range_end;
2138721418

2138821419
if (hb_start == hb_end) {
2138921420
inplace_flip_container(&x1->high_low_container, hb_start, lb_start,
@@ -22141,15 +22172,28 @@ bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val) {
2214122172
*/
2214222173
bool roaring_bitmap_contains_range(const roaring_bitmap_t *r,
2214322174
uint64_t range_start, uint64_t range_end) {
22144-
if (range_end >= UINT64_C(0x100000000)) {
22145-
range_end = UINT64_C(0x100000000);
22175+
if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
22176+
return true;
2214622177
}
22147-
if (range_start >= range_end)
22148-
return true; // empty range are always contained!
22149-
if (range_end - range_start == 1)
22178+
return roaring_bitmap_contains_range_closed(r, (uint32_t)range_start,
22179+
(uint32_t)(range_end - 1));
22180+
}
22181+
22182+
/**
22183+
* Check whether a range of values from range_start (included) to range_end
22184+
* (included) is present
22185+
*/
22186+
bool roaring_bitmap_contains_range_closed(const roaring_bitmap_t *r,
22187+
uint32_t range_start,
22188+
uint32_t range_end) {
22189+
if (range_start > range_end) {
22190+
return true;
22191+
} // empty range are always contained!
22192+
if (range_end == range_start) {
2215022193
return roaring_bitmap_contains(r, (uint32_t)range_start);
22194+
}
2215122195
uint16_t hb_rs = (uint16_t)(range_start >> 16);
22152-
uint16_t hb_re = (uint16_t)((range_end - 1) >> 16);
22196+
uint16_t hb_re = (uint16_t)(range_end >> 16);
2215322197
const int32_t span = hb_re - hb_rs;
2215422198
const int32_t hlc_sz = ra_get_size(&r->high_low_container);
2215522199
if (hlc_sz < span + 1) {
@@ -22161,7 +22205,7 @@ bool roaring_bitmap_contains_range(const roaring_bitmap_t *r,
2216122205
return false;
2216222206
}
2216322207
const uint32_t lb_rs = range_start & 0xFFFF;
22164-
const uint32_t lb_re = ((range_end - 1) & 0xFFFF) + 1;
22208+
const uint32_t lb_re = (range_end & 0xFFFF) + 1;
2216522209
uint8_t type;
2216622210
container_t *c =
2216722211
ra_get_container_at_index(&r->high_low_container, (uint16_t)is, &type);
@@ -24646,6 +24690,8 @@ roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe(
2464624690
roaring64_bitmap_free(r);
2464724691
return NULL;
2464824692
}
24693+
previous_high32 = high32;
24694+
2464924695
// Read the 32-bit Roaring bitmaps representing the least significant
2465024696
// bits of a set of elements.
2465124697
size_t bitmap32_size = roaring_bitmap_portable_deserialize_size(
@@ -25510,7 +25556,7 @@ size_t ra_portable_deserialize_size(const char *buf, const size_t maxbytes) {
2551025556
memcpy(&size, buf, sizeof(int32_t));
2551125557
buf += sizeof(uint32_t);
2551225558
}
25513-
if (size > (1 << 16)) {
25559+
if (size > (1 << 16) || size < 0) {
2551425560
return 0;
2551525561
}
2551625562
char *bitmapOfRunContainers = NULL;

pyroaring/roaring.h

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// !!! DO NOT EDIT - THIS IS AN AUTO-GENERATED FILE !!!
2-
// Created by amalgamation.sh on 2024-09-19T23:52:46Z
2+
// Created by amalgamation.sh on 2024-09-30T21:45:33Z
33

44
/*
55
* The CRoaring project is under a dual license (Apache/MIT).
@@ -59,11 +59,11 @@
5959
// /include/roaring/roaring_version.h automatically generated by release.py, do not change by hand
6060
#ifndef ROARING_INCLUDE_ROARING_VERSION
6161
#define ROARING_INCLUDE_ROARING_VERSION
62-
#define ROARING_VERSION "4.1.5"
62+
#define ROARING_VERSION "4.2.0"
6363
enum {
6464
ROARING_VERSION_MAJOR = 4,
65-
ROARING_VERSION_MINOR = 1,
66-
ROARING_VERSION_REVISION = 5
65+
ROARING_VERSION_MINOR = 2,
66+
ROARING_VERSION_REVISION = 0
6767
};
6868
#endif // ROARING_INCLUDE_ROARING_VERSION
6969
// clang-format on/* end file include/roaring/roaring_version.h */
@@ -967,7 +967,10 @@ inline bool bitset_get(const bitset_t *bitset, size_t i) {
967967
/* Count number of bits set. */
968968
size_t bitset_count(const bitset_t *bitset);
969969

970-
/* Find the index of the first bit set. Or zero if the bitset is empty. */
970+
/* Returns true if no bit is set. */
971+
bool bitset_empty(const bitset_t *bitset);
972+
973+
/* Find the index of the first bit set. Or SIZE_MAX if the bitset is empty. */
971974
size_t bitset_minimum(const bitset_t *bitset);
972975

973976
/* Find the index of the last bit set. Or zero if the bitset is empty. */
@@ -1514,7 +1517,9 @@ void roaring_bitmap_add_range_closed(roaring_bitmap_t *r, uint32_t min,
15141517
*/
15151518
inline void roaring_bitmap_add_range(roaring_bitmap_t *r, uint64_t min,
15161519
uint64_t max) {
1517-
if (max <= min) return;
1520+
if (max <= min || min > (uint64_t)UINT32_MAX + 1) {
1521+
return;
1522+
}
15181523
roaring_bitmap_add_range_closed(r, (uint32_t)min, (uint32_t)(max - 1));
15191524
}
15201525

@@ -1534,7 +1539,9 @@ void roaring_bitmap_remove_range_closed(roaring_bitmap_t *r, uint32_t min,
15341539
*/
15351540
inline void roaring_bitmap_remove_range(roaring_bitmap_t *r, uint64_t min,
15361541
uint64_t max) {
1537-
if (max <= min) return;
1542+
if (max <= min || min > (uint64_t)UINT32_MAX + 1) {
1543+
return;
1544+
}
15381545
roaring_bitmap_remove_range_closed(r, (uint32_t)min, (uint32_t)(max - 1));
15391546
}
15401547

@@ -1562,6 +1569,14 @@ bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val);
15621569
bool roaring_bitmap_contains_range(const roaring_bitmap_t *r,
15631570
uint64_t range_start, uint64_t range_end);
15641571

1572+
/**
1573+
* Check whether a range of values from range_start (included)
1574+
* to range_end (included) is present
1575+
*/
1576+
bool roaring_bitmap_contains_range_closed(const roaring_bitmap_t *r,
1577+
uint32_t range_start,
1578+
uint32_t range_end);
1579+
15651580
/**
15661581
* Check if an items is present, using context from a previous insert or search
15671582
* for speed optimization.
@@ -1593,6 +1608,12 @@ uint64_t roaring_bitmap_range_cardinality(const roaring_bitmap_t *r,
15931608
uint64_t range_start,
15941609
uint64_t range_end);
15951610

1611+
/**
1612+
* Returns the number of elements in the range [range_start, range_end].
1613+
*/
1614+
uint64_t roaring_bitmap_range_cardinality_closed(const roaring_bitmap_t *r,
1615+
uint32_t range_start,
1616+
uint32_t range_end);
15961617
/**
15971618
* Returns true if the bitmap is empty (cardinality is zero).
15981619
*/
@@ -1994,6 +2015,14 @@ void roaring_bitmap_lazy_xor_inplace(roaring_bitmap_t *r1,
19942015
roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *r1,
19952016
uint64_t range_start, uint64_t range_end);
19962017

2018+
/**
2019+
* Compute the negation of the bitmap in the interval [range_start, range_end].
2020+
* The number of negated values is range_end - range_start + 1.
2021+
* Areas outside the range are passed through unchanged.
2022+
*/
2023+
roaring_bitmap_t *roaring_bitmap_flip_closed(const roaring_bitmap_t *x1,
2024+
uint32_t range_start,
2025+
uint32_t range_end);
19972026
/**
19982027
* compute (in place) the negation of the roaring bitmap within a specified
19992028
* interval: [range_start, range_end). The number of negated values is
@@ -2003,6 +2032,16 @@ roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *r1,
20032032
void roaring_bitmap_flip_inplace(roaring_bitmap_t *r1, uint64_t range_start,
20042033
uint64_t range_end);
20052034

2035+
/**
2036+
* compute (in place) the negation of the roaring bitmap within a specified
2037+
* interval: [range_start, range_end]. The number of negated values is
2038+
* range_end - range_start + 1.
2039+
* Areas outside the range are passed through unchanged.
2040+
*/
2041+
void roaring_bitmap_flip_inplace_closed(roaring_bitmap_t *r1,
2042+
uint32_t range_start,
2043+
uint32_t range_end);
2044+
20062045
/**
20072046
* Selects the element at index 'rank' where the smallest element is at index 0.
20082047
* If the size of the roaring bitmap is strictly greater than rank, then this

test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ def test_invalid_deserialization(
905905
bm = cls(list(range(0, 1000000, 3)))
906906
bitmap_bytes = bm.serialize()
907907
bitmap_bytes = bitmap_bytes[:42] + wrong_input + bitmap_bytes[42:]
908-
with pytest.raises(ValueError, match='Invalid bitmap after deserialization'):
908+
with pytest.raises(ValueError, match='Invalid bitmap after deserialization|Could not deserialize bitmap'):
909909
bitmap = cls.deserialize(bitmap_bytes)
910910

911911

0 commit comments

Comments
 (0)