Coverage Report

Created: 2026-09-04 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/croaring/include/roaring/containers/bitset.h
Line
Count
Source
1
/*
2
 * bitset.h
3
 *
4
 * Bitset containers store a set of 16-bit integers as a fixed-size bitmap.
5
 * The words pointer references an array of 64-bit words covering the full
6
 * 16-bit domain, with one bit per possible value. The cardinality field tracks
7
 * the number of set bits; when it is BITSET_UNKNOWN_CARDINALITY, the count must
8
 * be recomputed from the bitmap contents.
9
 *
10
 * This representation is used for denser containers because membership tests,
11
 * set operations, and sequential scans can be implemented efficiently with
12
 * word-level bitwise operations.
13
 */
14
15
#ifndef INCLUDE_CONTAINERS_BITSET_H_
16
#define INCLUDE_CONTAINERS_BITSET_H_
17
18
#include <stdbool.h>
19
#include <stdint.h>
20
21
#include <roaring/roaring_types.h>  // roaring_iterator
22
23
// Include other headers after roaring_types.h
24
#include <roaring/containers/container_defs.h>  // container_t, perfparameters
25
#include <roaring/portability.h>
26
#include <roaring/roaring_types.h>  // roaring_iterator
27
#include <roaring/utilasm.h>        // ASM_XXX macros
28
29
#ifdef __cplusplus
30
extern "C" {
31
namespace roaring {
32
33
// Note: in pure C++ code, you should avoid putting `using` in header files
34
using api::roaring_iterator;
35
using api::roaring_iterator64;
36
37
namespace internal {
38
#endif
39
40
enum {
41
    BITSET_CONTAINER_SIZE_IN_WORDS = (1 << 16) / 64,
42
    BITSET_UNKNOWN_CARDINALITY = -1
43
};
44
45
STRUCT_CONTAINER(bitset_container_s) {
46
    int32_t cardinality;
47
    uint64_t *words;
48
};
49
50
typedef struct bitset_container_s bitset_container_t;
51
52
10.9k
#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
53
113
#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
54
#define movable_CAST_bitset(c) movable_CAST(bitset_container_t **, c)
55
56
/* Create a new bitset. Return NULL in case of failure. */
57
bitset_container_t *bitset_container_create(void);
58
59
/* Create a bitset without zeroing the words. Caller must overwrite `words`
60
 * before the container is used. Return NULL in case of failure. */
61
bitset_container_t *bitset_container_create_uninitialized(void);
62
63
/* Free memory. */
64
void bitset_container_free(bitset_container_t *bitset);
65
66
/* Clear bitset (sets bits to 0). */
67
void bitset_container_clear(bitset_container_t *bitset);
68
69
/* Set all bits to 1. */
70
void bitset_container_set_all(bitset_container_t *bitset);
71
72
/* Duplicate bitset */
73
bitset_container_t *bitset_container_clone(const bitset_container_t *src);
74
75
/* Set the bit in [begin,end). WARNING: as of April 2016, this method is slow
76
 * and
77
 * should not be used in performance-sensitive code. Ever.  */
78
void bitset_container_set_range(bitset_container_t *bitset, uint32_t begin,
79
                                uint32_t end);
80
81
#if defined(CROARING_ASMBITMANIPOPTIMIZATION) && defined(__AVX2__)
82
/* Set the ith bit.  */
83
static inline void bitset_container_set(bitset_container_t *bitset,
84
                                        uint16_t pos) {
85
    uint64_t shift = 6;
86
    uint64_t offset;
87
    uint64_t p = pos;
88
    ASM_SHIFT_RIGHT(p, shift, offset);
89
    uint64_t load = bitset->words[offset];
90
    ASM_SET_BIT_INC_WAS_CLEAR(load, p, bitset->cardinality);
91
    bitset->words[offset] = load;
92
}
93
94
/* Unset the ith bit. Currently unused. Could be used for optimization. */
95
/*static inline void bitset_container_unset(bitset_container_t *bitset,
96
                                          uint16_t pos) {
97
    uint64_t shift = 6;
98
    uint64_t offset;
99
    uint64_t p = pos;
100
    ASM_SHIFT_RIGHT(p, shift, offset);
101
    uint64_t load = bitset->words[offset];
102
    ASM_CLEAR_BIT_DEC_WAS_SET(load, p, bitset->cardinality);
103
    bitset->words[offset] = load;
104
}*/
105
106
/* Add `pos' to `bitset'. Returns true if `pos' was not present. Might be slower
107
 * than bitset_container_set.  */
108
static inline bool bitset_container_add(bitset_container_t *bitset,
109
                                        uint16_t pos) {
110
    uint64_t shift = 6;
111
    uint64_t offset;
112
    uint64_t p = pos;
113
    ASM_SHIFT_RIGHT(p, shift, offset);
114
    uint64_t load = bitset->words[offset];
115
    // could be possibly slightly further optimized
116
    const int32_t oldcard = bitset->cardinality;
117
    ASM_SET_BIT_INC_WAS_CLEAR(load, p, bitset->cardinality);
118
    bitset->words[offset] = load;
119
    return bitset->cardinality - oldcard;
120
}
121
122
/* Remove `pos' from `bitset'. Returns true if `pos' was present.  Might be
123
 * slower than bitset_container_unset.  */
124
static inline bool bitset_container_remove(bitset_container_t *bitset,
125
                                           uint16_t pos) {
126
    uint64_t shift = 6;
127
    uint64_t offset;
128
    uint64_t p = pos;
129
    ASM_SHIFT_RIGHT(p, shift, offset);
130
    uint64_t load = bitset->words[offset];
131
    // could be possibly slightly further optimized
132
    const int32_t oldcard = bitset->cardinality;
133
    ASM_CLEAR_BIT_DEC_WAS_SET(load, p, bitset->cardinality);
134
    bitset->words[offset] = load;
135
    return oldcard - bitset->cardinality;
136
}
137
138
/* Get the value of the ith bit.  */
139
inline bool bitset_container_get(const bitset_container_t *bitset,
140
                                 uint16_t pos) {
141
    uint64_t word = bitset->words[pos >> 6];
142
    const uint64_t p = pos;
143
    ASM_INPLACESHIFT_RIGHT(word, p);
144
    return word & 1;
145
}
146
147
#else
148
149
/* Set the ith bit.  */
150
static inline void bitset_container_set(bitset_container_t *bitset,
151
10.1k
                                        uint16_t pos) {
152
10.1k
    const uint64_t old_word = bitset->words[pos >> 6];
153
10.1k
    const int index = pos & 63;
154
10.1k
    const uint64_t new_word = old_word | (UINT64_C(1) << index);
155
10.1k
    bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index);
156
10.1k
    bitset->words[pos >> 6] = new_word;
157
10.1k
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_set
Unexecuted instantiation: containers.c:bitset_container_set
roaring.c:bitset_container_set
Line
Count
Source
151
4.43k
                                        uint16_t pos) {
152
4.43k
    const uint64_t old_word = bitset->words[pos >> 6];
153
4.43k
    const int index = pos & 63;
154
    const uint64_t new_word = old_word | (UINT64_C(1) << index);
155
4.43k
    bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index);
156
4.43k
    bitset->words[pos >> 6] = new_word;
157
4.43k
}
roaring64.c:bitset_container_set
Line
Count
Source
151
5.70k
                                        uint16_t pos) {
152
5.70k
    const uint64_t old_word = bitset->words[pos >> 6];
153
5.70k
    const int index = pos & 63;
154
    const uint64_t new_word = old_word | (UINT64_C(1) << index);
155
5.70k
    bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index);
