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