Loading...
Searching...
No Matches
as_scan.h
Go to the documentation of this file.
1/*
2 * Copyright 2008-2024 Aerospike, Inc.
3 *
4 * Portions may be licensed to Aerospike, Inc. under one or more contributor
5 * license agreements.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 * use this file except in compliance with the License. You may obtain a copy of
9 * the License at http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17#pragma once
18
19#include <aerospike/as_bin.h>
20#include <aerospike/as_key.h>
22#include <aerospike/as_udf.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28//---------------------------------
29// Macros
30//---------------------------------
31
32/**
33 * Default value for as_scan.no_bins
34 */
35#define AS_SCAN_NOBINS_DEFAULT false
36
37/**
38 * Default value for as_scan.concurrent
39 */
40#define AS_SCAN_CONCURRENT_DEFAULT false
41
42/**
43 * Default value for as_scan.deserialize_list_map
44 */
45#define AS_SCAN_DESERIALIZE_DEFAULT true
46
47//---------------------------------
48// Types
49//---------------------------------
50
51struct as_operations_s;
52
53/**
54 * The status of a particular background scan.
55 */
56typedef enum as_scan_status_e {
57
58 /**
59 * The scan status is undefined.
60 * This is likely due to the status not being properly checked.
61 */
63
64 /**
65 * The scan is currently running.
66 */
68
69 /**
70 * The scan was aborted. Due to failure or the user.
71 */
73
74 /**
75 * The scan completed successfully.
76 */
78
80
81/**
82 * Information about a particular background scan.
83 */
84typedef struct as_scan_info_s {
85
86 /**
87 * Status of the scan.
88 */
90
91 /**
92 * Progress estimate for the scan, as percentage.
93 */
94 uint32_t progress_pct;
95
96 /**
97 * How many records have been scanned.
98 */
100
102
103/**
104 * Sequence of bins which should be selected during a scan.
105 *
106 * Entries can either be initialized on the stack or on the heap.
107 *
108 * Initialization should be performed via a query object, using:
109 * - as_scan_select_init()
110 * - as_scan_select_inita()
111 */
112typedef struct as_scan_bins_s {
113
114 /**
115 * Sequence of entries
116 */
118
119 /**
120 * Number of entries allocated
121 */
122 uint16_t capacity;
123
124 /**
125 * Number of entries used
126 */
127 uint16_t size;
128
129 /**
130 * @private
131 * If true, then as_scan_destroy() will free this instance.
132 */
133 bool _free;
134
136
137/**
138 * In order to execute a scan using the Scan API, an as_scan object
139 * must be initialized and populated.
140 *
141 * ## Initialization
142 *
143 * Before using an as_scan, it must be initialized via either:
144 * - as_scan_init()
145 * - as_scan_new()
146 *
147 * as_scan_init() should be used on a stack allocated as_scan. It will
148 * initialize the as_scan with the given namespace and set. On success,
149 * it will return a pointer to the initialized as_scan. Otherwise, NULL
150 * is returned.
151 *
152 * ~~~~~~~~~~{.c}
153 * as_scan scan;
154 * as_scan_init(&scan, "namespace", "set");
155 * ~~~~~~~~~~
156 *
157 * as_scan_new() should be used to allocate and initialize a heap allocated
158 * as_scan. It will allocate the as_scan, then initialized it with the
159 * given namespace and set. On success, it will return a pointer to the
160 * initialized as_scan. Otherwise, NULL is returned.
161 *
162 * ~~~~~~~~~~{.c}
163 * as_scan* scan = as_scan_new("namespace", "set");
164 * ~~~~~~~~~~
165 *
166 * ## Destruction
167 *
168 * When you are finished with the as_scan, you can destroy it and associated
169 * resources:
170 *
171 * ~~~~~~~~~~{.c}
172 * as_scan_destroy(scan);
173 * ~~~~~~~~~~
174 *
175 * ## Usage
176 *
177 * An initialized as_scan can be populated with additional fields.
178 *
179 * ### Selecting Bins
180 *
181 * as_scan_select() is used to specify the bins to be selected by the scan.
182 * If a scan specifies bins to be selected, then only those bins will be
183 * returned. If no bins are selected, then all bins will be returned.
184 *
185 * ~~~~~~~~~~{.c}
186 * as_scan_select(query, "bin1");
187 * as_scan_select(query, "bin2");
188 * ~~~~~~~~~~
189 *
190 * Before adding bins to select, the select structure must be initialized via
191 * either:
192 * - as_scan_select_inita() - Initializes the structure on the stack.
193 * - as_scan_select_init() - Initializes the structure on the heap.
194 *
195 * Both functions are given the number of bins to be selected.
196 *
197 * A complete example using as_scan_select_inita()
198 *
199 * ~~~~~~~~~~{.c}
200 * as_scan_select_inita(query, 2);
201 * as_scan_select(query, "bin1");
202 * as_scan_select(query, "bin2");
203 * ~~~~~~~~~~
204 *
205 * ### Returning only meta data
206 *
207 * A scan can return only record meta data, and exclude bins.
208 *
209 * ~~~~~~~~~~{.c}
210 * as_scan_set_nobins(scan, true);
211 * ~~~~~~~~~~
212 *
213 * ### Scan nodes in parallel
214 *
215 * A scan can be made to scan all the nodes in parallel
216 *
217 * ~~~~~~~~~~{.c}
218 * as_scan_set_concurrent(scan, true);
219 * ~~~~~~~~~~
220 *
221 * ### Scan a Percentage of Records
222 *
223 * A scan can define the percentage of record in the cluster to be scaned.
224 *
225 * ~~~~~~~~~~{.c}
226 * as_scan_set_percent(scan, 100);
227 * ~~~~~~~~~~
228 *
229 * ### Scan a Priority
230 *
231 * To set the priority of the scan, the set as_scan.priority.
232 *
233 * The priority of a scan can be defined as either:
234 * - `AS_SCAN_PRIORITY_AUTO`
235 * - `AS_SCAN_PRIORITY_LOW`
236 * - `AS_SCAN_PRIORITY_MEDIUM`
237 * - `AS_SCAN_PRIORITY_HIGH`
238 *
239 * ~~~~~~~~~~{.c}
240 * as_scan_set_priority(scan, AS_SCAN_PRIORITY_LOW);
241 * ~~~~~~~~~~
242 *
243 * ### Applying a UDF to each Record Scanned
244 *
245 * A UDF can be applied to each record scanned.
246 *
247 * To define the UDF for the scan, use as_scan_apply_each().
248 *
249 * ~~~~~~~~~~{.c}
250 * as_scan_apply_each(scan, "udf_module", "udf_function", arglist);
251 * ~~~~~~~~~~
252 *
253 * @ingroup scan_operations
254 */
255typedef struct as_scan_s {
256
257 /**
258 * @memberof as_scan
259 * Namespace to be scanned.
260 *
261 * Should be initialized via either:
262 * - as_scan_init() - To initialize a stack allocated scan.
263 * - as_scan_new() - To heap allocate and initialize a scan.
264 */
266
267 /**
268 * Set to be scanned.
269 *
270 * Should be initialized via either:
271 * - as_scan_init() - To initialize a stack allocated scan.
272 * - as_scan_new() - To heap allocate and initialize a scan.
273 */
275
276 /**
277 * Name of bins to select.
278 *
279 * Use either of the following function to initialize:
280 * - as_scan_select_init() - To initialize on the heap.
281 * - as_scan_select_inita() - To initialize on the stack.
282 *
283 * Use as_scan_select() to populate.
284 */
286
287 /**
288 * UDF to apply to results of the background scan.
289 *
290 * Should be set via `as_scan_apply_each()`.
291 */
293
294 /**
295 * Perform write operations on a background scan.
296 * If ops is set, ops will be destroyed when as_scan_destroy() is called.
297 */
298 struct as_operations_s* ops;
299
300 /**
301 * Status of all partitions.
302 */
304
305 /**
306 * The time-to-live (expiration) of the record in seconds. Note that ttl
307 * is only used on background scan writes.
308 *
309 * There are also special values that can be set in the record ttl:
310 * <ul>
311 * <li>AS_RECORD_DEFAULT_TTL: Use the server default ttl from the namespace.</li>
312 * <li>AS_RECORD_NO_EXPIRE_TTL: Do not expire the record.</li>
313 * <li>AS_RECORD_NO_CHANGE_TTL: Keep the existing record ttl when the record is updated.</li>
314 * <li>AS_RECORD_CLIENT_DEFAULT_TTL: Use the default client ttl in as_policy_scan.</li>
315 * </ul>
316 */
317 uint32_t ttl;
318
319 /**
320 * Set to true if as_policy_scan.max_records is set and you need to scan data in pages.
321 *
322 * Default: false
323 */
325
326 /**
327 * Set to true if the scan should return only the metadata of the record.
328 *
329 * Default value is AS_SCAN_NOBINS_DEFAULT.
330 */
332
333 /**
334 * Set to true if the scan should scan all the nodes in parallel
335 *
336 * Default value is AS_SCAN_CONCURRENT_DEFAULT.
337 */
339
340 /**
341 * Set to true if the scan should deserialize list and map raw bytes.
342 * Set to false for backup programs that just need access to raw bytes.
343 *
344 * Default value is AS_SCAN_DESERIALIZE_DEFAULT.
345 */
347
348 /**
349 * @private
350 * If true, then as_scan_destroy() will free this instance.
351 */
352 bool _free;
353
354} as_scan;
355
356//---------------------------------
357// Instance Functions
358//---------------------------------
359
360/**
361 * Initializes a scan.
362 *
363 * ~~~~~~~~~~{.c}
364 * as_scan scan;
365 * as_scan_init(&scan, "test", "demo");
366 * ~~~~~~~~~~
367 *
368 * When you no longer require the scan, you should release the scan and
369 * related resources via `as_scan_destroy()`.
370 *
371 * @param scan The scan to initialize.
372 * @param ns The namespace to scan.
373 * @param set The set to scan.
374 *
375 * @returns On succes, the initialized scan. Otherwise NULL.
376 *
377 * @relates as_scan
378 * @ingroup scan_operations
379 */
381as_scan_init(as_scan* scan, const char* ns, const char* set);
382
383/**
384 * Create and initializes a new scan on the heap.
385 *
386 * ~~~~~~~~~~{.c}
387 * as_scan* scan = as_scan_new("test","demo");
388 * ~~~~~~~~~~
389 *
390 * When you no longer require the scan, you should release the scan and
391 * related resources via `as_scan_destroy()`.
392 *
393 * @param ns The namespace to scan.
394 * @param set The set to scan.
395 *
396 * @returns On success, a new scan. Otherwise NULL.
397 *
398 * @relates as_scan
399 * @ingroup scan_operations
400 */
402as_scan_new(const char* ns, const char* set);
403
404/**
405 * Releases all resources allocated to the scan.
406 *
407 * ~~~~~~~~~~{.c}
408 * as_scan_destroy(scan);
409 * ~~~~~~~~~~
410 *
411 * @relates as_scan
412 * @ingroup scan_operations
413 */
414AS_EXTERN void
416
417//---------------------------------
418// Select Functions
419//---------------------------------
420
421/**
422 * Initializes `as_scan.select` with a capacity of `n` using `alloca`
423 *
424 * For heap allocation, use `as_scan_select_init()`.
425 *
426 * ~~~~~~~~~~{.c}
427 * as_scan_select_inita(&scan, 2);
428 * as_scan_select(&scan, "bin1");
429 * as_scan_select(&scan, "bin2");
430 * ~~~~~~~~~~
431 *
432 * @param __scan The scan to initialize.
433 * @param __n The number of bins to allocate.
434 *
435 * @relates as_scan
436 * @ingroup scan_operations
437 */
438#define as_scan_select_inita(__scan, __n) \
439 do {\
440 if ((__scan)->select.entries == NULL) {\
441 (__scan)->select.entries = (as_bin_name*) alloca(sizeof(as_bin_name) * (__n));\
442 if ((__scan)->select.entries) {\
443 (__scan)->select.capacity = (__n);\
444 (__scan)->select.size = 0;\
445 (__scan)->select._free = false;\
446 }\
447 }\
448 } while(0)
449
450/**
451 * Initializes `as_scan.select` with a capacity of `n` using `malloc()`.
452 *
453 * For stack allocation, use `as_scan_select_inita()`.
454 *
455 * ~~~~~~~~~~{.c}
456 * as_scan_select_init(&scan, 2);
457 * as_scan_select(&scan, "bin1");
458 * as_scan_select(&scan, "bin2");
459 * ~~~~~~~~~~
460 *
461 * @param scan The scan to initialize.
462 * @param n The number of bins to allocate.
463 *
464 * @return On success, true. Otherwise an error occurred.
465 *
466 * @relates as_scan
467 * @ingroup scan_operations
468 */
469AS_EXTERN bool
470as_scan_select_init(as_scan* scan, uint16_t n);
471
472/**
473 * Select bins to be projected from matching records.
474 *
475 * You have to ensure as_scan.select has sufficient capacity, prior to
476 * adding a bin. If capacity is insufficient then false is returned.
477 *
478 * ~~~~~~~~~~{.c}
479 * as_scan_select_init(&scan, 2);
480 * as_scan_select(&scan, "bin1");
481 * as_scan_select(&scan, "bin2");
482 * ~~~~~~~~~~
483 *
484 * @param scan The scan to modify.
485 * @param bin The name of the bin to select.
486 *
487 * @return On success, true. Otherwise an error occurred.
488 *
489 * @relates as_scan
490 * @ingroup scan_operations
491 */
492AS_EXTERN bool
493as_scan_select(as_scan* scan, const char * bin);
494
495//---------------------------------
496// Modifier Functions
497//---------------------------------
498
499/**
500 * Do not return bins. This will only return the metadata for the records.
501 *
502 * ~~~~~~~~~~{.c}
503 * as_scan_set_nobins(&q, true);
504 * ~~~~~~~~~~
505 *
506 * @param scan The scan to set the priority on.
507 * @param nobins If true, then do not return bins.
508 *
509 * @return On success, true. Otherwise an error occurred.
510 *
511 * @relates as_scan
512 * @ingroup scan_operations
513 */
514AS_EXTERN bool
515as_scan_set_nobins(as_scan* scan, bool nobins);
516
517/**
518 * Scan all the nodes in prallel
519 *
520 * ~~~~~~~~~~{.c}
521 * as_scan_set_concurrent(&q, true);
522 * ~~~~~~~~~~
523 *
524 * @param scan The scan to set the concurrency on.
525 * @param concurrent If true, scan all the nodes in parallel
526 *
527 * @return On success, true. Otherwise an error occurred.
528 *
529 * @relates as_scan
530 * @ingroup scan_operations
531 */
532AS_EXTERN bool
533as_scan_set_concurrent(as_scan* scan, bool concurrent);
534
535//---------------------------------
536// Background Scan Functions
537//---------------------------------
538
539/**
540 * Apply a UDF to each record scanned on the server.
541 *
542 * ~~~~~~~~~~{.c}
543 * as_arraylist arglist;
544 * as_arraylist_init(&arglist, 2, 0);
545 * as_arraylist_append_int64(&arglist, 1);
546 * as_arraylist_append_int64(&arglist, 2);
547 *
548 * as_scan_apply_each(&q, "module", "func", (as_list *) &arglist);
549 *
550 * as_arraylist_destroy(&arglist);
551 * ~~~~~~~~~~
552 *
553 * @param scan The scan to apply the UDF to.
554 * @param module The module containing the function to execute.
555 * @param function The function to execute.
556 * @param arglist The arguments for the function.
557 *
558 * @return On success, true. Otherwise an error occurred.
559 *
560 * @relates as_scan
561 * @ingroup scan_operations
562 */
563AS_EXTERN bool
564as_scan_apply_each(as_scan* scan, const char* module, const char* function, as_list* arglist);
565
566//---------------------------------
567// Paginate Functions
568//---------------------------------
569
570/**
571 * Set to true if as_policy_scan.max_records is set and you need to scan data in pages.
572 *
573 * @relates as_scan
574 * @ingroup scan_operations
575 */
576static inline void
577as_scan_set_paginate(as_scan* scan, bool paginate)
578{
579 scan->paginate = paginate;
580}
581
582/**
583 * Set completion status of all partitions from a previous scan that ended early.
584 * The scan will resume from this point.
585 *
586 * @relates as_scan
587 * @ingroup scan_operations
588 */
589static inline void
594
595/**
596 * If using scan pagination, did previous paginated scan with this scan instance
597 * return all records?
598 *
599 * @relates as_scan
600 * @ingroup scan_operations
601 */
602static inline bool
604{
605 return scan->parts_all && scan->parts_all->done;
606}
607
608//---------------------------------
609// Serialization Functions
610//---------------------------------
611
612/**
613 * Serialize scan definition to bytes.
614 *
615 * @returns true on success and false on failure.
616 *
617 * @relates as_scan
618 * @ingroup scan_operations
619 */
620AS_EXTERN bool
621as_scan_to_bytes(const as_scan* scan, uint8_t** bytes, uint32_t* bytes_size);
622
623/**
624 * Deserialize bytes to scan definition. Scan definition is assumed to be on the stack.
625 * as_scan_destroy() should be called when done with the scan definition.
626 *
627 * @returns true on success and false on failure.
628 *
629 * @relates as_scan
630 * @ingroup scan_operations
631 */
632AS_EXTERN bool
633as_scan_from_bytes(as_scan* scan, const uint8_t* bytes, uint32_t bytes_size);
634
635/**
636 * Create scan definition on the heap and deserialize bytes to that scan definition.
637 * as_scan_destroy() should be called when done with the scan definition.
638 *
639 * @returns scan definition on success and NULL on failure.
640 *
641 * @relates as_scan
642 * @ingroup scan_operations
643 */
645as_scan_from_bytes_new(const uint8_t* bytes, uint32_t bytes_size);
646
647/**
648 * Compare scan objects.
649 * @private
650 * @relates as_scan
651 * @ingroup scan_operations
652 */
653AS_EXTERN bool
655
656#ifdef __cplusplus
657} // end extern "C"
658#endif
char as_bin_name[AS_BIN_NAME_MAX_SIZE]
Definition as_bin.h:53
char as_namespace[AS_NAMESPACE_MAX_SIZE]
Definition as_key.h:55
char as_set[AS_SET_MAX_SIZE]
Definition as_key.h:60
static as_partitions_status * as_partitions_status_reserve(as_partitions_status *parts_all)
as_scan_status
Definition as_scan.h:56
@ AS_SCAN_STATUS_UNDEF
Definition as_scan.h:62
@ AS_SCAN_STATUS_INPROGRESS
Definition as_scan.h:67
@ AS_SCAN_STATUS_ABORTED
Definition as_scan.h:72
@ AS_SCAN_STATUS_COMPLETED
Definition as_scan.h:77
#define AS_EXTERN
Definition as_std.h:25
AS_EXTERN bool as_scan_from_bytes(as_scan *scan, const uint8_t *bytes, uint32_t bytes_size)
AS_EXTERN bool as_scan_select_init(as_scan *scan, uint16_t n)
AS_EXTERN bool as_scan_apply_each(as_scan *scan, const char *module, const char *function, as_list *arglist)
AS_EXTERN as_scan * as_scan_new(const char *ns, const char *set)
AS_EXTERN bool as_scan_to_bytes(const as_scan *scan, uint8_t **bytes, uint32_t *bytes_size)
static void as_scan_set_paginate(as_scan *scan, bool paginate)
Definition as_scan.h:577
AS_EXTERN void as_scan_destroy(as_scan *scan)
AS_EXTERN bool as_scan_select(as_scan *scan, const char *bin)
AS_EXTERN as_scan * as_scan_init(as_scan *scan, const char *ns, const char *set)
static bool as_scan_is_done(as_scan *scan)
Definition as_scan.h:603
AS_EXTERN bool as_scan_set_nobins(as_scan *scan, bool nobins)
AS_EXTERN as_scan * as_scan_from_bytes_new(const uint8_t *bytes, uint32_t bytes_size)
AS_EXTERN bool as_scan_set_concurrent(as_scan *scan, bool concurrent)
static void as_scan_set_partitions(as_scan *scan, as_partitions_status *parts_all)
Definition as_scan.h:590
AS_EXTERN bool as_scan_compare(as_scan *s1, as_scan *s2)
uint16_t capacity
Definition as_scan.h:122
as_bin_name * entries
Definition as_scan.h:117
uint16_t size
Definition as_scan.h:127
uint32_t records_scanned
Definition as_scan.h:99
uint32_t progress_pct
Definition as_scan.h:94
as_scan_status status
Definition as_scan.h:89
bool deserialize_list_map
Definition as_scan.h:346
uint32_t ttl
Definition as_scan.h:317
bool paginate
Definition as_scan.h:324
struct as_operations_s * ops
Definition as_scan.h:298
as_scan_bins select
Definition as_scan.h:285
bool concurrent
Definition as_scan.h:338
as_udf_call apply_each
Definition as_scan.h:292
as_partitions_status * parts_all
Definition as_scan.h:303
as_namespace ns
Definition as_scan.h:265
bool no_bins
Definition as_scan.h:331
as_set set
Definition as_scan.h:274