All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_scan.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2017 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 #pragma GCC diagnostic ignored "-Waddress"
19 
20 #include <aerospike/as_bin.h>
21 #include <aerospike/as_key.h>
22 #include <aerospike/as_predexp.h>
23 #include <aerospike/as_udf.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /******************************************************************************
30  * MACROS
31  *****************************************************************************/
32 
33 /**
34  * Default value for as_scan.priority
35  */
36 #define AS_SCAN_PRIORITY_DEFAULT AS_SCAN_PRIORITY_AUTO
37 
38 /**
39  * Default value for as_scan.percent
40  */
41 #define AS_SCAN_PERCENT_DEFAULT 100
42 
43 /**
44  * Default value for as_scan.no_bins
45  */
46 #define AS_SCAN_NOBINS_DEFAULT false
47 
48 /**
49  * Default value for as_scan.concurrent
50  */
51 #define AS_SCAN_CONCURRENT_DEFAULT false
52 
53 /**
54  * Default value for as_scan.include_ldt
55  */
56 #define AS_SCAN_INCLUDE_LDT_DEFAULT false
57 
58 /**
59  * Default value for as_scan.deserialize_list_map
60  */
61 #define AS_SCAN_DESERIALIZE_DEFAULT true
62 
63 /******************************************************************************
64  * TYPES
65  *****************************************************************************/
66 
67 /**
68  * Priority levels for a scan operation.
69  */
70 typedef enum as_scan_priority_e {
71 
72  /**
73  * The cluster will auto adjust the scan priority.
74  */
76 
77  /**
78  * Low priority scan.
79  */
81 
82  /**
83  * Medium priority scan.
84  */
86 
87  /**
88  * High priority scan.
89  */
91 
93 
94 /**
95  * The status of a particular background scan.
96  */
97 typedef enum as_scan_status_e {
98 
99  /**
100  * The scan status is undefined.
101  * This is likely due to the status not being properly checked.
102  */
104 
105  /**
106  * The scan is currently running.
107  */
109 
110  /**
111  * The scan was aborted. Due to failure or the user.
112  */
114 
115  /**
116  * The scan completed successfully.
117  */
119 
121 
122 /**
123  * Information about a particular background scan.
124  *
125  * @ingroup as_scan_object
126  */
127 typedef struct as_scan_info_s {
128 
129  /**
130  * Status of the scan.
131  */
133 
134  /**
135  * Progress estimate for the scan, as percentage.
136  */
137  uint32_t progress_pct;
138 
139  /**
140  * How many records have been scanned.
141  */
142  uint32_t records_scanned;
143 
144 } as_scan_info;
145 
146 /**
147  * Sequence of bins which should be selected during a scan.
148  *
149  * Entries can either be initialized on the stack or on the heap.
150  *
151  * Initialization should be performed via a query object, using:
152  * - as_scan_select_init()
153  * - as_scan_select_inita()
154  */
155 typedef struct as_scan_bins_s {
156 
157  /**
158  * @private
159  * If true, then as_scan_destroy() will free this instance.
160  */
161  bool _free;
162 
163  /**
164  * Number of entries allocated
165  */
166  uint16_t capacity;
167 
168  /**
169  * Number of entries used
170  */
171  uint16_t size;
172 
173  /**
174  * Sequence of entries
175  */
177 
178 } as_scan_bins;
179 
180 /**
181  * Sequence of predicate expressions to be applied to a scan.
182  *
183  * Entries can either be initialized on the stack or on the heap.
184  *
185  * Initialization should be performed via a scan object, using:
186  * - as_scan_predexp_init()
187  * - as_scan_predexp_inita()
188  */
189 typedef struct as_scan_predexp_s {
190 
191  /**
192  * @private
193  * If true, then as_scan_destroy() will free this instance.
194  */
195  bool _free;
196 
197  /**
198  * Number of entries allocated
199  */
200  uint16_t capacity;
201 
202  /**
203  * Number of entries used
204  */
205  uint16_t size;
206 
207  /**
208  * Sequence of entries
209  */
211 
213 
214 /**
215  * In order to execute a scan using the Scan API, an as_scan object
216  * must be initialized and populated.
217  *
218  * ## Initialization
219  *
220  * Before using an as_scan, it must be initialized via either:
221  * - as_scan_init()
222  * - as_scan_new()
223  *
224  * as_scan_init() should be used on a stack allocated as_scan. It will
225  * initialize the as_scan with the given namespace and set. On success,
226  * it will return a pointer to the initialized as_scan. Otherwise, NULL
227  * is returned.
228  *
229  * ~~~~~~~~~~{.c}
230  * as_scan scan;
231  * as_scan_init(&scan, "namespace", "set");
232  * ~~~~~~~~~~
233  *
234  * as_scan_new() should be used to allocate and initialize a heap allocated
235  * as_scan. It will allocate the as_scan, then initialized it with the
236  * given namespace and set. On success, it will return a pointer to the
237  * initialized as_scan. Otherwise, NULL is returned.
238  *
239  * ~~~~~~~~~~{.c}
240  * as_scan * scan = as_scan_new("namespace", "set");
241  * ~~~~~~~~~~
242  *
243  * ## Destruction
244  *
245  * When you are finished with the as_scan, you can destroy it and associated
246  * resources:
247  *
248  * ~~~~~~~~~~{.c}
249  * as_scan_destroy(scan);
250  * ~~~~~~~~~~
251  *
252  * ## Usage
253  *
254  * An initialized as_scan can be populated with additional fields.
255  *
256  * ### Selecting Bins
257  *
258  * as_scan_select() is used to specify the bins to be selected by the scan.
259  * If a scan specifies bins to be selected, then only those bins will be
260  * returned. If no bins are selected, then all bins will be returned.
261  *
262  * ~~~~~~~~~~{.c}
263  * as_scan_select(query, "bin1");
264  * as_scan_select(query, "bin2");
265  * ~~~~~~~~~~
266  *
267  * Before adding bins to select, the select structure must be initialized via
268  * either:
269  * - as_scan_select_inita() - Initializes the structure on the stack.
270  * - as_scan_select_init() - Initializes the structure on the heap.
271  *
272  * Both functions are given the number of bins to be selected.
273  *
274  * A complete example using as_scan_select_inita()
275  *
276  * ~~~~~~~~~~{.c}
277  * as_scan_select_inita(query, 2);
278  * as_scan_select(query, "bin1");
279  * as_scan_select(query, "bin2");
280  * ~~~~~~~~~~
281  *
282  * ### Returning only meta data
283  *
284  * A scan can return only record meta data, and exclude bins.
285  *
286  * ~~~~~~~~~~{.c}
287  * as_scan_set_nobins(scan, true);
288  * ~~~~~~~~~~
289  *
290  * ### Scan nodes in parallel
291  *
292  * A scan can be made to scan all the nodes in parallel
293  *
294  * ~~~~~~~~~~{.c}
295  * as_scan_set_concurrent(scan, true);
296  * ~~~~~~~~~~
297  *
298  * ### Scan a Percentage of Records
299  *
300  * A scan can define the percentage of record in the cluster to be scaned.
301  *
302  * ~~~~~~~~~~{.c}
303  * as_scan_set_percent(scan, 100);
304  * ~~~~~~~~~~
305  *
306  * ### Scan a Priority
307  *
308  * To set the priority of the scan, the set as_scan.priority.
309  *
310  * The priority of a scan can be defined as either:
311  * - `AS_SCAN_PRIORITY_AUTO`
312  * - `AS_SCAN_PRIORITY_LOW`
313  * - `AS_SCAN_PRIORITY_MEDIUM`
314  * - `AS_SCAN_PRIORITY_HIGH`
315  *
316  * ~~~~~~~~~~{.c}
317  * as_scan_set_priority(scan, AS_SCAN_PRIORITY_LOW);
318  * ~~~~~~~~~~
319  *
320  * ### Applying a UDF to each Record Scanned
321  *
322  * A UDF can be applied to each record scanned.
323  *
324  * To define the UDF for the scan, use as_scan_apply_each().
325  *
326  * ~~~~~~~~~~{.c}
327  * as_scan_apply_each(scan, "udf_module", "udf_function", arglist);
328  * ~~~~~~~~~~
329  *
330  * @ingroup client_objects
331  */
332 typedef struct as_scan_s {
333 
334  /**
335  * @private
336  * If true, then as_scan_destroy() will free this instance.
337  */
338  bool _free;
339 
340  /**
341  * Priority of scan.
342  *
343  * Default value is AS_SCAN_PRIORITY_DEFAULT.
344  */
346 
347  /**
348  * Percentage of the data to scan.
349  *
350  * Default value is AS_SCAN_PERCENT_DEFAULT.
351  */
352  uint8_t percent;
353 
354  /**
355  * Set to true if the scan should return only the metadata of the record.
356  *
357  * Default value is AS_SCAN_NOBINS_DEFAULT.
358  */
359  bool no_bins;
360 
361  /**
362  * Set to true if the scan should scan all the nodes in parallel
363  *
364  * Default value is AS_SCAN_CONCURRENT_DEFAULT.
365  */
367 
368  /**
369  * Include large data type bin values in addition to large data type bin names.
370  * If false, LDT bin names will be returned, but LDT bin values will be empty.
371  * If true, LDT bin names and the entire LDT bin values will be returned.
372  * This is useful for backups.
373  * Default: false
374  */
376 
377  /**
378  * Set to true if the scan should deserialize list and map raw bytes.
379  * Set to false for backup programs that just need access to raw bytes.
380  *
381  * Default value is AS_SCAN_DESERIALIZE_DEFAULT.
382  */
384 
385  /**
386  * @memberof as_scan
387  * Namespace to be scanned.
388  *
389  * Should be initialized via either:
390  * - as_scan_init() - To initialize a stack allocated scan.
391  * - as_scan_new() - To heap allocate and initialize a scan.
392  *
393  */
395 
396  /**
397  * Set to be scanned.
398  *
399  * Should be initialized via either:
400  * - as_scan_init() - To initialize a stack allocated scan.
401  * - as_scan_new() - To heap allocate and initialize a scan.
402  *
403  */
405 
406  /**
407  * Name of bins to select.
408  *
409  * Use either of the following function to initialize:
410  * - as_scan_select_init() - To initialize on the heap.
411  * - as_scan_select_inita() - To initialize on the stack.
412  *
413  * Use as_scan_select() to populate.
414  */
416 
417  /**
418  * Predicate Expressions for filtering.
419  *
420  * Use either of the following function to initialize:
421  * - as_query_predexp_init() - To initialize on the heap.
422  * - as_query_predexp_inita() - To initialize on the stack.
423  *
424  * Use as_query_predexp() to populate.
425  */
427 
428  /**
429  * Apply the UDF for each record scanned on the server.
430  *
431  * Should be set via `as_scan_apply_each()`.
432  */
434 
435 } as_scan;
436 
437 /******************************************************************************
438  * INSTANCE FUNCTIONS
439  *****************************************************************************/
440 
441 /**
442  * Initializes a scan.
443  *
444  * ~~~~~~~~~~{.c}
445  * as_scan scan;
446  * as_scan_init(&scan, "test", "demo");
447  * ~~~~~~~~~~
448  *
449  * When you no longer require the scan, you should release the scan and
450  * related resources via `as_scan_destroy()`.
451  *
452  * @param scan The scan to initialize.
453  * @param ns The namespace to scan.
454  * @param set The set to scan.
455  *
456  * @returns On succes, the initialized scan. Otherwise NULL.
457  *
458  * @relates as_scan
459  * @ingroup as_scan_object
460  */
461 as_scan * as_scan_init(as_scan * scan, const as_namespace ns, const as_set set);
462 
463 /**
464  * Create and initializes a new scan on the heap.
465  *
466  * ~~~~~~~~~~{.c}
467  * as_scan * scan = as_scan_new("test","demo");
468  * ~~~~~~~~~~
469  *
470  * When you no longer require the scan, you should release the scan and
471  * related resources via `as_scan_destroy()`.
472  *
473  * @param ns The namespace to scan.
474  * @param set The set to scan.
475  *
476  * @returns On success, a new scan. Otherwise NULL.
477  *
478  * @relates as_scan
479  * @ingroup as_scan_object
480  */
481 as_scan * as_scan_new(const as_namespace ns, const as_set set);
482 
483 /**
484  * Releases all resources allocated to the scan.
485  *
486  * ~~~~~~~~~~{.c}
487  * as_scan_destroy(scan);
488  * ~~~~~~~~~~
489  *
490  * @relates as_scan
491  * @ingroup as_scan_object
492  */
493 void as_scan_destroy(as_scan * scan);
494 
495 /******************************************************************************
496  * SELECT FUNCTIONS
497  *****************************************************************************/
498 
499 /**
500  * Initializes `as_scan.select` with a capacity of `n` using `alloca`
501  *
502  * For heap allocation, use `as_scan_select_init()`.
503  *
504  * ~~~~~~~~~~{.c}
505  * as_scan_select_inita(&scan, 2);
506  * as_scan_select(&scan, "bin1");
507  * as_scan_select(&scan, "bin2");
508  * ~~~~~~~~~~
509  *
510  * @param __scan The scan to initialize.
511  * @param __n The number of bins to allocate.
512  *
513  * @ingroup as_scan_object
514  */
515 #define as_scan_select_inita(__scan, __n) \
516  do { \
517  if ( (__scan) != NULL && (__scan)->select.entries == NULL ) {\
518  (__scan)->select.entries = (as_bin_name*) alloca(sizeof(as_bin_name) * (__n));\
519  if ( (__scan)->select.entries ) { \
520  (__scan)->select._free = false;\
521  (__scan)->select.capacity = (__n);\
522  (__scan)->select.size = 0;\
523  }\
524  } \
525  } while(0)
526 
527 /**
528  * Initializes `as_scan.select` with a capacity of `n` using `malloc()`.
529  *
530  * For stack allocation, use `as_scan_select_inita()`.
531  *
532  * ~~~~~~~~~~{.c}
533  * as_scan_select_init(&scan, 2);
534  * as_scan_select(&scan, "bin1");
535  * as_scan_select(&scan, "bin2");
536  * ~~~~~~~~~~
537  *
538  * @param scan The scan to initialize.
539  * @param n The number of bins to allocate.
540  *
541  * @return On success, the initialized. Otherwise an error occurred.
542  *
543  * @relates as_scan
544  * @ingroup as_scan_object
545  */
546 bool as_scan_select_init(as_scan * scan, uint16_t n);
547 
548 /**
549  * Select bins to be projected from matching records.
550  *
551  * You have to ensure as_scan.select has sufficient capacity, prior to
552  * adding a bin. If capacity is insufficient then false is returned.
553  *
554  * ~~~~~~~~~~{.c}
555  * as_scan_select_init(&scan, 2);
556  * as_scan_select(&scan, "bin1");
557  * as_scan_select(&scan, "bin2");
558  * ~~~~~~~~~~
559  *
560  * @param scan The scan to modify.
561  * @param bin The name of the bin to select.
562  *
563  * @return On success, true. Otherwise an error occurred.
564  *
565  * @relates as_scan
566  * @ingroup as_scan_object
567  */
568 bool as_scan_select(as_scan * scan, const char * bin);
569 
570 
571 /******************************************************************************
572  * PREDEXP FUNCTIONS
573  *****************************************************************************/
574 
575 /**
576  * Initializes `as_scan.predexp` with a capacity of `n` using `alloca`
577  *
578  * For heap allocation, use `as_scan_predexp_init()`.
579  *
580  * ~~~~~~~~~~{.c}
581  * as_scan_predexp_inita(&scan, 3);
582  * as_scan_predexp_add(&scan, as_predexp_integer_value(90));
583  * as_scan_predexp_add(&scan, as_predexp_integer_bin("bin1"));
584  * as_scan_predexp_add(&scan, as_predexp_integer_greatereq());
585  * ~~~~~~~~~~
586  *
587  * @param __scan The scan to initialize.
588  * @param __n The number of predicate expression slots to allocate.
589  *
590  * @relates as_scan
591  * @ingroup as_scan_object
592  */
593 #define as_scan_predexp_inita(__scan, __n) \
594  if ( (__scan) != NULL && (__scan)->predexp.entries == NULL ) { \
595  (__scan)->predexp.entries = \
596  (as_predexp_base **) \
597  alloca(__n * sizeof(as_predexp_base *)); \
598  if ( (__scan)->predexp.entries ) { \
599  (__scan)->predexp._free = false; \
600  (__scan)->predexp.capacity = __n; \
601  (__scan)->predexp.size = 0; \
602  } \
603  }
604 
605 /**
606  * Initializes `as_scan.predexp` with a capacity of `n` using `malloc()`.
607  *
608  * For stack allocation, use `as_scan_predexp_inita()`.
609  *
610  * ~~~~~~~~~~{.c}
611  * as_scan_predexp_init(&scan, 3);
612  * as_scan_predexp_add(&scan, as_predexp_integer_value(90));
613  * as_scan_predexp_add(&scan, as_predexp_integer_bin("bin1"));
614  * as_scan_predexp_add(&scan, as_predexp_integer_greatereq());
615  * ~~~~~~~~~~
616  *
617  * @param scan The scan to initialize.
618  * @param n The number of predicate expression slots to allocate.
619  *
620  * @return On success, the initialized. Otherwise an error occurred.
621  *
622  * @relates as_scan
623  * @ingroup as_scan_object
624  */
625 bool as_scan_predexp_init(as_scan * scan, uint16_t n);
626 
627 /**
628  * Adds predicate expressions to a scan.
629  *
630  * You have to ensure as_scan.predexp has sufficient capacity, prior to
631  * adding a predexp. If capacity is sufficient then false is returned.
632  *
633  * ~~~~~~~~~~{.c}
634  * as_scan_predexp_inita(&scan, 3);
635  * as_scan_predexp_add(&scan, as_predexp_integer_value(90));
636  * as_scan_predexp_add(&scan, as_predexp_integer_bin("bin1"));
637  * as_scan_predexp_add(&scan, as_predexp_integer_greatereq());
638  * ~~~~~~~~~~
639  *
640  * @param scan The scan to modify.
641  * @param predexp Pointer to a constructed predicate expression.
642  *
643  * @return On success, true. Otherwise an error occurred.
644  *
645  * @relates as_scan
646  * @ingroup as_scan_object
647  */
648 bool as_scan_predexp_add(as_scan * scan, as_predexp_base * predexp);
649 
650 /******************************************************************************
651  * MODIFIER FUNCTIONS
652  *****************************************************************************/
653 
654 /**
655  * The percentage of data to scan.
656  *
657  * ~~~~~~~~~~{.c}
658  * as_scan_set_percent(&q, 100);
659  * ~~~~~~~~~~
660  *
661  * @param scan The scan to set the priority on.
662  * @param percent The percent to scan.
663  *
664  * @return On success, true. Otherwise an error occurred.
665  *
666  * @relates as_scan
667  * @ingroup as_scan_object
668  */
669 bool as_scan_set_percent(as_scan * scan, uint8_t percent);
670 
671 /**
672  * Set the priority for the scan.
673  *
674  * ~~~~~~~~~~{.c}
675  * as_scan_set_priority(&q, AS_SCAN_PRIORITY_LOW);
676  * ~~~~~~~~~~
677  *
678  * @param scan The scan to set the priority on.
679  * @param priority The priority for the scan.
680  *
681  * @return On success, true. Otherwise an error occurred.
682  *
683  * @relates as_scan
684  * @ingroup as_scan_object
685  */
686 bool as_scan_set_priority(as_scan * scan, as_scan_priority priority);
687 
688 /**
689  * Do not return bins. This will only return the metadata for the records.
690  *
691  * ~~~~~~~~~~{.c}
692  * as_scan_set_nobins(&q, true);
693  * ~~~~~~~~~~
694  *
695  * @param scan The scan to set the priority on.
696  * @param nobins If true, then do not return bins.
697  *
698  * @return On success, true. Otherwise an error occurred.
699  *
700  * @relates as_scan
701  * @ingroup as_scan_object
702  */
703 bool as_scan_set_nobins(as_scan * scan, bool nobins);
704 
705 /**
706  * Scan all the nodes in prallel
707  *
708  * ~~~~~~~~~~{.c}
709  * as_scan_set_concurrent(&q, true);
710  * ~~~~~~~~~~
711  *
712  * @param scan The scan to set the concurrency on.
713  * @param concurrent If true, scan all the nodes in parallel
714  *
715  * @return On success, true. Otherwise an error occurred.
716  */
717 bool as_scan_set_concurrent(as_scan * scan, bool concurrent);
718 
719 /**
720  * Apply a UDF to each record scanned on the server.
721  *
722  * ~~~~~~~~~~{.c}
723  * as_arraylist arglist;
724  * as_arraylist_init(&arglist, 2, 0);
725  * as_arraylist_append_int64(&arglist, 1);
726  * as_arraylist_append_int64(&arglist, 2);
727  *
728  * as_scan_apply_each(&q, "module", "func", (as_list *) &arglist);
729  *
730  * as_arraylist_destroy(&arglist);
731  * ~~~~~~~~~~
732  *
733  * @param scan The scan to apply the UDF to.
734  * @param module The module containing the function to execute.
735  * @param function The function to execute.
736  * @param arglist The arguments for the function.
737  *
738  * @return On success, true. Otherwise an error occurred.
739  *
740  * @relates as_scan
741  * @ingroup as_scan_object
742  */
743 bool as_scan_apply_each(as_scan * scan, const char * module, const char * function, as_list * arglist);
744 
745 #ifdef __cplusplus
746 } // end extern "C"
747 #endif
uint8_t percent
Definition: as_scan.h:352
as_namespace ns
Definition: as_scan.h:394
bool as_scan_select(as_scan *scan, const char *bin)
as_scan * as_scan_init(as_scan *scan, const as_namespace ns, const as_set set)
bool include_ldt
Definition: as_scan.h:375
as_udf_call apply_each
Definition: as_scan.h:433
uint32_t records_scanned
Definition: as_scan.h:142
char as_namespace[AS_NAMESPACE_MAX_SIZE]
Definition: as_key.h:66
bool _free
Definition: as_scan.h:161
as_predexp_base ** entries
Definition: as_scan.h:210
as_scan_status status
Definition: as_scan.h:132
as_set set
Definition: as_scan.h:404
bool as_scan_predexp_init(as_scan *scan, uint16_t n)
bool as_scan_select_init(as_scan *scan, uint16_t n)
bool as_scan_predexp_add(as_scan *scan, as_predexp_base *predexp)
uint16_t capacity
Definition: as_scan.h:166
bool as_scan_set_percent(as_scan *scan, uint8_t percent)
uint16_t size
Definition: as_scan.h:171
void as_scan_destroy(as_scan *scan)
uint32_t progress_pct
Definition: as_scan.h:137
uint16_t size
Definition: as_scan.h:205
as_scan_predexp predexp
Definition: as_scan.h:426
as_scan_priority priority
Definition: as_scan.h:345
as_scan * as_scan_new(const as_namespace ns, const as_set set)
uint16_t capacity
Definition: as_scan.h:200
bool deserialize_list_map
Definition: as_scan.h:383
bool no_bins
Definition: as_scan.h:359
bool as_scan_set_concurrent(as_scan *scan, bool concurrent)
bool as_scan_apply_each(as_scan *scan, const char *module, const char *function, as_list *arglist)
bool as_scan_set_nobins(as_scan *scan, bool nobins)
char as_bin_name[AS_BIN_NAME_MAX_SIZE]
Definition: as_bin.h:52
as_bin_name * entries
Definition: as_scan.h:176
bool as_scan_set_priority(as_scan *scan, as_scan_priority priority)
bool _free
Definition: as_scan.h:338
as_scan_bins select
Definition: as_scan.h:415
as_scan_priority
Definition: as_scan.h:70
bool concurrent
Definition: as_scan.h:366
as_scan_status
Definition: as_scan.h:97
char as_set[AS_SET_MAX_SIZE]
Definition: as_key.h:73