156
5.70k
    bitset->words[pos >> 6] = new_word;
157
5.70k
}
Unexecuted instantiation: roaring_array.c:bitset_container_set
Unexecuted instantiation: bitset.c:bitset_container_set
Unexecuted instantiation: convert.c:bitset_container_set
Unexecuted instantiation: mixed_intersection.c:bitset_container_set
Unexecuted instantiation: mixed_union.c:bitset_container_set
Unexecuted instantiation: mixed_equal.c:bitset_container_set
Unexecuted instantiation: mixed_subset.c:bitset_container_set
Unexecuted instantiation: mixed_negation.c:bitset_container_set
Unexecuted instantiation: mixed_xor.c:bitset_container_set
Unexecuted instantiation: mixed_andnot.c:bitset_container_set
158
159
/* Unset the ith bit. Currently unused.  */
160
/*static inline void bitset_container_unset(bitset_container_t *bitset,
161
                                          uint16_t pos) {
162
    const uint64_t old_word = bitset->words[pos >> 6];
163
    const int index = pos & 63;
164
    const uint64_t new_word = old_word & (~(UINT64_C(1) << index));
165
    bitset->cardinality -= (uint32_t)((old_word ^ new_word) >> index);
166
    bitset->words[pos >> 6] = new_word;
167
}*/
168
169
/* Add `pos' to `bitset'. Returns true if `pos' was not present. Might be slower
170
 * than bitset_container_set.  */
