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
47typedef 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
63typedef struct cdt_process_state_s {
64 as_cdt_optype type;
65 as_unpacker pk;
66 uint32_t ele_count;
67} cdt_process_state;
68
69typedef struct cdt_payload_s {
70 const uint8_t *ptr;
71 uint32_t sz;
72} cdt_payload;
73
74typedef 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
82typedef struct cdt_mem_s {
83 uint8_t type;
84 uint32_t sz;
85 uint8_t data[];
86} __attribute__ ((__packed__)) cdt_mem;
87
88typedef 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
96typedef 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
116typedef bool (*cdt_subcontext_fn)(cdt_context *ctx, as_unpacker *val);
117
118typedef 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
125typedef 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
132typedef 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
139typedef 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
149typedef struct msgpacked_index_s {
150 uint8_t *ptr;
151 uint32_t ele_sz;
152 uint32_t ele_count;
153} msgpacked_index;
154
155typedef 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.
164typedef struct order_index_s {
165 msgpacked_index _;
166 uint32_t max_idx;
167} order_index;
168
169typedef 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
177typedef msgpack_compare_t (*order_heap_compare_fn)(const void *ptr, uint32_t index0, uint32_t index1);
178
179// Value order heap.
180typedef 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
188typedef 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
202struct order_index_adjust_s;
203typedef uint32_t (*order_index_adjust_func)(const struct order_index_adjust_s *via, uint32_t src);
204
205typedef 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
212typedef 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 VA_NARGS_EXTRACT_N(_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
272static const uint8_t msgpack_nil[1] = {0xC0};
273
274
275//==========================================================
276// Function declarations.
277//
278
279bool 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);
280void 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
282bool cdt_check_storage_list_contents(const uint8_t *buf, uint32_t sz, uint32_t count);
283
284// cdt_result_data
285bool result_data_set_not_found(cdt_result_data *rd, int64_t index);
286void result_data_set_list_int2x(cdt_result_data *rd, int64_t i1, int64_t i2);
287int result_data_set_index_rank_count(cdt_result_data *rd, uint32_t start, uint32_t count, uint32_t ele_count);
288int result_data_set_range(cdt_result_data *rd, uint32_t start, uint32_t count, uint32_t ele_count);
289void result_data_set_by_irc(cdt_result_data *rd, const order_index *ordidx, const order_index *idx_map, uint32_t total_count);
290void result_data_set_by_itemlist_irc(cdt_result_data *rd, const order_index *items_ord, order_index *ranks, uint32_t total_count);
291void 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
294void as_bin_set_int(as_bin *b, int64_t value);
295void as_bin_set_double(as_bin *b, double value);
296void as_bin_set_unordered_empty_list(as_bin *b, rollback_alloc *alloc_buf);
297void as_bin_set_empty_packed_map(as_bin *b, rollback_alloc *alloc_buf, uint8_t flags);
298
299// cdt_delta_value
300bool cdt_calc_delta_init(cdt_calc_delta *cdv, const cdt_payload *delta_value, bool is_decrement);
301bool cdt_calc_delta_add(cdt_calc_delta *cdv, as_unpacker *pk_value);
302void cdt_calc_delta_pack_and_result(cdt_calc_delta *cdv, cdt_payload *value, as_bin *result);
303
304// cdt_payload
305bool cdt_payload_is_int(const cdt_payload *payload);
306int64_t cdt_payload_get_int64(const cdt_payload *payload);
307void cdt_payload_pack_int(cdt_payload *packed, int64_t value);
308void cdt_payload_pack_double(cdt_payload *packed, double value);
309
310// cdt_process_state
311bool cdt_process_state_init(cdt_process_state *cdt_state, const as_msg_op *op);
312bool cdt_process_state_get_params(cdt_process_state *state, size_t n, ...);
313const char *cdt_process_state_get_op_name(const cdt_process_state *state);
314
315// cdt_process_state_packed_list
316bool cdt_process_state_packed_list_modify_optype(cdt_process_state *state, cdt_op_mem *com);
317bool cdt_process_state_packed_list_read_optype(cdt_process_state *state, cdt_op_mem *com);
318
319void cdt_container_builder_add(cdt_container_builder *builder, const uint8_t *buf, uint32_t sz);
320void cdt_container_builder_add_n(cdt_container_builder *builder, const uint8_t *buf, uint32_t count, uint32_t sz);
321void cdt_container_builder_add_int64(cdt_container_builder *builder, int64_t value);
322void cdt_container_builder_add_int_range(cdt_container_builder *builder, uint32_t start, uint32_t count, uint32_t ele_count, bool reverse);
323void cdt_container_builder_set_result(cdt_container_builder *builder, cdt_result_data *result);
324
325void cdt_list_builder_start(cdt_container_builder *builder, rollback_alloc *alloc_buf, uint32_t ele_count, uint32_t max_sz);
326void 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
329bool cdt_process_state_packed_map_modify_optype(cdt_process_state *state, cdt_op_mem *com);
330bool cdt_process_state_packed_map_read_optype(cdt_process_state *state, cdt_op_mem *com);
331
332// cdt_process_state_context_eval
333bool cdt_process_state_context_eval(cdt_process_state *state, cdt_op_mem *com);
334
335// rollback_alloc
336void rollback_alloc_push(rollback_alloc *packed_alloc, void *ptr);
337uint8_t *rollback_alloc_reserve(rollback_alloc *alloc_buf, size_t sz);
338void rollback_alloc_rollback(rollback_alloc *alloc_buf);
339bool rollback_alloc_from_msgpack(rollback_alloc *alloc_buf, as_bin *b, const cdt_payload *seg);
340
341// msgpacked_index
342void msgpacked_index_set(msgpacked_index *idxs, uint32_t index, uint32_t value);
343void msgpacked_index_incr(msgpacked_index *idxs, uint32_t index);
344void msgpacked_index_set_ptr(msgpacked_index *idxs, uint8_t *ptr);
345void *msgpacked_index_get_mem(const msgpacked_index *idxs, uint32_t index);
346uint32_t msgpacked_index_size(const msgpacked_index *idxs);
347uint32_t msgpacked_index_ptr2value(const msgpacked_index *idxs, const void *ptr);
348uint32_t msgpacked_index_get(const msgpacked_index *idxs, uint32_t index);
349void msgpacked_index_print(const msgpacked_index *idxs, const char *name);
350
351// offset_index
352void offset_index_init(offset_index *offidx, uint8_t *idx_mem_ptr, uint32_t ele_count, const uint8_t *contents, uint32_t content_sz);
353void offset_index_set(offset_index *offidx, uint32_t index, uint32_t value);
354bool offset_index_set_next(offset_index *offidx, uint32_t index, uint32_t value);
355void offset_index_set_filled(offset_index *offidx, uint32_t ele_filled);
356void offset_index_set_ptr(offset_index *offidx, uint8_t *idx_mem, const uint8_t *packed_mem);
357void offset_index_copy(offset_index *dest, const offset_index *src, uint32_t d_start, uint32_t s_start, uint32_t count, int delta);
358void offset_index_move_ele(offset_index *dest, const offset_index *src, uint32_t ele_idx, uint32_t to_idx);
359void offset_index_append_size(offset_index *offidx, uint32_t delta);
360
361bool 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
363void *offset_index_get_mem(const offset_index *offidx, uint32_t index);
364uint32_t offset_index_size(const offset_index *offidx);
365bool offset_index_is_null(const offset_index *offidx);
366bool offset_index_is_valid(const offset_index *offidx);
367bool offset_index_is_full(const offset_index *offidx);
368uint32_t offset_index_get_const(const offset_index *offidx, uint32_t idx);
369uint32_t offset_index_get_delta_const(const offset_index *offidx, uint32_t index);
370uint32_t offset_index_get_filled(const offset_index *offidx);
371
372bool offset_index_check_order_and_fill(offset_index *offidx, bool pairs);
373
374uint32_t offset_index_vla_sz(const offset_index *offidx);
375void offset_index_alloc_temp(offset_index *offidx, uint8_t *mem_temp, rollback_alloc *alloc);
376
377void offset_index_print(const offset_index *offidx, const char *name);
378void offset_index_delta_print(const offset_index *offidx, const char *name);
379
380// order_index
381void order_index_init(order_index *ordidx, uint8_t *ptr, uint32_t ele_count);
382void order_index_init2(order_index *ordidx, uint8_t *ptr, uint32_t max_idx, uint32_t ele_count);
383void order_index_init2_temp(order_index *ordidx, uint8_t *mem_temp, rollback_alloc *alloc_idx, uint32_t max_idx, uint32_t ele_count);
384void order_index_init_ref(order_index *dst, const order_index *src, uint32_t start, uint32_t count);
385void order_index_set(order_index *ordidx, uint32_t index, uint32_t value);
386void order_index_set_ptr(order_index *ordidx, uint8_t *ptr);
387void order_index_incr(order_index *ordidx, uint32_t index);
388void order_index_clear(order_index *ordidx);
389bool order_index_sorted_mark_dup_eles(order_index *ordidx, const offset_index *full_offidx, uint32_t *count_r, uint32_t *sz_r);
390
391uint32_t order_index_size(const order_index *ordidx);
392bool order_index_is_null(const order_index *ordidx);
393bool order_index_is_valid(const order_index *ordidx);
394bool order_index_is_filled(const order_index *ordidx);
395
396void *order_index_get_mem(const order_index *ordidx, uint32_t index);
397uint32_t order_index_ptr2value(const order_index *ordidx, const void *ptr);
398uint32_t order_index_get(const order_index *ordidx, uint32_t index);
399
400void 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
402uint32_t order_index_get_ele_size(const order_index *ordidx, uint32_t count, const offset_index *full_offidx);
403uint8_t *order_index_write_eles(const order_index *ordidx, uint32_t count, const offset_index *full_offidx, uint8_t *ptr, bool invert);
404
405uint32_t order_index_adjust_value(const order_index_adjust *via, uint32_t src);
406void 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);
407size_t order_index_calc_size(uint32_t max_idx, uint32_t ele_count);
408
409void order_index_print(const order_index *ordidx, const char *name);
410
411// order_heap
412bool 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);
413void order_heap_swap(order_heap *heap, uint32_t index1, uint32_t index2);
414bool order_heap_remove_top(order_heap *heap);
415bool order_heap_replace_top(order_heap *heap, uint32_t value);
416bool order_heap_heapify(order_heap *heap, uint32_t index);
417bool order_heap_build(order_heap *heap, bool init);
418bool order_heap_order_at_end(order_heap *heap, uint32_t count);
419void order_heap_reverse_end(order_heap *heap, uint32_t count);
420
421void order_heap_print(const order_heap *heap);
422
423// cdt_idx_mask
424void cdt_idx_mask_init_temp(uint64_t **mask, uint32_t ele_count, rollback_alloc *alloc);
425void cdt_idx_mask_set(uint64_t *mask, uint32_t idx);
426void cdt_idx_mask_set_by_ordidx(uint64_t *mask, const order_index *ordidx, uint32_t start, uint32_t count, bool inverted);
427void cdt_idx_mask_set_by_irc(uint64_t *mask, const order_index *rankcount, const order_index *idx_map, bool inverted);
428void cdt_idx_mask_invert(uint64_t *mask, uint32_t ele_count);
429
430uint64_t cdt_idx_mask_get(const uint64_t *mask, uint32_t idx);
431size_t cdt_idx_mask_bit_count(const uint64_t *mask, uint32_t ele_count);
432
433bool cdt_idx_mask_is_set(const uint64_t *mask, uint32_t idx);
434
435uint32_t cdt_idx_mask_find(const uint64_t *mask, uint32_t start, uint32_t end, bool is_find0);
436uint8_t *cdt_idx_mask_write_eles(const uint64_t *mask, uint32_t count, const offset_index *full_offidx, uint8_t *ptr, bool invert);
437uint32_t cdt_idx_mask_get_content_sz(const uint64_t *mask, uint32_t count, const offset_index *full_offidx);
438
439void cdt_idx_mask_print(const uint64_t *mask, uint32_t ele_count, const char *name);
440
441// list
442bool list_full_offset_index_fill_all(offset_index *offidx);
443bool list_order_index_sort(order_index *ordidx, const offset_index *full_offidx, as_cdt_sort_flags flags);
444
445bool list_param_parse(const cdt_payload *items, as_unpacker *pk, uint32_t *count_r);
446
447bool list_subcontext_by_index(cdt_context *ctx, as_unpacker *val);
448bool list_subcontext_by_rank(cdt_context *ctx, as_unpacker *val);
449bool list_subcontext_by_key(cdt_context *ctx, as_unpacker *val);
450bool list_subcontext_by_value(cdt_context *ctx, as_unpacker *val);
451
452void cdt_context_unwind_list(cdt_context *ctx, cdt_ctx_list_stack_entry *p);
453
454// map
455bool map_subcontext_by_index(cdt_context *ctx, as_unpacker *val);
456bool map_subcontext_by_rank(cdt_context *ctx, as_unpacker *val);
457bool map_subcontext_by_key(cdt_context *ctx, as_unpacker *val);
458bool map_subcontext_by_value(cdt_context *ctx, as_unpacker *val);
459
460void cdt_context_unwind_map(cdt_context *ctx, cdt_ctx_list_stack_entry *p);
461
462// cdt_context
463uint32_t cdt_context_get_sz(cdt_context *ctx);
464const uint8_t *cdt_context_get_data(cdt_context *ctx);
465uint8_t *cdt_context_create_new_particle(cdt_context *ctx, uint32_t subctx_sz);
466
467cdt_ctx_list_stack_entry *cdt_context_push(cdt_context *ctx, uint32_t idx, uint8_t *idx_mem);
468
469static inline bool
470cdt_context_is_toplvl(const cdt_context *ctx)
471{
472 return ctx->data_sz == 0;
473}
474
475// Debugging support
476bool cdt_verify(cdt_context *ctx);
477bool list_verify(const cdt_context *ctx);
478bool map_verify(const cdt_context *ctx);
479
480void print_hex(const uint8_t *packed, uint32_t packed_sz, char *buf, uint32_t buf_sz);
481void print_packed(const uint8_t *packed, uint32_t sz, const char *name);
482void cdt_bin_print(const as_bin *b, const char *name);
483void cdt_context_print(const cdt_context *ctx, const char *name);
484
485
486//==========================================================
487// Inline functions.
488//
489
490static inline bool
491result_data_is_inverted(cdt_result_data *rd)
492{
493 return (rd->flags & AS_CDT_OP_FLAG_INVERTED) != 0;
494}
495
496static inline void
497result_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
504static inline void
505result_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
512static inline bool
513result_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
519static inline bool
520result_data_is_return_index(const cdt_result_data *rd)
521{
522 return (rd->type == RESULT_TYPE_INDEX || rd->type == RESULT_TYPE_REVINDEX);
523}
524
525static inline bool
526result_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
532static inline bool
533result_data_is_return_rank(const cdt_result_data *rd)
534{
535 return (rd->type == RESULT_TYPE_REVRANK || rd->type == RESULT_TYPE_RANK);
536}
537
538static inline bool
539result_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
545static inline void
546order_heap_set(order_heap *heap, uint32_t index, uint32_t value)
547{
548 order_index_set((order_index *)heap, index, value);
549}
550
551static inline uint32_t
552order_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.
558static inline int64_t
559calc_index(int64_t index, uint32_t max_index)
560{
561 return index < 0 ? (int64_t)max_index + index : index;
562}
563
564static inline bool
565cdt_context_is_modify(const cdt_context *ctx)
566{
567 return ctx->alloc_buf != NULL;
568}
569
570static inline bool
571cdt_op_is_modify(const cdt_op_mem *com)
572{
573 return cdt_context_is_modify(&com->ctx);
574}
575
576static inline void
577cdt_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
584static inline uint32_t
585cdt_vla_sz(uint32_t sz)
586{
587 return sz > CDT_MAX_STACK_OBJ_SZ ? 0 : sz;
588}
589
590// cdt_idx_mask
591static inline uint32_t
592cdt_idx_mask_count(uint32_t ele_count)
593{
594 return (ele_count + 63) / 64;
595}
596
597static inline uint32_t
598cdt_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