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-2013 by Aerospike.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  *****************************************************************************/
22 
23 #pragma once
24 
25 #include <aerospike/as_bin.h>
26 #include <aerospike/as_key.h>
27 #include <aerospike/as_udf.h>
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  * TYPES
55  *****************************************************************************/
56 
57 /**
58  * Priority levels for a scan operation.
59  */
60 typedef enum as_scan_priority_e {
61 
62  /**
63  * The cluster will auto adjust the scan priority.
64  */
66 
67  /**
68  * Low priority scan.
69  */
71 
72  /**
73  * Medium priority scan.
74  */
76 
77  /**
78  * High priority scan.
79  */
81 
83 
84 /**
85  * The status of a particular background scan.
86  */
87 typedef enum as_scan_status_e {
88 
89  /**
90  * The scan status is undefined.
91  * This is likely due to the status not being properly checked.
92  */
94 
95  /**
96  * The scan is currently running.
97  */
99 
100  /**
101  * The scan was aborted. Due to failure or the user.
102  */
104 
105  /**
106  * The scan completed successfully.
107  */
109 
111 
112 /**
113  * Information about a particular background scan.
114  *
115  * @ingroup as_scan_object
116  */
117 typedef struct as_scan_info_s {
118 
119  /**
120  * Status of the scan.
121  */
123 
124  /**
125  * Progress estimate for the scan, as percentage.
126  */
127  uint32_t progress_pct;
128 
129  /**
130  * How many records have been scanned.
131  */
132  uint32_t records_scanned;
133 
134 } as_scan_info;
135 
136 /**
137  * Sequence of bins which should be selected during a scan.
138  *
139  * Entries can either be initialized on the stack or on the heap.
140  *
141  * Initialization should be performed via a query object, using:
142  * - as_scan_select_init()
143  * - as_scan_select_inita()
144  */
145 typedef struct as_scan_bins_s {
146 
147  /**
148  * @private
149  * If true, then as_scan_destroy() will free this instance.
150  */
151  bool _free;
152 
153  /**
154  * Number of entries allocated
155  */
156  uint16_t capacity;
157 
158  /**
159  * Number of entries used
160  */
161  uint16_t size;
162 
163  /**
164  * Sequence of entries
165  */
167 
168 } as_scan_bins;
169 
170 /**
171  * In order to execute a scan using the Scan API, an as_scan object
172  * must be initialized and populated.
173  *
174  * ## Initialization
175  *
176  * Before using an as_scan, it must be initialized via either:
177  * - as_scan_init()
178  * - as_scan_new()
179  *
180  * as_scan_init() should be used on a stack allocated as_scan. It will
181  * initialize the as_scan with the given namespace and set. On success,
182  * it will return a pointer to the initialized as_scan. Otherwise, NULL
183  * is returned.
184  *
185  * ~~~~~~~~~~{.c}
186  * as_scan scan;
187  * as_scan_init(&scan, "namespace", "set");
188  * ~~~~~~~~~~
189  *
190  * as_scan_new() should be used to allocate and initialize a heap allocated
191  * as_scan. It will allocate the as_scan, then initialized it with the
192  * given namespace and set. On success, it will return a pointer to the
193  * initialized as_scan. Otherwise, NULL is returned.
194  *
195  * ~~~~~~~~~~{.c}
196  * as_scan * scan = as_scan_new("namespace", "set");
197  * ~~~~~~~~~~
198  *
199  * ## Destruction
200  *
201  * When you are finished with the as_scan, you can destroy it and associated
202  * resources:
203  *
204  * ~~~~~~~~~~{.c}
205  * as_scan_destroy(scan);
206  * ~~~~~~~~~~
207  *
208  * ## Usage
209  *
210  * An initialized as_query can be populated with additional fields.
211  *
212  * ### Selecting Bins
213  *
214  * as_scan_select() is used to specify the bins to be selected by the scan.
215  * If a scan specifies bins to be selected, then only those bins will be
216  * returned. If no bins are selected, then all bins will be returned.
217  *
218  * ~~~~~~~~~~{.c}
219  * as_scan_select(query, "bin1");
220  * as_scan_select(query, "bin2");
221  * ~~~~~~~~~~
222  *
223  * Before adding bins to select, the select structure must be initialized via
224  * either:
225  * - as_scan_select_inita() - Initializes the structure on the stack.
226  * - as_scan_select_init() - Initializes the structure on the heap.
227  *
228  * Both functions are given the number of bins to be selected.
229  *
230  * A complete example using as_scan_select_inita()
231  *
232  * ~~~~~~~~~~{.c}
233  * as_scan_select_inita(query, 2);
234  * as_scan_select(query, "bin1");
235  * as_scan_select(query, "bin2");
236  * ~~~~~~~~~~
237  *
238  * ### Returning only meta data
239  *
240  * A scan can return only record meta data, and exclude bins.
241  *
242  * ~~~~~~~~~~{.c}
243  * as_scan_set_nobins(scan, true);
244  * ~~~~~~~~~~
245  *
246  * ### Scan nodes in parallel
247  *
248  * A scan can be made to scan all the nodes in parallel
249  *
250  * ~~~~~~~~~~{.c}
251  * as_scan_set_concurrent(scan, true);
252  * ~~~~~~~~~~
253  *
254  * ### Scan a Percentage of Records
255  *
256  * A scan can define the percentage of record in the cluster to be scaned.
257  *
258  * ~~~~~~~~~~{.c}
259  * as_scan_set_percent(scan, 100);
260  * ~~~~~~~~~~
261  *
262  * ### Scan a Priority
263  *
264  * To set the priority of the scan, the set as_scan.priority.
265  *
266  * The priority of a scan can be defined as either:
267  * - `AS_SCAN_PRIORITY_AUTO`
268  * - `AS_SCAN_PRIORITY_LOW`
269  * - `AS_SCAN_PRIORITY_MEDIUM`
270  * - `AS_SCAN_PRIORITY_HIGH`
271  *
272  * ~~~~~~~~~~{.c}
273  * as_scan_set_priority(scan, AS_SCAN_PRIORITY_LOW);
274  * ~~~~~~~~~~
275  *
276  * ### Applying a UDF to each Record Scanned
277  *
278  * A UDF can be applied to each record scanned.
279  *
280  * To define the UDF for the scan, use as_scan_apply_each().
281  *
282  * ~~~~~~~~~~{.c}
283  * as_scan_apply_each(scan, "udf_module", "udf_function", arglist);
284  * ~~~~~~~~~~
285  *
286  * @ingroup client_objects
287  */
288 typedef struct as_scan_s {
289 
290  /**
291  * @private
292  * If true, then as_scan_destroy() will free this instance.
293  */
294  bool _free;
295 
296  /**
297  * Priority of scan.
298  *
299  * Default value is AS_SCAN_PRIORITY_DEFAULT.
300  */
302 
303  /**
304  * Percentage of the data to scan.
305  *
306  * Default value is AS_SCAN_PERCENT_DEFAULT.
307  */
308  uint8_t percent;
309 
310  /**
311  * Set to true if the scan should return only the metadata of the record.
312  *
313  * Default value is AS_SCAN_NOBINS_DEFAULT.
314  */
315  bool no_bins;
316 
317  /**
318  * Set to true if the scan should scan all the nodes in parallel
319  *
320  * Default value is AS_SCAN_CONCURRENT_DEFAULT.
321  */
323 
324  /**
325  * @memberof as_scan
326  * Namespace to be scanned.
327  *
328  * Should be initialized via either:
329  * - as_scan_init() - To initialize a stack allocated scan.
330  * - as_scan_new() - To heap allocate and initialize a scan.
331  *
332  */
334 
335  /**
336  * Set to be scanned.
337  *
338  * Should be initialized via either:
339  * - as_scan_init() - To initialize a stack allocated scan.
340  * - as_scan_new() - To heap allocate and initialize a scan.
341  *
342  */
344 
345  /**
346  * Name of bins to select.
347  *
348  * Use either of the following function to initialize:
349  * - as_scan_select_init() - To initialize on the heap.
350  * - as_scan_select_inita() - To initialize on the stack.
351  *
352  * Use as_scan_select() to populate.
353  */
355 
356  /**
357  * Apply the UDF for each record scanned on the server.
358  *
359  * Should be set via `as_scan_apply_each()`.
360  */
362 
363 } as_scan;
364 
365 /******************************************************************************
366  * INSTANCE FUNCTIONS
367  *****************************************************************************/
368 
369 /**
370  * Initializes a scan.
371  *
372  * ~~~~~~~~~~{.c}
373  * as_scan scan;
374  * as_scan_init(&scan, "test", "demo");
375  * ~~~~~~~~~~
376  *
377  * When you no longer require the scan, you should release the scan and
378  * related resources via `as_scan_destroy()`.
379  *
380  * @param scan The scan to initialize.
381  * @param ns The namespace to scan.
382  * @param set The set to scan.
383  *
384  * @returns On succes, the initialized scan. Otherwise NULL.
385  *
386  * @relates as_scan
387  * @ingroup as_scan_object
388  */
389 as_scan * as_scan_init(as_scan * scan, const as_namespace ns, const as_set set);
390 
391 /**
392  * Create and initializes a new scan on the heap.
393  *
394  * ~~~~~~~~~~{.c}
395  * as_scan * scan = as_scan_new("test","demo");
396  * ~~~~~~~~~~
397  *
398  * When you no longer require the scan, you should release the scan and
399  * related resources via `as_scan_destroy()`.
400  *
401  * @param ns The namespace to scan.
402  * @param set The set to scan.
403  *
404  * @returns On success, a new scan. Otherwise NULL.
405  *
406  * @relates as_scan
407  * @ingroup as_scan_object
408  */
409 as_scan * as_scan_new(const as_namespace ns, const as_set set);
410 
411 /**
412  * Releases all resources allocated to the scan.
413  *
414  * ~~~~~~~~~~{.c}
415  * as_scan_destroy(scan);
416  * ~~~~~~~~~~
417  *
418  * @relates as_scan
419  * @ingroup as_scan_object
420  */
421 void as_scan_destroy(as_scan * scan);
422 
423 /******************************************************************************
424  * SELECT FUNCTIONS
425  *****************************************************************************/
426 
427 /**
428  * Initializes `as_scan.select` with a capacity of `n` using `alloca`
429  *
430  * For heap allocation, use `as_scan_select_init()`.
431  *
432  * ~~~~~~~~~~{.c}
433  * as_scan_select_inita(&scan, 2);
434  * as_scan_select(&scan, "bin1");
435  * as_scan_select(&scan, "bin2");
436  * ~~~~~~~~~~
437  *
438  * @param __scan The scan to initialize.
439  * @param __n The number of bins to allocate.
440  *
441  * @ingroup as_scan_object
442  */
443 #define as_scan_select_inita(__scan, __n) \
444  if ( (__scan) != NULL && (__scan)->select.entries == NULL ) {\
445  (__scan)->select.entries = (as_bin_name *) alloca(__n * sizeof(as_bin_name));\
446  if ( (__scan)->select.entries ) { \
447  (__scan)->select._free = false;\
448  (__scan)->select.capacity = __n;\
449  (__scan)->select.size = 0;\
450  }\
451  }
452 
453 /**
454  * Initializes `as_scan.select` with a capacity of `n` using `malloc()`.
455  *
456  * For stack allocation, use `as_scan_select_inita()`.
457  *
458  * ~~~~~~~~~~{.c}
459  * as_scan_select_init(&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  * @return On success, the initialized. Otherwise an error occurred.
468  *
469  * @relates as_scan
470  * @ingroup as_scan_object
471  */
472 bool as_scan_select_init(as_scan * scan, uint16_t n);
473 
474 /**
475  * Select bins to be projected from matching records.
476  *
477  * You have to ensure as_scan.select has sufficient capacity, prior to
478  * adding a bin. If capacity is insufficient then false is returned.
479  *
480  * ~~~~~~~~~~{.c}
481  * as_scan_select_init(&scan, 2);
482  * as_scan_select(&scan, "bin1");
483  * as_scan_select(&scan, "bin2");
484  * ~~~~~~~~~~
485  *
486  * @param scan The scan to modify.
487  * @param bin The name of the bin to select.
488  *
489  * @return On success, true. Otherwise an error occurred.
490  *
491  * @relates as_scan
492  * @ingroup as_scan_object
493  */
494 bool as_scan_select(as_scan * scan, const char * bin);
495 
496 /******************************************************************************
497  * MODIFIER FUNCTIONS
498  *****************************************************************************/
499 
500 /**
501  * The percentage of data to scan.
502  *
503  * ~~~~~~~~~~{.c}
504  * as_scan_set_percent(&q, 100);
505  * ~~~~~~~~~~
506  *
507  * @param scan The scan to set the priority on.
508  * @param percent The percent to scan.
509  *
510  * @return On success, true. Otherwise an error occurred.
511  *
512  * @relates as_scan
513  * @ingroup as_scan_object
514  */
515 bool as_scan_set_percent(as_scan * scan, uint8_t percent);
516 
517 /**
518  * Set the priority for the scan.
519  *
520  * ~~~~~~~~~~{.c}
521  * as_scan_set_priority(&q, AS_SCAN_PRIORITY_LOW);
522  * ~~~~~~~~~~
523  *
524  * @param scan The scan to set the priority on.
525  * @param priority The priority for the scan.
526  *
527  * @return On success, true. Otherwise an error occurred.
528  *
529  * @relates as_scan
530  * @ingroup as_scan_object
531  */
532 bool as_scan_set_priority(as_scan * scan, as_scan_priority priority);
533 
534 /**
535  * Do not return bins. This will only return the metadata for the records.
536  *
537  * ~~~~~~~~~~{.c}
538  * as_scan_set_nobins(&q, true);
539  * ~~~~~~~~~~
540  *
541  * @param scan The scan to set the priority on.
542  * @param nobins If true, then do not return bins.
543  *
544  * @return On success, true. Otherwise an error occurred.
545  *
546  * @relates as_scan
547  * @ingroup as_scan_object
548  */
549 bool as_scan_set_nobins(as_scan * scan, bool nobins);
550 
551 /**
552  * Scan all the nodes in prallel
553  *
554  * ~~~~~~~~~~{.c}
555  * as_scan_set_concurrent(&q, true);
556  * ~~~~~~~~~~
557  *
558  * @param scan The scan to set the concurrency on.
559  * @param concurrent If true, scan all the nodes in parallel
560  *
561  * @return On success, true. Otherwise an error occurred.
562  */
563 bool as_scan_set_concurrent(as_scan * scan, bool concurrent);
564 
565 /**
566  * Apply a UDF to each record scanned on the server.
567  *
568  * ~~~~~~~~~~{.c}
569  * as_arraylist arglist;
570  * as_arraylist_init(&arglist, 2, 0);
571  * as_arraylist_append_int64(&arglist, 1);
572  * as_arraylist_append_int64(&arglist, 2);
573  *
574  * as_scan_apply_each(&q, "module", "func", (as_list *) &arglist);
575  *
576  * as_arraylist_destroy(&arglist);
577  * ~~~~~~~~~~
578  *
579  * @param scan The scan to apply the UDF to.
580  * @param module The module containing the function to execute.
581  * @param function The function to execute.
582  * @param arglist The arguments for the function.
583  *
584  * @return On success, true. Otherwise an error occurred.
585  *
586  * @relates as_scan
587  * @ingroup as_scan_object
588  */
589 bool as_scan_apply_each(as_scan * scan, const char * module, const char * function, as_list * arglist);