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