/src/croaring/include/roaring/roaring_array.h
Line | Count | Source |
1 | | /* |
2 | | * roaring_array.h |
3 | | * |
4 | | * This file declares the roaring_array helper structure and the operations |
5 | | * used to manage it. A roaring array is the top-level index used by a 32-bit |
6 | | * Roaring bitmap: it stores sorted 16-bit high keys alongside the container |
7 | | * pointers and type codes associated with each key. |
8 | | * |
9 | | * In effect, it is the directory that maps each populated 16-bit chunk of the |
10 | | * 32-bit value space to the container holding that chunk's low 16-bit values. |
11 | | * The functions in this header handle allocation, lookup, insertion, |
12 | | * replacement, copying, serialization support, and structural updates on that |
13 | | * directory. |
14 | | */ |
15 | | #ifndef INCLUDE_ROARING_ARRAY_H |
16 | | #define INCLUDE_ROARING_ARRAY_H |
17 | | |
18 | | #include <assert.h> |
19 | | #include <stdbool.h> |
20 | | #include <stdint.h> |
21 | | |
22 | | #include <roaring/array_util.h> |
23 | | #include <roaring/containers/containers.h> // get_writable_copy_if_shared() |
24 | | |
25 | | #ifdef __cplusplus |
26 | | extern "C" { |
27 | | namespace roaring { |
28 | | |
29 | | // Note: in pure C++ code, you should avoid putting `using` in header files |
30 | | using api::roaring_array_t; |
31 | | |
32 | | namespace internal { |
33 | | #endif |
34 | | |
35 | | enum { |
36 | | SERIAL_COOKIE_NO_RUNCONTAINER = 12346, |
37 | | SERIAL_COOKIE = 12347, |
38 | | FROZEN_COOKIE = 13766, |
39 | | NO_OFFSET_THRESHOLD = 4 |
40 | | }; |
41 | | |
42 | | /** |
43 | | * Create a new roaring array |
44 | | */ |
45 | | roaring_array_t *ra_create(void); |
46 | | |
47 | | /** |
48 | | * Initialize an existing roaring array with the specified capacity (in number |
49 | | * of containers) |
50 | | */ |
51 | | bool ra_init_with_capacity(roaring_array_t *new_ra, uint32_t cap); |
52 | | |
53 | | /** |
54 | | * Initialize with zero capacity |
55 | | */ |
56 | | void ra_init(roaring_array_t *t); |
57 | | |
58 | | /** |
59 | | * Copies this roaring array, we assume that dest is not initialized |
60 | | */ |
61 | | bool ra_copy(const roaring_array_t *source, roaring_array_t *dest, |
62 | | bool copy_on_write); |
63 | | |
64 | | /* |
65 | | * Shrinks the capacity, returns the number of bytes saved. |
66 | | */ |
67 | | int ra_shrink_to_fit(roaring_array_t *ra); |
68 | | |
69 | | /** |
70 | | * Copies this roaring array, we assume that dest is initialized |
71 | | */ |
72 | | bool ra_overwrite(const roaring_array_t *source, roaring_array_t *dest, |
73 | | bool copy_on_write); |
74 | | |
75 | | /** |
76 | | * Frees the memory used by a roaring array |
77 | | */ |
78 | | void ra_clear(roaring_array_t *r); |
79 | | |
80 | | /** |
81 | | * Frees the memory used by a roaring array, but does not free the containers |
82 | | */ |
83 | | void ra_clear_without_containers(roaring_array_t *r); |
84 | | |
85 | | /** |
86 | | * Frees just the containers |
87 | | */ |
88 | | void ra_clear_containers(roaring_array_t *ra); |
89 | | |
90 | | /** |
91 | | * Get the index corresponding to a 16-bit key |
92 | | */ |
93 | 87.2k | inline int32_t ra_get_index(const roaring_array_t *ra, uint16_t x) { |
94 | 87.2k | if ((ra->size == 0) || ra->keys[ra->size - 1] == x) return ra->size - 1; |
95 | 42.0k | return binarySearch(ra->keys, (int32_t)ra->size, x); |
96 | 87.2k | } |
97 | | |
98 | | /** |
99 | | * Retrieves the container at index i, filling in the typecode |
100 | | */ |
101 | | inline container_t *ra_get_container_at_index(const roaring_array_t *ra, |
102 | 573k | uint16_t i, uint8_t *typecode) { |
103 | 573k | *typecode = ra->typecodes[i]; |
104 | 573k | return ra->containers[i]; |
105 | 573k | } |
106 | | |
107 | | /** |
108 | | * Retrieves the key at index i |
109 | | */ |
110 | 430k | inline uint16_t ra_get_key_at_index(const roaring_array_t *ra, uint16_t i) { |
111 | 430k | return ra->keys[i]; |
112 | 430k | } |
113 | | |
114 | | /** |
115 | | * Add a new key-value pair at index i |
116 | | */ |
117 | | void ra_insert_new_key_value_at(roaring_array_t *ra, int32_t i, uint16_t key, |
118 | | container_t *c, uint8_t typecode); |
119 | | |
120 | | /** |
121 | | * Append a new key-value pair |
122 | | */ |
123 | | void ra_append(roaring_array_t *ra, uint16_t key, container_t *c, |
124 | | uint8_t typecode); |
125 | | |
126 | | /** |
127 | | * Append a new key-value pair to ra, cloning (in COW sense) a value from sa |
128 | | * at index index |
129 | | */ |
130 | | void ra_append_copy(roaring_array_t *ra, const roaring_array_t *sa, |
131 | | uint16_t index, bool copy_on_write); |
132 | | |
133 | | /** |
134 | | * Append new key-value pairs to ra, cloning (in COW sense) values from sa |
135 | | * at indexes |
136 | | * [start_index, end_index) |
137 | | */ |
138 | | void ra_append_copy_range(roaring_array_t *ra, const roaring_array_t *sa, |
139 | | int32_t start_index, int32_t end_index, |
140 | | bool copy_on_write); |
141 | | |
142 | | /** appends from sa to ra, ending with the greatest key that is |
143 | | * is less or equal stopping_key |
144 | | */ |
145 | | void ra_append_copies_until(roaring_array_t *ra, const roaring_array_t *sa, |
146 | | uint16_t stopping_key, bool copy_on_write); |
147 | | |
148 | | /** appends from sa to ra, starting with the smallest key that is |
149 | | * is strictly greater than before_start |
150 | | */ |
151 | | |
152 | | void ra_append_copies_after(roaring_array_t *ra, const roaring_array_t *sa, |
153 | | uint16_t before_start, bool copy_on_write); |
154 | | |
155 | | /** |
156 | | * Move the key-value pairs to ra from sa at indexes |
157 | | * [start_index, end_index), old array should not be freed |
158 | | * (use ra_clear_without_containers) |
159 | | **/ |
160 | | void ra_append_move_range(roaring_array_t *ra, roaring_array_t *sa, |
161 | | int32_t start_index, int32_t end_index); |
162 | | /** |
163 | | * Append new key-value pairs to ra, from sa at indexes |
164 | | * [start_index, end_index) |
165 | | */ |
166 | | void ra_append_range(roaring_array_t *ra, roaring_array_t *sa, |
167 | | int32_t start_index, int32_t end_index, |
168 | | bool copy_on_write); |
169 | | |
170 | | /** |
171 | | * Set the container at the corresponding index using the specified |
172 | | * typecode. |
173 | | */ |
174 | | inline void ra_set_container_at_index(const roaring_array_t *ra, int32_t i, |
175 | 113k | container_t *c, uint8_t typecode) { |
176 | 113k | assert(i < ra->size); |
177 | 113k | ra->containers[i] = c; |
178 | 113k | ra->typecodes[i] = typecode; |
179 | 113k | } |
180 | | |
181 | | container_t *ra_get_container(roaring_array_t *ra, uint16_t x, |
182 | | uint8_t *typecode); |
183 | | |
184 | | /** |
185 | | * If needed, increase the capacity of the array so that it can fit k values |
186 | | * (at |
187 | | * least); |
188 | | */ |
189 | | bool extend_array(roaring_array_t *ra, int32_t k); |
190 | | |
191 | 13.5k | inline int32_t ra_get_size(const roaring_array_t *ra) { return ra->size; } |
192 | | |
193 | | static inline int32_t ra_advance_until(const roaring_array_t *ra, uint16_t x, |
194 | 497 | int32_t pos) { |
195 | 497 | return advanceUntil(ra->keys, pos, ra->size, x); |
196 | 497 | } Unexecuted instantiation: croaring_fuzzer_cc.cc:roaring::internal::ra_advance_until(roaring::api::roaring_array_s const*, unsigned short, int) roaring.c:ra_advance_until Line | Count | Source | 194 | 497 | int32_t pos) { | 195 | 497 | return advanceUntil(ra->keys, pos, ra->size, x); | 196 | 497 | } |
Unexecuted instantiation: roaring_array.c:ra_advance_until Unexecuted instantiation: croaring_fuzzer.c:ra_advance_until Unexecuted instantiation: roaring64.c:ra_advance_until |
197 | | |
198 | | int32_t ra_advance_until_freeing(roaring_array_t *ra, uint16_t x, int32_t pos); |
199 | | |
200 | | void ra_downsize(roaring_array_t *ra, int32_t new_length); |
201 | | |
202 | | inline void ra_replace_key_and_container_at_index(roaring_array_t *ra, |
203 | | int32_t i, uint16_t key, |
204 | | container_t *c, |
205 | 155k | uint8_t typecode) { |
206 | 155k | assert(i < ra->size); |
207 | | |
208 | 155k | ra->keys[i] = key; |
209 | 155k | ra->containers[i] = c; |
210 | 155k | ra->typecodes[i] = typecode; |
211 | 155k | } |
212 | | |
213 | | // write set bits to an array |
214 | | void ra_to_uint32_array(const roaring_array_t *ra, uint32_t *ans); |
215 | | |
216 | | /** |
217 | | * write a bitmap to a buffer. This is meant to be compatible with |
218 | | * the |
219 | | * Java and Go versions. Return the size in bytes of the serialized |
220 | | * output (which should be ra_portable_size_in_bytes(ra)). |
221 | | */ |
222 | | size_t ra_portable_serialize(const roaring_array_t *ra, char *buf); |
223 | | |
224 | | /** |
225 | | * read a bitmap from a serialized version. This is meant to be compatible |
226 | | * with the Java and Go versions. |
227 | | * maxbytes indicates how many bytes available from buf. |
228 | | * When the function returns true, roaring_array_t is populated with the data |
229 | | * and *readbytes indicates how many bytes were read. In all cases, if the |
230 | | * function returns true, then maxbytes >= *readbytes. |
231 | | */ |
232 | | bool ra_portable_deserialize(roaring_array_t *ra, const char *buf, |
233 | | const size_t maxbytes, size_t *readbytes); |
234 | | |
235 | | /** |
236 | | * Quickly checks whether there is a serialized bitmap at the pointer, |
237 | | * not exceeding size "maxbytes" in bytes. This function does not allocate |
238 | | * memory dynamically. |
239 | | * |
240 | | * This function returns 0 if and only if no valid bitmap is found. |
241 | | * Otherwise, it returns how many bytes are occupied by the bitmap data. |
242 | | */ |
243 | | size_t ra_portable_deserialize_size(const char *buf, const size_t maxbytes); |
244 | | |
245 | | /** |
246 | | * How many bytes are required to serialize this bitmap (meant to be |
247 | | * compatible |
248 | | * with Java and Go versions) |
249 | | */ |
250 | | size_t ra_portable_size_in_bytes(const roaring_array_t *ra); |
251 | | |
252 | | /** |
253 | | * return true if it contains at least one run container. |
254 | | */ |
255 | | bool ra_has_run_container(const roaring_array_t *ra); |
256 | | |
257 | | /** |
258 | | * Size of the header when serializing (meant to be compatible |
259 | | * with Java and Go versions) |
260 | | */ |
261 | | uint32_t ra_portable_header_size(const roaring_array_t *ra); |
262 | | |
263 | | /** |
264 | | * If the container at the index i is share, unshare it (creating a local |
265 | | * copy if needed). |
266 | | */ |
267 | | static inline void ra_unshare_container_at_index(roaring_array_t *ra, |
268 | 64.7k | uint16_t i) { |
269 | | assert(i < ra->size); |
270 | 64.7k | ra->containers[i] = |
271 | 64.7k | get_writable_copy_if_shared(ra->containers[i], &ra->typecodes[i]); |
272 | 64.7k | } Unexecuted instantiation: croaring_fuzzer_cc.cc:roaring::internal::ra_unshare_container_at_index(roaring::api::roaring_array_s*, unsigned short) roaring.c:ra_unshare_container_at_index Line | Count | Source | 268 | 64.7k | uint16_t i) { | 269 | | assert(i < ra->size); | 270 | 64.7k | ra->containers[i] = | 271 | 64.7k | get_writable_copy_if_shared(ra->containers[i], &ra->typecodes[i]); | 272 | 64.7k | } |
Unexecuted instantiation: roaring_array.c:ra_unshare_container_at_index Unexecuted instantiation: croaring_fuzzer.c:ra_unshare_container_at_index Unexecuted instantiation: roaring64.c:ra_unshare_container_at_index |
273 | | |
274 | | /** |
275 | | * remove at index i, sliding over all entries after i |
276 | | */ |
277 | | void ra_remove_at_index(roaring_array_t *ra, int32_t i); |
278 | | |
279 | | /** |
280 | | * clears all containers, sets the size at 0 and shrinks the memory usage. |
281 | | */ |
282 | | void ra_reset(roaring_array_t *ra); |
283 | | |
284 | | /** |
285 | | * remove at index i, sliding over all entries after i. Free removed container. |
286 | | */ |
287 | | void ra_remove_at_index_and_free(roaring_array_t *ra, int32_t i); |
288 | | |
289 | | /** |
290 | | * remove a chunk of indices, sliding over entries after it |
291 | | */ |
292 | | // void ra_remove_index_range(roaring_array_t *ra, int32_t begin, int32_t end); |
293 | | |
294 | | // used in inplace andNot only, to slide left the containers from |
295 | | // the mutated RoaringBitmap that are after the largest container of |
296 | | // the argument RoaringBitmap. It is followed by a call to resize. |
297 | | // |
298 | | void ra_copy_range(roaring_array_t *ra, uint32_t begin, uint32_t end, |
299 | | uint32_t new_begin); |
300 | | |
301 | | /** |
302 | | * Shifts rightmost $count containers to the left (distance < 0) or |
303 | | * to the right (distance > 0). |
304 | | * Allocates memory if necessary. |
305 | | * This function doesn't free or create new containers. |
306 | | * Caller is responsible for that. |
307 | | */ |
308 | | void ra_shift_tail(roaring_array_t *ra, int32_t count, int32_t distance); |
309 | | |
310 | | #ifdef __cplusplus |
311 | | } // namespace internal |
312 | | } |
313 | | } // extern "C" { namespace roaring { |
314 | | #endif |
315 | | |
316 | | #endif |