/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_ */ |