1 | /* |
2 | * cdt.h |
3 | * |
4 | * Copyright (C) 2015-2018 Aerospike, Inc. |
5 | * |
6 | * Portions may be licensed to Aerospike, Inc. under one or more contributor |
7 | * license agreements. |
8 | * |
9 | * This program is free software: you can redistribute it and/or modify it under |
10 | * the terms of the GNU Affero General Public License as published by the Free |
11 | * Software Foundation, either version 3 of the License, or (at your option) any |
12 | * later version. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, but WITHOUT |
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
16 | * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
17 | * details. |
18 | * |
19 | * You should have received a copy of the GNU Affero General Public License |
20 | * along with this program. If not, see http://www.gnu.org/licenses/ |
21 | */ |
22 | |
23 | #pragma once |
24 | |
25 | #include <stdarg.h> |
26 | #include <stddef.h> |
27 | #include <stdint.h> |
28 | |
29 | #include "aerospike/as_msgpack.h" |
30 | |
31 | #include "base/datamodel.h" |
32 | #include "base/proto.h" |
33 | |
34 | #include "dynbuf.h" |
35 | |
36 | |
37 | //========================================================== |
38 | // Typedefs & constants. |
39 | // |
40 | |
41 | //#define CDT_DEBUG_VERIFY |
42 | |
43 | #define CDT_MAX_PACKED_INT_SZ (sizeof(uint64_t) + 1) |
44 | #define CDT_MAX_STACK_OBJ_SZ (1024 * 1024) |
45 | #define CDT_MAX_PARAM_LIST_COUNT (1024 * 1024) |
46 | |
47 | typedef struct rollback_alloc_s { |
48 | cf_ll_buf *ll_buf; |
49 | size_t malloc_list_sz; |
50 | size_t malloc_list_cap; |
51 | bool malloc_ns; |
52 | void *malloc_list[]; |
53 | } rollback_alloc; |
54 | |
55 | #define define_rollback_alloc(__name, __alloc_buf, __rollback_size, __malloc_ns) \ |
56 | uint8_t __name ## __mem[sizeof(rollback_alloc) + sizeof(void *) * (__alloc_buf ? 0 : __rollback_size)]; \ |
57 | rollback_alloc * const __name = (rollback_alloc *)__name ## __mem; \ |
58 | __name->ll_buf = __alloc_buf; \ |
59 | __name->malloc_list_sz = 0; \ |
60 | __name->malloc_list_cap = (__alloc_buf ? 0 : __rollback_size); \ |
61 | __name->malloc_ns = __malloc_ns; |
62 | |
63 | typedef struct cdt_process_state_s { |
64 | as_cdt_optype type; |
65 | as_unpacker pk; |
66 | uint32_t ele_count; |
67 | } cdt_process_state; |
68 | |
69 | typedef struct cdt_payload_s { |
70 | const uint8_t *ptr; |
71 | uint32_t sz; |
72 | } cdt_payload; |
73 | |
74 | typedef struct cdt_result_data_s { |
75 | as_bin *result; |
76 | rollback_alloc *alloc; |
77 | result_type_t type; |
78 | as_cdt_op_flags flags; |
79 | bool is_multi; |
80 | } cdt_result_data; |
81 | |
82 | typedef struct cdt_mem_s { |
83 | uint8_t type; |
84 | uint32_t sz; |
85 | uint8_t data[]; |
86 | } __attribute__ ((__packed__)) cdt_mem; |
87 | |
88 | typedef struct { |
89 | uint32_t data_offset; // 0 starts at cdt_mem->data[0] |
90 | uint32_t data_sz; |
91 | uint32_t idx; |
92 | uint8_t type; |
93 | uint8_t *idx_mem; |
94 | } cdt_ctx_list_stack_entry; |
95 | |
96 | typedef struct cdt_context_s { |
97 | as_bin *b; |
98 | as_particle *orig; |
99 | rollback_alloc *alloc_buf; |
100 | uint32_t data_offset; // 0 starts at cdt_mem->data[0] |
101 | uint32_t data_sz; // 0 means no sub-context |
102 | |
103 | uint32_t stack_idx; |
104 | uint32_t stack_cap; |
105 | cdt_ctx_list_stack_entry stack[2]; |
106 | cdt_ctx_list_stack_entry *pstack; |
107 | |
108 | uint32_t top_content_sz; |
109 | uint32_t top_content_off; // 0 means no top level indexes |
110 | uint32_t top_ele_count; |
111 | |
112 | int32_t delta_off; |
113 | int32_t delta_sz; |
114 | } cdt_context; |
115 | |
116 | typedef bool (*cdt_subcontext_fn)(cdt_context *ctx, as_unpacker *val); |
117 | |
118 | typedef struct cdt_op_mem_s { |
119 | cdt_context ctx; |
120 | cdt_result_data result; |
121 | rollback_alloc *alloc_idx; |
122 | int ret_code; |
123 | } cdt_op_mem; |
124 | |
125 | typedef struct cdt_container_builder_s { |
126 | as_particle *particle; |
127 | uint8_t *write_ptr; |
128 | uint32_t *sz; |
129 | uint32_t ele_count; |
130 | } cdt_container_builder; |
131 | |
132 | typedef struct cdt_op_table_entry_s { |
133 | uint32_t count; |
134 | uint32_t opt_args; |
135 | const char *name; |
136 | const as_cdt_paramtype *args; |
137 | } cdt_op_table_entry; |
138 | |
139 | typedef struct cdt_calc_delta_s { |
140 | int64_t incr_int; |
141 | double incr_double; |
142 | |
143 | as_val_t type; |
144 | |
145 | int64_t value_int; |
146 | double value_double; |
147 | } cdt_calc_delta; |
148 | |
149 | typedef struct msgpacked_index_s { |
150 | uint8_t *ptr; |
151 | uint32_t ele_sz; |
152 | uint32_t ele_count; |
153 | } msgpacked_index; |
154 | |
155 | typedef struct offset_index_s { |
156 | msgpacked_index _; |
157 | |
158 | const uint8_t *contents; |
159 | uint32_t content_sz; |
160 | bool is_partial; |
161 | } offset_index; |
162 | |
163 | // Value order index. |
164 | typedef struct order_index_s { |
165 | msgpacked_index _; |
166 | uint32_t max_idx; |
167 | } order_index; |
168 | |
169 | typedef struct order_index_find_s { |
170 | uint32_t start; |
171 | uint32_t count; |
172 | uint32_t target; |
173 | uint32_t result; |
174 | bool found; |
175 | } order_index_find; |
176 | |
177 | typedef msgpack_compare_t (*order_heap_compare_fn)(const void *ptr, uint32_t index0, uint32_t index1); |
178 | |
179 | // Value order heap. |
180 | typedef struct order_heap_s { |
181 | order_index _; |
182 | const void *userdata; |
183 | order_heap_compare_fn cmp_fn; |
184 | msgpack_compare_t cmp; |
185 | uint32_t filled; |
186 | } order_heap; |
187 | |
188 | typedef struct cdt_packed_op_s { |
189 | // Input. |
190 | const uint8_t *packed; |
191 | uint32_t packed_sz; |
192 | |
193 | // Parsed. |
194 | uint32_t ele_count; |
195 | const uint8_t *contents; |
196 | uint32_t content_sz; |
197 | |
198 | // Result. |
199 | uint32_t new_ele_count; |
200 | } cdt_packed_op; |
201 | |
202 | struct order_index_adjust_s; |
203 | typedef uint32_t (*order_index_adjust_func)(const struct order_index_adjust_s *via, uint32_t src); |
204 | |
205 | typedef struct order_index_adjust_s { |
206 | order_index_adjust_func f; |
207 | uint32_t upper; |
208 | uint32_t lower; |
209 | int32_t delta; |
210 | } order_index_adjust; |
211 | |
212 | typedef enum { |
213 | CDT_FIND_ITEMS_IDXS_FOR_LIST_VALUE, |
214 | CDT_FIND_ITEMS_IDXS_FOR_MAP_KEY, |
215 | CDT_FIND_ITEMS_IDXS_FOR_MAP_VALUE |
216 | } cdt_find_items_idxs_type; |
217 | |
218 | #define define_offset_index(__name, __contents, __content_sz, __ele_count, __alloc) \ |
219 | offset_index __name; \ |
220 | offset_index_init(&__name, NULL, __ele_count, __contents, __content_sz); \ |
221 | uint8_t __name ## __vlatemp[1 + offset_index_vla_sz(&__name)]; \ |
222 | offset_index_alloc_temp(&__name, __name ## __vlatemp, __alloc) |
223 | |
224 | // NULL if !__cond |
225 | #define definep_cond_order_index2(__name, __max_idx, __alloc_count, __cond, __alloc) \ |
226 | uint8_t __name ## __vlatemp[(__cond) ? sizeof(order_index) + cdt_vla_sz(order_index_calc_size(__max_idx, __alloc_count)) : 1]; \ |
227 | order_index *__name = NULL; \ |
228 | if (__cond) { \ |
229 | __name = (order_index *)__name ## __vlatemp; \ |
230 | order_index_init2_temp(__name, __name ## __vlatemp + sizeof(order_index), __alloc, __max_idx, __alloc_count); \ |
231 | } |
232 | |
233 | #define define_order_index(__name, __ele_count, __alloc) \ |
234 | order_index __name; \ |
235 | uint8_t __name ## __vlatemp[1 + cdt_vla_sz(order_index_calc_size(__ele_count, __ele_count))]; \ |
236 | order_index_init2_temp(&__name, __name ## __vlatemp, __alloc, __ele_count, __ele_count) |
237 | |
238 | #define define_order_index2(__name, __max_idx, __alloc_count, __alloc) \ |
239 | order_index __name; \ |
240 | uint8_t __name ## __vlatemp[1 + cdt_vla_sz(order_index_calc_size(__max_idx, __alloc_count))]; \ |
241 | order_index_init2_temp(&__name, __name ## __vlatemp, __alloc, __max_idx, __alloc_count) |
242 | |
243 | #define define_int_list_builder(__name, __alloc, __count) \ |
244 | cdt_container_builder __name; \ |
245 | cdt_int_list_builder_start(&__name, __alloc, __count) |
246 | |
247 | #define define_cdt_idx_mask(__name, __ele_count, __alloc) \ |
248 | uint64_t __name ## __vla[cdt_idx_vla_mask_count(__ele_count)]; \ |
249 | uint64_t *__name = __name ## __vla; \ |
250 | cdt_idx_mask_init_temp(&__name, __ele_count, __alloc) |
251 | |
252 | #define define_cond_cdt_idx_mask(__name, __ele_count, __cond, __alloc) \ |
253 | uint64_t __name ## __vla[__cond ? cdt_idx_vla_mask_count(__ele_count) : 1]; \ |
254 | uint64_t *__name = __name ## __vla; \ |
255 | if (__cond) { \ |
256 | cdt_idx_mask_init_temp(&__name, __ele_count, __alloc); \ |
257 | } |
258 | |
259 | #define define_build_order_heap_by_range(__name, __idx, __count, __ele_count, __udata, __cmp_fn, __success, __alloc) \ |
260 | order_heap __name; \ |
261 | uint8_t __name ## __order_heap_mem__[1 + cdt_vla_sz(order_index_calc_size(__ele_count, __ele_count))]; \ |
262 | bool __success = order_heap_init_build_by_range_temp(&__name, __name ## __order_heap_mem__, __alloc, __idx, __count, __ele_count, __cmp_fn, __udata) |
263 | |
264 | #define VA_NARGS_SEQ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 |
265 | #define (_9, _8, _7, _6, _5, _4, _3, _2, _1, _0, N, ...) N |
266 | #define VA_NARGS_SEQ2N(...) VA_NARGS_EXTRACT_N(__VA_ARGS__) |
267 | #define VA_NARGS(...) VA_NARGS_SEQ2N(_, ##__VA_ARGS__, VA_NARGS_SEQ) |
268 | |
269 | // Get around needing to pass last named arg to va_start(). |
270 | #define CDT_OP_TABLE_GET_PARAMS(state, ...) cdt_process_state_get_params(state, VA_NARGS(__VA_ARGS__), __VA_ARGS__) |
271 | |
272 | static const uint8_t msgpack_nil[1] = {0xC0}; |
273 | |
274 | |
275 | //========================================================== |
276 | // Function declarations. |
277 | // |
278 | |
279 | bool calc_index_count(int64_t in_index, uint64_t in_count, uint32_t ele_count, uint32_t *out_index, uint32_t *out_count, bool is_multi); |
280 | void calc_rel_index_count(int64_t in_index, uint64_t in_count, uint32_t rel_index, int64_t *out_index, uint64_t *out_count); |
281 | |
282 | bool cdt_check_storage_list_contents(const uint8_t *buf, uint32_t sz, uint32_t count); |
283 | |
284 | // cdt_result_data |
285 | bool result_data_set_not_found(cdt_result_data *rd, int64_t index); |
286 | void result_data_set_list_int2x(cdt_result_data *rd, int64_t i1, int64_t i2); |
287 | int result_data_set_index_rank_count(cdt_result_data *rd, uint32_t start, uint32_t count, uint32_t ele_count); |
288 | int result_data_set_range(cdt_result_data *rd, uint32_t start, uint32_t count, uint32_t ele_count); |
289 | void result_data_set_by_irc(cdt_result_data *rd, const order_index *ordidx, const order_index *idx_map, uint32_t total_count); |
290 | void result_data_set_by_itemlist_irc(cdt_result_data *rd, const order_index *items_ord, order_index *ranks, uint32_t total_count); |
291 | void result_data_set_int_list_by_mask(cdt_result_data *rd, const uint64_t *mask, uint32_t count, uint32_t ele_count); |
292 | |
293 | // as_bin |
294 | void as_bin_set_int(as_bin *b, int64_t value); |
295 | void as_bin_set_double(as_bin *b, double value); |
296 | void as_bin_set_unordered_empty_list(as_bin *b, rollback_alloc *alloc_buf); |
297 | void as_bin_set_empty_packed_map(as_bin *b, rollback_alloc *alloc_buf, uint8_t flags); |
298 | |
299 | // cdt_delta_value |
300 | bool cdt_calc_delta_init(cdt_calc_delta *cdv, const cdt_payload *delta_value, bool is_decrement); |
301 | bool cdt_calc_delta_add(cdt_calc_delta *cdv, as_unpacker *pk_value); |
302 | void cdt_calc_delta_pack_and_result(cdt_calc_delta *cdv, cdt_payload *value, as_bin *result); |
303 | |
304 | // cdt_payload |
305 | bool cdt_payload_is_int(const cdt_payload *payload); |
306 | int64_t cdt_payload_get_int64(const cdt_payload *payload); |
307 | void cdt_payload_pack_int(cdt_payload *packed, int64_t value); |
308 | void cdt_payload_pack_double(cdt_payload *packed, double value); |
309 | |
310 | // cdt_process_state |
311 | bool cdt_process_state_init(cdt_process_state *cdt_state, const as_msg_op *op); |
312 | bool cdt_process_state_get_params(cdt_process_state *state, size_t n, ...); |
313 | const char *cdt_process_state_get_op_name(const cdt_process_state *state); |
314 | |
315 | // cdt_process_state_packed_list |
316 | bool cdt_process_state_packed_list_modify_optype(cdt_process_state *state, cdt_op_mem *com); |
317 | bool cdt_process_state_packed_list_read_optype(cdt_process_state *state, cdt_op_mem *com); |
318 | |
319 | void cdt_container_builder_add(cdt_container_builder *builder, const uint8_t *buf, uint32_t sz); |
320 | void cdt_container_builder_add_n(cdt_container_builder *builder, const uint8_t *buf, uint32_t count, uint32_t sz); |
321 | void cdt_container_builder_add_int64(cdt_container_builder *builder, int64_t value); |
322 | void cdt_container_builder_add_int_range(cdt_container_builder *builder, uint32_t start, uint32_t count, uint32_t ele_count, bool reverse); |
323 | void cdt_container_builder_set_result(cdt_container_builder *builder, cdt_result_data *result); |
324 | |
325 | void cdt_list_builder_start(cdt_container_builder *builder, rollback_alloc *alloc_buf, uint32_t ele_count, uint32_t max_sz); |
326 | void cdt_map_builder_start(cdt_container_builder *builder, rollback_alloc *alloc_buf, uint32_t ele_count, uint32_t content_max_sz, uint8_t flags); |
327 | |
328 | // cdt_process_state_packed_map |
329 | bool cdt_process_state_packed_map_modify_optype(cdt_process_state *state, cdt_op_mem *com); |
330 | bool cdt_process_state_packed_map_read_optype(cdt_process_state *state, cdt_op_mem *com); |
331 | |
332 | // cdt_process_state_context_eval |
333 | bool cdt_process_state_context_eval(cdt_process_state *state, cdt_op_mem *com); |
334 | |
335 | // rollback_alloc |
336 | void rollback_alloc_push(rollback_alloc *packed_alloc, void *ptr); |
337 | uint8_t *rollback_alloc_reserve(rollback_alloc *alloc_buf, size_t sz); |
338 | void rollback_alloc_rollback(rollback_alloc *alloc_buf); |
339 | bool rollback_alloc_from_msgpack(rollback_alloc *alloc_buf, as_bin *b, const cdt_payload *seg); |
340 | |
341 | // msgpacked_index |
342 | void msgpacked_index_set(msgpacked_index *idxs, uint32_t index, uint32_t value); |
343 | void msgpacked_index_incr(msgpacked_index *idxs, uint32_t index); |
344 | void msgpacked_index_set_ptr(msgpacked_index *idxs, uint8_t *ptr); |
345 | void *msgpacked_index_get_mem(const msgpacked_index *idxs, uint32_t index); |
346 | uint32_t msgpacked_index_size(const msgpacked_index *idxs); |
347 | uint32_t msgpacked_index_ptr2value(const msgpacked_index *idxs, const void *ptr); |
348 | uint32_t msgpacked_index_get(const msgpacked_index *idxs, uint32_t index); |
349 | void msgpacked_index_print(const msgpacked_index *idxs, const char *name); |
350 | |
351 | // offset_index |
352 | void offset_index_init(offset_index *offidx, uint8_t *idx_mem_ptr, uint32_t ele_count, const uint8_t *contents, uint32_t content_sz); |
353 | void offset_index_set(offset_index *offidx, uint32_t index, uint32_t value); |
354 | bool offset_index_set_next(offset_index *offidx, uint32_t index, uint32_t value); |
355 | void offset_index_set_filled(offset_index *offidx, uint32_t ele_filled); |
356 | void offset_index_set_ptr(offset_index *offidx, uint8_t *idx_mem, const uint8_t *packed_mem); |
357 | void offset_index_copy(offset_index *dest, const offset_index *src, uint32_t d_start, uint32_t s_start, uint32_t count, int delta); |
358 | void offset_index_move_ele(offset_index *dest, const offset_index *src, uint32_t ele_idx, uint32_t to_idx); |
359 | void offset_index_append_size(offset_index *offidx, uint32_t delta); |
360 | |
361 | bool offset_index_find_items(offset_index *full_offidx, cdt_find_items_idxs_type find_type, as_unpacker *items_pk, order_index *items_ordidx_r, bool inverted, uint64_t *rm_mask, uint32_t *rm_count_r, order_index *rm_ranks_r, rollback_alloc *alloc); |
362 | |
363 | void *offset_index_get_mem(const offset_index *offidx, uint32_t index); |
364 | uint32_t offset_index_size(const offset_index *offidx); |
365 | bool offset_index_is_null(const offset_index *offidx); |
366 | bool offset_index_is_valid(const offset_index *offidx); |
367 | bool offset_index_is_full(const offset_index *offidx); |
368 | uint32_t offset_index_get_const(const offset_index *offidx, uint32_t idx); |
369 | uint32_t offset_index_get_delta_const(const offset_index *offidx, uint32_t index); |
370 | uint32_t offset_index_get_filled(const offset_index *offidx); |
371 | |
372 | bool offset_index_check_order_and_fill(offset_index *offidx, bool pairs); |
373 | |
374 | uint32_t offset_index_vla_sz(const offset_index *offidx); |
375 | void offset_index_alloc_temp(offset_index *offidx, uint8_t *mem_temp, rollback_alloc *alloc); |
376 | |
377 | void offset_index_print(const offset_index *offidx, const char *name); |
378 | void offset_index_delta_print(const offset_index *offidx, const char *name); |
379 | |
380 | // order_index |
381 | void order_index_init(order_index *ordidx, uint8_t *ptr, uint32_t ele_count); |
382 | void order_index_init2(order_index *ordidx, uint8_t *ptr, uint32_t max_idx, uint32_t ele_count); |
383 | void order_index_init2_temp(order_index *ordidx, uint8_t *mem_temp, rollback_alloc *alloc_idx, uint32_t max_idx, uint32_t ele_count); |
384 | void order_index_init_ref(order_index *dst, const order_index *src, uint32_t start, uint32_t count); |
385 | void order_index_set(order_index *ordidx, uint32_t index, uint32_t value); |
386 | void order_index_set_ptr(order_index *ordidx, uint8_t *ptr); |
387 | void order_index_incr(order_index *ordidx, uint32_t index); |
388 | void order_index_clear(order_index *ordidx); |
389 | bool order_index_sorted_mark_dup_eles(order_index *ordidx, const offset_index *full_offidx, uint32_t *count_r, uint32_t *sz_r); |
390 | |
391 | uint32_t order_index_size(const order_index *ordidx); |
392 | bool order_index_is_null(const order_index *ordidx); |
393 | bool order_index_is_valid(const order_index *ordidx); |
394 | bool order_index_is_filled(const order_index *ordidx); |
395 | |
396 | void *order_index_get_mem(const order_index *ordidx, uint32_t index); |
397 | uint32_t order_index_ptr2value(const order_index *ordidx, const void *ptr); |
398 | uint32_t order_index_get(const order_index *ordidx, uint32_t index); |
399 | |
400 | void order_index_find_rank_by_value(const order_index *ordidx, const cdt_payload *value, const offset_index *full_offidx, order_index_find *find, bool skip_key); |
401 | |
402 | uint32_t order_index_get_ele_size(const order_index *ordidx, uint32_t count, const offset_index *full_offidx); |
403 | uint8_t *order_index_write_eles(const order_index *ordidx, uint32_t count, const offset_index *full_offidx, uint8_t *ptr, bool invert); |
404 | |
405 | uint32_t order_index_adjust_value(const order_index_adjust *via, uint32_t src); |
406 | void order_index_copy(order_index *dest, const order_index *src, uint32_t d_start, uint32_t s_start, uint32_t count, const order_index_adjust *adjust); |
407 | size_t order_index_calc_size(uint32_t max_idx, uint32_t ele_count); |
408 | |
409 | void order_index_print(const order_index *ordidx, const char *name); |
410 | |
411 | // order_heap |
412 | bool order_heap_init_build_by_range_temp(order_heap *heap, uint8_t *heap_mem, rollback_alloc *alloc_idx, uint32_t idx, uint32_t count, uint32_t ele_count, order_heap_compare_fn cmp_fn, const void *udata); |
413 | void order_heap_swap(order_heap *heap, uint32_t index1, uint32_t index2); |
414 | bool order_heap_remove_top(order_heap *heap); |
415 | bool order_heap_replace_top(order_heap *heap, uint32_t value); |
416 | bool order_heap_heapify(order_heap *heap, uint32_t index); |
417 | bool order_heap_build(order_heap *heap, bool init); |
418 | bool order_heap_order_at_end(order_heap *heap, uint32_t count); |
419 | void order_heap_reverse_end(order_heap *heap, uint32_t count); |
420 | |
421 | void order_heap_print(const order_heap *heap); |
422 | |
423 | // cdt_idx_mask |
424 | void cdt_idx_mask_init_temp(uint64_t **mask, uint32_t ele_count, rollback_alloc *alloc); |
425 | void cdt_idx_mask_set(uint64_t *mask, uint32_t idx); |
426 | void cdt_idx_mask_set_by_ordidx(uint64_t *mask, const order_index *ordidx, uint32_t start, uint32_t count, bool inverted); |
427 | void cdt_idx_mask_set_by_irc(uint64_t *mask, const order_index *rankcount, const order_index *idx_map, bool inverted); |
428 | void cdt_idx_mask_invert(uint64_t *mask, uint32_t ele_count); |
429 | |
430 | uint64_t cdt_idx_mask_get(const uint64_t *mask, uint32_t idx); |
431 | size_t cdt_idx_mask_bit_count(const uint64_t *mask, uint32_t ele_count); |
432 | |
433 | bool cdt_idx_mask_is_set(const uint64_t *mask, uint32_t idx); |
434 | |
435 | uint32_t cdt_idx_mask_find(const uint64_t *mask, uint32_t start, uint32_t end, bool is_find0); |
436 | uint8_t *cdt_idx_mask_write_eles(const uint64_t *mask, uint32_t count, const offset_index *full_offidx, uint8_t *ptr, bool invert); |
437 | uint32_t cdt_idx_mask_get_content_sz(const uint64_t *mask, uint32_t count, const offset_index *full_offidx); |
438 | |
439 | void cdt_idx_mask_print(const uint64_t *mask, uint32_t ele_count, const char *name); |
440 | |
441 | // list |
442 | bool list_full_offset_index_fill_all(offset_index *offidx); |
443 | bool list_order_index_sort(order_index *ordidx, const offset_index *full_offidx, as_cdt_sort_flags flags); |
444 | |
445 | bool list_param_parse(const cdt_payload *items, as_unpacker *pk, uint32_t *count_r); |
446 | |
447 | bool list_subcontext_by_index(cdt_context *ctx, as_unpacker *val); |
448 | bool list_subcontext_by_rank(cdt_context *ctx, as_unpacker *val); |
449 | bool list_subcontext_by_key(cdt_context *ctx, as_unpacker *val); |
450 | bool list_subcontext_by_value(cdt_context *ctx, as_unpacker *val); |
451 | |
452 | void cdt_context_unwind_list(cdt_context *ctx, cdt_ctx_list_stack_entry *p); |
453 | |
454 | // map |
455 | bool map_subcontext_by_index(cdt_context *ctx, as_unpacker *val); |
456 | bool map_subcontext_by_rank(cdt_context *ctx, as_unpacker *val); |
457 | bool map_subcontext_by_key(cdt_context *ctx, as_unpacker *val); |
458 | bool map_subcontext_by_value(cdt_context *ctx, as_unpacker *val); |
459 | |
460 | void cdt_context_unwind_map(cdt_context *ctx, cdt_ctx_list_stack_entry *p); |
461 | |
462 | // cdt_context |
463 | uint32_t cdt_context_get_sz(cdt_context *ctx); |
464 | const uint8_t *cdt_context_get_data(cdt_context *ctx); |
465 | uint8_t *cdt_context_create_new_particle(cdt_context *ctx, uint32_t subctx_sz); |
466 | |
467 | cdt_ctx_list_stack_entry *cdt_context_push(cdt_context *ctx, uint32_t idx, uint8_t *idx_mem); |
468 | |
469 | static inline bool |
470 | cdt_context_is_toplvl(const cdt_context *ctx) |
471 | { |
472 | return ctx->data_sz == 0; |
473 | } |
474 | |
475 | // Debugging support |
476 | bool cdt_verify(cdt_context *ctx); |
477 | bool list_verify(const cdt_context *ctx); |
478 | bool map_verify(const cdt_context *ctx); |
479 | |
480 | void print_hex(const uint8_t *packed, uint32_t packed_sz, char *buf, uint32_t buf_sz); |
481 | void print_packed(const uint8_t *packed, uint32_t sz, const char *name); |
482 | void cdt_bin_print(const as_bin *b, const char *name); |
483 | void cdt_context_print(const cdt_context *ctx, const char *name); |
484 | |
485 | |
486 | //========================================================== |
487 | // Inline functions. |
488 | // |
489 | |
490 | static inline bool |
491 | result_data_is_inverted(cdt_result_data *rd) |
492 | { |
493 | return (rd->flags & AS_CDT_OP_FLAG_INVERTED) != 0; |
494 | } |
495 | |
496 | static inline void |
497 | result_data_set(cdt_result_data *rd, uint64_t result_type, bool is_multi) |
498 | { |
499 | rd->type = (result_type_t)(result_type & AS_CDT_OP_FLAG_RESULT_MASK); |
500 | rd->flags = (as_cdt_op_flags)(result_type & (~AS_CDT_OP_FLAG_RESULT_MASK)); |
501 | rd->is_multi = is_multi; |
502 | } |
503 | |
504 | static inline void |
505 | result_data_set_int(cdt_result_data *rd, int64_t value) |
506 | { |
507 | if (rd) { |
508 | as_bin_set_int(rd->result, value); |
509 | } |
510 | } |
511 | |
512 | static inline bool |
513 | result_data_is_return_elements(const cdt_result_data *rd) |
514 | { |
515 | return (rd->type == RESULT_TYPE_KEY || rd->type == RESULT_TYPE_VALUE || |
516 | rd->type == RESULT_TYPE_MAP); |
517 | } |
518 | |
519 | static inline bool |
520 | result_data_is_return_index(const cdt_result_data *rd) |
521 | { |
522 | return (rd->type == RESULT_TYPE_INDEX || rd->type == RESULT_TYPE_REVINDEX); |
523 | } |
524 | |
525 | static inline bool |
526 | result_data_is_return_index_range(const cdt_result_data *rd) |
527 | { |
528 | return (rd->type == RESULT_TYPE_INDEX_RANGE || |
529 | rd->type == RESULT_TYPE_REVINDEX_RANGE); |
530 | } |
531 | |
532 | static inline bool |
533 | result_data_is_return_rank(const cdt_result_data *rd) |
534 | { |
535 | return (rd->type == RESULT_TYPE_REVRANK || rd->type == RESULT_TYPE_RANK); |
536 | } |
537 | |
538 | static inline bool |
539 | result_data_is_return_rank_range(const cdt_result_data *rd) |
540 | { |
541 | return (rd->type == RESULT_TYPE_REVRANK_RANGE || |
542 | rd->type == RESULT_TYPE_RANK_RANGE); |
543 | } |
544 | |
545 | static inline void |
546 | order_heap_set(order_heap *heap, uint32_t index, uint32_t value) |
547 | { |
548 | order_index_set((order_index *)heap, index, value); |
549 | } |
550 | |
551 | static inline uint32_t |
552 | order_heap_get(const order_heap *heap, uint32_t index) |
553 | { |
554 | return order_index_get((const order_index *)heap, index); |
555 | } |
556 | |
557 | // Calculate index given index and max_index. |
558 | static inline int64_t |
559 | calc_index(int64_t index, uint32_t max_index) |
560 | { |
561 | return index < 0 ? (int64_t)max_index + index : index; |
562 | } |
563 | |
564 | static inline bool |
565 | cdt_context_is_modify(const cdt_context *ctx) |
566 | { |
567 | return ctx->alloc_buf != NULL; |
568 | } |
569 | |
570 | static inline bool |
571 | cdt_op_is_modify(const cdt_op_mem *com) |
572 | { |
573 | return cdt_context_is_modify(&com->ctx); |
574 | } |
575 | |
576 | static inline void |
577 | cdt_int_list_builder_start(cdt_container_builder *builder, |
578 | rollback_alloc *alloc_buf, uint32_t ele_count) |
579 | { |
580 | cdt_list_builder_start(builder, alloc_buf, ele_count, |
581 | CDT_MAX_PACKED_INT_SZ * ele_count); |
582 | } |
583 | |
584 | static inline uint32_t |
585 | cdt_vla_sz(uint32_t sz) |
586 | { |
587 | return sz > CDT_MAX_STACK_OBJ_SZ ? 0 : sz; |
588 | } |
589 | |
590 | // cdt_idx_mask |
591 | static inline uint32_t |
592 | cdt_idx_mask_count(uint32_t ele_count) |
593 | { |
594 | return (ele_count + 63) / 64; |
595 | } |
596 | |
597 | static inline uint32_t |
598 | cdt_idx_vla_mask_count(uint32_t ele_count) |
599 | { |
600 | uint32_t count = cdt_idx_mask_count(ele_count); |
601 | |
602 | return (count == 0 || count * sizeof(uint64_t) > CDT_MAX_STACK_OBJ_SZ) ? |
603 | 1 : count; |
604 | } |
605 | |