Coverage Report

Created: 2025-07-12 06:04

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