171
static inline bool bitset_container_add(bitset_container_t *bitset,
172
0
                                        uint16_t pos) {
173
0
    const uint64_t old_word = bitset->words[pos >> 6];
174
0
    const int index = pos & 63;
175
0
    const uint64_t new_word = old_word | (UINT64_C(1) << index);
176
0
    const uint64_t increment = (old_word ^ new_word) >> index;
177
0
    bitset->cardinality += (uint32_t)increment;
178
0
    bitset->words[pos >> 6] = new_word;
179
0
    return increment > 0;
180
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_add
Unexecuted instantiation: containers.c:bitset_container_add
Unexecuted instantiation: roaring.c:bitset_container_add
Unexecuted instantiation: roaring64.c:bitset_container_add
Unexecuted instantiation: roaring_array.c:bitset_container_add
Unexecuted instantiation: bitset.c:bitset_container_add
Unexecuted instantiation: convert.c:bitset_container_add
Unexecuted instantiation: mixed_intersection.c:bitset_container_add
Unexecuted instantiation: mixed_union.c:bitset_container_add
Unexecuted instantiation: mixed_equal.c:bitset_container_add
Unexecuted instantiation: mixed_subset.c:bitset_container_add
Unexecuted instantiation: mixed_negation.c:bitset_container_add
Unexecuted instantiation: mixed_xor.c:bitset_container_add
Unexecuted instantiation: mixed_andnot.c:bitset_container_add
181
182
/* Remove `pos' from `bitset'. Returns true if `pos' was present.  Might be
183
 * slower than bitset_container_unset.  */
184
static inline bool bitset_container_remove(bitset_container_t *bitset,
185
0
                                           uint16_t pos) {
186
0
    const uint64_t old_word = bitset->words[pos >> 6];
187
0
    const int index = pos & 63;
188
0
    const uint64_t new_word = old_word & (~(UINT64_C(1) << index));
189
0
    const uint64_t increment = (old_word ^ new_word) >> index;
190
0
    bitset->cardinality -= (uint32_t)increment;
191
0
    bitset->words[pos >> 6] = new_word;
192
0
    return increment > 0;
193
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_remove
Unexecuted instantiation: containers.c:bitset_container_remove
Unexecuted instantiation: roaring.c:bitset_container_remove
Unexecuted instantiation: roaring64.c:bitset_container_remove
Unexecuted instantiation: roaring_array.c:bitset_container_remove
Unexecuted instantiation: bitset.c:bitset_container_remove
Unexecuted instantiation: convert.c:bitset_container_remove
Unexecuted instantiation: mixed_intersection.c:bitset_container_remove
Unexecuted instantiation: mixed_union.c:bitset_container_remove
Unexecuted instantiation: mixed_equal.c:bitset_container_remove
Unexecuted instantiation: mixed_subset.c:bitset_container_remove
Unexecuted instantiation: mixed_negation.c:bitset_container_remove
Unexecuted instantiation: mixed_xor.c:bitset_container_remove
Unexecuted instantiation: mixed_andnot.c:bitset_container_remove
194
195
/* Get the value of the ith bit.  */
196
inline bool bitset_container_get(const bitset_container_t *bitset,
197
14.4k
                                 uint16_t pos) {
198
14.4k
    const uint64_t word = bitset->words[pos >> 6];
199
14.4k
    return (word >> (pos & 63)) & 1;
200
14.4k
}
201
202
#endif
203
204
/*
205
 * Check if all bits are set in a range of positions from pos_start (included)
206
 * to pos_end (excluded).
207
 */
208
static inline bool bitset_container_get_range(const bitset_container_t *bitset,
209
                                              uint32_t pos_start,
210
0
                                              uint32_t pos_end) {
211
0
    const uint32_t start = pos_start >> 6;
212
0
    const uint32_t end = pos_end >> 6;
213
214
0
    const uint64_t first = ~((1ULL << (pos_start & 0x3F)) - 1);
215
0
    const uint64_t last = (1ULL << (pos_end & 0x3F)) - 1;
216
217
0
    if (start == end)
218
0
        return ((bitset->words[end] & first & last) == (first & last));
219
0
    if ((bitset->words[start] & first) != first) return false;
220
221
0
    if ((end < BITSET_CONTAINER_SIZE_IN_WORDS) &&
222
0
        ((bitset->words[end] & last) != last)) {
223
0
        return false;
224
0
    }
225
226
0
    for (uint32_t i = start + 1;
227
0
         (i < BITSET_CONTAINER_SIZE_IN_WORDS) && (i < end); ++i) {
228
0
        if (bitset->words[i] != UINT64_C(0xFFFFFFFFFFFFFFFF)) return false;
229
0
    }
230
231
0
    return true;
232
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_get_range
Unexecuted instantiation: containers.c:bitset_container_get_range
Unexecuted instantiation: roaring.c:bitset_container_get_range
Unexecuted instantiation: roaring64.c:bitset_container_get_range
Unexecuted instantiation: roaring_array.c:bitset_container_get_range
Unexecuted instantiation: bitset.c:bitset_container_get_range
Unexecuted instantiation: convert.c:bitset_container_get_range
Unexecuted instantiation: mixed_intersection.c:bitset_container_get_range
Unexecuted instantiation: mixed_union.c:bitset_container_get_range
Unexecuted instantiation: mixed_equal.c:bitset_container_get_range
Unexecuted instantiation: mixed_subset.c:bitset_container_get_range
Unexecuted instantiation: mixed_negation.c:bitset_container_get_range
Unexecuted instantiation: mixed_xor.c:bitset_container_get_range
Unexecuted instantiation: mixed_andnot.c:bitset_container_get_range
233
234
/* Check whether `bitset' is present in `array'.  Calls bitset_container_get. */
235
inline bool bitset_container_contains(const bitset_container_t *bitset,
236
0
                                      uint16_t pos) {
237
0
    return bitset_container_get(bitset, pos);
238
0
}
239
240
/*
241
 * Check whether a range of bits from position `pos_start' (included) to
242
 * `pos_end' (excluded) is present in `bitset'.  Calls bitset_container_get_all.
243
 */
244
static inline bool bitset_container_contains_range(
245
0
    const bitset_container_t *bitset, uint32_t pos_start, uint32_t pos_end) {
246
0
    return bitset_container_get_range(bitset, pos_start, pos_end);
247
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_contains_range
Unexecuted instantiation: containers.c:bitset_container_contains_range
Unexecuted instantiation: roaring.c:bitset_container_contains_range
Unexecuted instantiation: roaring64.c:bitset_container_contains_range
Unexecuted instantiation: roaring_array.c:bitset_container_contains_range
Unexecuted instantiation: bitset.c:bitset_container_contains_range
Unexecuted instantiation: convert.c:bitset_container_contains_range
Unexecuted instantiation: mixed_intersection.c:bitset_container_contains_range
Unexecuted instantiation: mixed_union.c:bitset_container_contains_range
Unexecuted instantiation: mixed_equal.c:bitset_container_contains_range
Unexecuted instantiation: mixed_subset.c:bitset_container_contains_range
Unexecuted instantiation: mixed_negation.c:bitset_container_contains_range
Unexecuted instantiation: mixed_xor.c:bitset_container_contains_range
Unexecuted instantiation: mixed_andnot.c:bitset_container_contains_range
248
249
/* Get the number of bits set */
250
CROARING_ALLOW_UNALIGNED
251
static inline int bitset_container_cardinality(
252
46
    const bitset_container_t *bitset) {
253
46
    return bitset->cardinality;
254
46
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_cardinality
Unexecuted instantiation: containers.c:bitset_container_cardinality
roaring.c:bitset_container_cardinality
Line
Count
Source
252
20
    const bitset_container_t *bitset) {
253
20
    return bitset->cardinality;
254
20
}
roaring64.c:bitset_container_cardinality
Line
Count
Source
252
26
    const bitset_container_t *bitset) {
253
26
    return bitset->cardinality;
254
26
}
Unexecuted instantiation: roaring_array.c:bitset_container_cardinality
Unexecuted instantiation: bitset.c:bitset_container_cardinality
Unexecuted instantiation: convert.c:bitset_container_cardinality
Unexecuted instantiation: mixed_intersection.c:bitset_container_cardinality
Unexecuted instantiation: mixed_union.c:bitset_container_cardinality
Unexecuted instantiation: mixed_equal.c:bitset_container_cardinality
Unexecuted instantiation: mixed_subset.c:bitset_container_cardinality
Unexecuted instantiation: mixed_negation.c:bitset_container_cardinality
Unexecuted instantiation: mixed_xor.c:bitset_container_cardinality
Unexecuted instantiation: mixed_andnot.c:bitset_container_cardinality
255
256
/* Copy one container into another. We assume that they are distinct. */
257
void bitset_container_copy(const bitset_container_t *source,
258
                           bitset_container_t *dest);
259
260
/*  Add all the values [min,max) at a distance k*step from min: min,
261
 * min+step,.... */
262
void bitset_container_add_from_range(bitset_container_t *bitset, uint32_t min,
263
                                     uint32_t max, uint16_t step);
264
265
/* Get the number of bits set (force computation). This does not modify bitset.
266
 * To update the cardinality, you should do
267
 * bitset->cardinality =  bitset_container_compute_cardinality(bitset).*/
268
int bitset_container_compute_cardinality(const bitset_container_t *bitset);
269
270
/* Check whether this bitset is empty,
271
 *  it never modifies the bitset struct. */
272
0
static inline bool bitset_container_empty(const bitset_container_t *bitset) {
273
0
    if (bitset->cardinality == BITSET_UNKNOWN_CARDINALITY) {
274
0
        for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i++) {
275
0
            if ((bitset->words[i]) != 0) return false;
276
0
        }
277
0
        return true;
278
0
    }
279
0
    return bitset->cardinality == 0;
280
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_empty
Unexecuted instantiation: containers.c:bitset_container_empty
Unexecuted instantiation: roaring.c:bitset_container_empty
Unexecuted instantiation: roaring64.c:bitset_container_empty
Unexecuted instantiation: roaring_array.c:bitset_container_empty
Unexecuted instantiation: bitset.c:bitset_container_empty
Unexecuted instantiation: convert.c:bitset_container_empty
Unexecuted instantiation: mixed_intersection.c:bitset_container_empty
Unexecuted instantiation: mixed_union.c:bitset_container_empty
Unexecuted instantiation: mixed_equal.c:bitset_container_empty
Unexecuted instantiation: mixed_subset.c:bitset_container_empty
Unexecuted instantiation: mixed_negation.c:bitset_container_empty
Unexecuted instantiation: mixed_xor.c:bitset_container_empty
Unexecuted instantiation: mixed_andnot.c:bitset_container_empty
281
282
/* Get whether there is at least one bit set  (see bitset_container_empty for
283
   the reverse), the bitset is never modified */
284
static inline bool bitset_container_const_nonzero_cardinality(
285
0
    const bitset_container_t *bitset) {
286
0
    return !bitset_container_empty(bitset);
287
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: containers.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: roaring.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: roaring64.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: roaring_array.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: bitset.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: convert.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_intersection.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_union.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_equal.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_subset.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_negation.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_xor.c:bitset_container_const_nonzero_cardinality
Unexecuted instantiation: mixed_andnot.c:bitset_container_const_nonzero_cardinality
288
289
/*
290
 * Check whether the two bitsets intersect
291
 */
292
bool bitset_container_intersect(const bitset_container_t *src_1,
293
                                const bitset_container_t *src_2);
294
295
/* Computes the union of bitsets `src_1' and `src_2' into `dst'  and return the
296
 * cardinality. */
297
int bitset_container_or(const bitset_container_t *src_1,
298
                        const bitset_container_t *src_2,
299
                        bitset_container_t *dst);
300
301
/* Computes the union of bitsets `src_1' and `src_2' and return the cardinality.
302
 */
303
int bitset_container_or_justcard(const bitset_container_t *src_1,
304
                                 const bitset_container_t *src_2);
305
306
/* Computes the union of bitsets `src_1' and `src_2' into `dst' and return the
307
 * cardinality. Same as bitset_container_or. */
308
int bitset_container_union(const bitset_container_t *src_1,
309
                           const bitset_container_t *src_2,
310
                           bitset_container_t *dst);
311
312
/* Computes the union of bitsets `src_1' and `src_2'  and return the
313
 * cardinality. Same as bitset_container_or_justcard. */
314
int bitset_container_union_justcard(const bitset_container_t *src_1,
315
                                    const bitset_container_t *src_2);
316
317
/* Computes the union of bitsets `src_1' and `src_2' into `dst', but does
318
 * not update the cardinality. Provided to optimize chained operations. */
319
int bitset_container_union_nocard(const bitset_container_t *src_1,
320
                                  const bitset_container_t *src_2,
321
                                  bitset_container_t *dst);
322
323
/* Computes the union of bitsets `src_1' and `src_2' into `dst', but does not
324
 * update the cardinality. Provided to optimize chained operations. */
325
int bitset_container_or_nocard(const bitset_container_t *src_1,
326
                               const bitset_container_t *src_2,
327
                               bitset_container_t *dst);
328
329
/* Computes the intersection of bitsets `src_1' and `src_2' into `dst' and
330
 * return the cardinality. */
331
int bitset_container_and(const bitset_container_t *src_1,
332
                         const bitset_container_t *src_2,
333
                         bitset_container_t *dst);
334
335
/* Computes the intersection of bitsets `src_1' and `src_2'  and return the
336
 * cardinality. */
337
int bitset_container_and_justcard(const bitset_container_t *src_1,
338
                                  const bitset_container_t *src_2);
339
340
/* Computes the intersection of bitsets `src_1' and `src_2' into `dst' and
341
 * return the cardinality. Same as bitset_container_and. */
342
int bitset_container_intersection(const bitset_container_t *src_1,
343
                                  const bitset_container_t *src_2,
344
                                  bitset_container_t *dst);
345
346
/* Computes the intersection of bitsets `src_1' and `src_2' and return the
347
 * cardinality. Same as bitset_container_and_justcard. */
348
int bitset_container_intersection_justcard(const bitset_container_t *src_1,
349
                                           const bitset_container_t *src_2);
350
351
/* Computes the intersection of bitsets `src_1' and `src_2' into `dst', but does
352
 * not update the cardinality. Provided to optimize chained operations. */
353
int bitset_container_intersection_nocard(const bitset_container_t *src_1,
354
                                         const bitset_container_t *src_2,
355
                                         bitset_container_t *dst);
356
357
/* Computes the intersection of bitsets `src_1' and `src_2' into `dst', but does
358
 * not update the cardinality. Provided to optimize chained operations. */
359
int bitset_container_and_nocard(const bitset_container_t *src_1,
360
                                const bitset_container_t *src_2,
361
                                bitset_container_t *dst);
362
363
/* Computes the exclusive or of bitsets `src_1' and `src_2' into `dst' and
364
 * return the cardinality. */
365
int bitset_container_xor(const bitset_container_t *src_1,
366
                         const bitset_container_t *src_2,
367
                         bitset_container_t *dst);
368
369
/* Computes the exclusive or of bitsets `src_1' and `src_2' and return the
370
 * cardinality. */
371
int bitset_container_xor_justcard(const bitset_container_t *src_1,
372
                                  const bitset_container_t *src_2);
373
374
/* Computes the exclusive or of bitsets `src_1' and `src_2' into `dst', but does
375
 * not update the cardinality. Provided to optimize chained operations. */
376
int bitset_container_xor_nocard(const bitset_container_t *src_1,
377
                                const bitset_container_t *src_2,
378
                                bitset_container_t *dst);
379
380
/* Computes the and not of bitsets `src_1' and `src_2' into `dst' and return the
381
 * cardinality. */
382
int bitset_container_andnot(const bitset_container_t *src_1,
383
                            const bitset_container_t *src_2,
384
                            bitset_container_t *dst);
385
386
/* Computes the and not of bitsets `src_1' and `src_2'  and return the
387
 * cardinality. */
388
int bitset_container_andnot_justcard(const bitset_container_t *src_1,
389
                                     const bitset_container_t *src_2);
390
391
/* Computes the and not or of bitsets `src_1' and `src_2' into `dst', but does
392
 * not update the cardinality. Provided to optimize chained operations. */
393
int bitset_container_andnot_nocard(const bitset_container_t *src_1,
394
                                   const bitset_container_t *src_2,
395
                                   bitset_container_t *dst);
396
397
void bitset_container_offset(const bitset_container_t *c, container_t **loc,
398
                             container_t **hic, uint16_t offset);
399
/*
400
 * Write out the 16-bit integers contained in this container as a list of 32-bit
401
 * integers using base
402
 * as the starting value (it might be expected that base has zeros in its 16
403
 * least significant bits).
404
 * The function returns the number of values written.
405
 * The caller is responsible for allocating enough memory in out.
406
 * The out pointer should point to enough memory (the cardinality times 32
407
 * bits).
408
 */
409
int bitset_container_to_uint32_array(uint32_t *out,
410
                                     const bitset_container_t *bc,
411
                                     uint32_t base);
412
413
/*
414
 * Print this container using printf (useful for debugging).
415
 */
416
void bitset_container_printf(const bitset_container_t *v);
417
418
/*
419
 * Print this container using printf as a comma-separated list of 32-bit
420
 * integers starting at base.
421
 */
422
void bitset_container_printf_as_uint32_array(const bitset_container_t *v,
423
                                             uint32_t base);
424
425
bool bitset_container_validate(const bitset_container_t *v,
426
                               const char **reason);
427
428
/**
429
 * Return the serialized size in bytes of a container.
430
 */
431
0
static inline int32_t bitset_container_serialized_size_in_bytes(void) {
432
0
    return BITSET_CONTAINER_SIZE_IN_WORDS * 8;
433
0
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: containers.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: roaring.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: roaring64.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: roaring_array.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: bitset.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: convert.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_intersection.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_union.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_equal.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_subset.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_negation.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_xor.c:bitset_container_serialized_size_in_bytes
Unexecuted instantiation: mixed_andnot.c:bitset_container_serialized_size_in_bytes
434
435
/**
436
 * Return the the number of runs.
437
 */
438
int bitset_container_number_of_runs(bitset_container_t *bc);
439
440
bool bitset_container_iterate(const bitset_container_t *cont, uint32_t base,
441
                              roaring_iterator iterator, void *ptr);
442
bool bitset_container_iterate64(const bitset_container_t *cont, uint32_t base,
443
                                roaring_iterator64 iterator, uint64_t high_bits,
444
                                void *ptr);
445
446
/**
447
 * Writes the underlying array to buf, outputs how many bytes were written.
448
 * This is meant to be byte-by-byte compatible with the Java and Go versions of
449
 * Roaring.
450
 * The number of bytes written should be
451
 * bitset_container_size_in_bytes(container).
452
 */
453
int32_t bitset_container_write(const bitset_container_t *container, char *buf);
454
455
/**
456
 * Reads the instance from buf, outputs how many bytes were read.
457
 * This is meant to be byte-by-byte compatible with the Java and Go versions of
458
 * Roaring.
459
 * The number of bytes read should be bitset_container_size_in_bytes(container).
460
 * You need to provide the (known) cardinality.
461
 */
462
int32_t bitset_container_read(int32_t cardinality,
463
                              bitset_container_t *container, const char *buf);
464
/**
465
 * Return the serialized size in bytes of a container (see
466
 * bitset_container_write).
467
 * This is meant to be compatible with the Java and Go versions of Roaring and
468
 * assumes
469
 * that the cardinality of the container is already known or can be computed.
470
 */
471
static inline int32_t bitset_container_size_in_bytes(
472
841
    const bitset_container_t *container) {
473
841
    (void)container;
474
841
    return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
475
841
}
Unexecuted instantiation: croaring_fuzzer.c:bitset_container_size_in_bytes
Unexecuted instantiation: containers.c:bitset_container_size_in_bytes
Unexecuted instantiation: roaring.c:bitset_container_size_in_bytes
Unexecuted instantiation: roaring64.c:bitset_container_size_in_bytes
Unexecuted instantiation: roaring_array.c:bitset_container_size_in_bytes
bitset.c:bitset_container_size_in_bytes
Line
Count
Source
472
841
    const bitset_container_t *container) {
473
841
    (void)container;
474
841
    return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
475
841
}
Unexecuted instantiation: convert.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_intersection.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_union.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_equal.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_subset.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_negation.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_xor.c:bitset_container_size_in_bytes
Unexecuted instantiation: mixed_andnot.c:bitset_container_size_in_bytes
476
477
/**
478
 * Return true if the two containers have the same content.
479
 */
480
bool bitset_container_equals(const bitset_container_t *container1,
481
                             const bitset_container_t *container2);
482
483
/**
484
 * Return true if container1 is a subset of container2.
485
 */
486
bool bitset_container_is_subset(const bitset_container_t *container1,
487
                                const bitset_container_t *container2);
488
489
/**
490
 * If the element of given rank is in this container, supposing that the first
491
 * element has rank start_rank, then the function returns true and sets element
492
 * accordingly.
493
 * Otherwise, it returns false and update start_rank.
494
 */
495
bool bitset_container_select(const bitset_container_t *container,
496
                             uint32_t *start_rank, uint32_t rank,
497
                             uint32_t *element);
498
499
/* Returns the smallest value (assumes not empty) */
500
uint16_t bitset_container_minimum(const bitset_container_t *container);
501
502
/* Returns the largest value (assumes not empty) */
503
uint16_t bitset_container_maximum(const bitset_container_t *container);
504
505
/* Returns the number of values equal or smaller than x */
506
int bitset_container_rank(const bitset_container_t *container, uint16_t x);
507
508
/* bulk version of bitset_container_rank(); return number of consumed elements
509
 */
510
uint32_t bitset_container_rank_many(const bitset_container_t *container,
511
                                    uint64_t start_rank, const uint32_t *begin,
512
                                    const uint32_t *end, uint64_t *ans);
513
514
/* Returns the index of x , if not exsist return -1 */
515
int bitset_container_get_index(const bitset_container_t *container, uint16_t x);
516
517
/* Returns the index of the first value equal or larger than x, or -1 */
518
int bitset_container_index_equalorlarger(const bitset_container_t *container,
519
                                         uint16_t x);
520
521
#ifdef __cplusplus
522
}
523
}
524
}  // extern "C" { namespace roaring { namespace internal {
525
#endif
526
527
#endif /* INCLUDE_CONTAINERS_BITSET_H_ */