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