All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
aerospike_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 
19 /**
20  * @defgroup scan_operations Scan Operations
21  * @ingroup client_operations
22  *
23  * Aerospike Scan Operations provide the ability to scan all record of a
24  * namespace and set in an Aerospike database.
25  *
26  * ## Usage
27  *
28  * Before you can execute a scan, you first need to define a scan using
29  * as_scan. See as_scan for details on defining scans.
30  *
31  * Once you have a scan defined, then you can execute the scan
32  * using either:
33  *
34  * - aerospike_scan_foreach() — Execute a scan on the database, then process
35  * the results.
36  * - aerospike_scan_background() — Send a scan to the database, and not wait
37  * for completed. The scan is given an id, which can be used to query the
38  * scan status.
39  *
40  * When aerospike_scan_foreach() is executed, it will process the results
41  * and create records on the stack. Because the records are on the stack,
42  * they will only be available within the context of the callback function.
43  *
44  * When aerospike_scan_background() is executed, the client will not wait for
45  * results from the database. Instead, the client will be given a scan_id,
46  * which can be used to query the scan status on the database via
47  * aerospike_scan_info().
48  *
49  * ## Walk-through
50  *
51  * First, we build a scan using as_scan. The scan will be on the "test"
52  * namespace and "demo" set. We will select only bins "a" and "b" to be returned
53  * for each record.
54  *
55  * ~~~~~~~~~~{.c}
56  * as_scan scan;
57  * as_scan_init(&scan, "test", "demo");
58  *
59  * as_scan_select_inita(&scan, 2);
60  * as_scan_select(&scan, "a");
61  * as_scan_select(&scan, "B");
62  * ~~~~~~~~~~
63  *
64  * Now that we have a scan defined, we want to execute it using
65  * aerospike_scan_foreach().
66  *
67  * ~~~~~~~~~~{.c}
68  * if ( aerospike_scan_foreach(&as, &err, NULL, &scan, callback, NULL) != AEROSPIKE_OK ) {
69  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
70  * }
71  * ~~~~~~~~~~
72  *
73  * The callback provided to the function above is implemented as:
74  *
75  * ~~~~~~~~~~{.c}
76  * bool callback(const as_val * val, void * udata) {
77  * as_record * rec = as_record_fromval(val);
78  * if ( !rec ) return false;
79  * fprintf("record contains %d bins", as_record_numbins(rec));
80  * return true;
81  * }
82  * ~~~~~~~~~~
83  *
84  * An as_scan is simply a scan definition, so it does not contain any state,
85  * allowing it to be reused for multiple scan operations.
86  *
87  * When you are finished with the scan, you should destroy the resources
88  * allocated to it:
89  *
90  * ~~~~~~~~~~{.c}
91  * as_scan_destroy(&scan);
92  * ~~~~~~~~~~
93  */
94 
95 #include <aerospike/aerospike.h>
96 #include <aerospike/as_listener.h>
97 #include <aerospike/as_error.h>
98 #include <aerospike/as_policy.h>
99 #include <aerospike/as_record.h>
100 #include <aerospike/as_scan.h>
101 #include <aerospike/as_status.h>
102 #include <aerospike/as_val.h>
103 
104 #ifdef __cplusplus
105 extern "C" {
106 #endif
107 
108 /******************************************************************************
109  * TYPES
110  *****************************************************************************/
111 
112 /**
113  * This callback will be called for each value or record returned from a synchronous scan.
114  * Multiple threads will likely be calling this callback in parallel. Therefore,
115  * your callback implementation should be thread safe.
116  *
117  * The following functions accept the callback:
118  * - aerospike_scan_foreach()
119  * - aerospike_scan_node()
120  *
121  * ~~~~~~~~~~{.c}
122  * bool my_callback(const as_val * val, void * udata) {
123  * return true;
124  * }
125  * ~~~~~~~~~~
126  *
127  * @param val The value received from the query.
128  * @param udata User-data provided to the calling function.
129  *
130  * @return `true` to continue to the next value. Otherwise, the scan will end.
131  *
132  * @ingroup scan_operations
133  */
134 typedef bool (*aerospike_scan_foreach_callback)(const as_val* val, void* udata);
135 
136 /**
137  * Asynchronous scan user callback. This function is called for each record returned.
138  * This function is also called once when the scan completes or an error has occurred.
139  *
140  * @param err This error structure is only populated when the command fails. Null on success.
141  * @param record Returned record. Use as_val_reserve() on record to prevent calling function from destroying.
142  * The record will be null on final scan completion or scan error.
143  * @param udata User data that is forwarded from asynchronous command function.
144  * @param event_loop Event loop that this command was executed on. Use this event loop when running
145  * nested asynchronous commands when single threaded behavior is desired for the
146  * group of commands.
147  *
148  * @return `true` to continue to the next value. Otherwise, the scan will end.
149  *
150  * @ingroup scan_operations
151  */
152 typedef bool (*as_async_scan_listener)(as_error* err, as_record* record, void* udata, as_event_loop* event_loop);
153 
154 /******************************************************************************
155  * FUNCTIONS
156  *****************************************************************************/
157 
158 /**
159  * Scan the records in the specified namespace and set in the cluster.
160  *
161  * Scan will be run in the background by a thread on client side.
162  * No callback will be called in this case.
163  *
164  * ~~~~~~~~~~{.c}
165  * as_scan scan;
166  * as_scan_init(&scan, "test", "demo");
167  *
168  * uint64_t scanid = 0;
169  *
170  * if (aerospike_scan_background(&as, &err, NULL, &scan, &scanid) != AEROSPIKE_OK) {
171  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
172  * }
173  * else {
174  * printf("Running background scan job: %ll", scanid);
175  * }
176  * as_scan_destroy(&scan);
177  * ~~~~~~~~~~
178  *
179  * The scanid can be used to query the status of the scan running in the
180  * database via aerospike_scan_info().
181  *
182  * @param as The aerospike instance to use for this operation.
183  * @param err The as_error to be populated if an error occurs.
184  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
185  * @param scan The scan to execute against the cluster.
186  * @param scan_id The id for the scan job, which can be used for querying the status of the scan.
187  *
188  * @return AEROSPIKE_OK on success. Otherwise an error occurred.
189  *
190  * @ingroup scan_operations
191  */
192 as_status
194  aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan,
195  uint64_t* scan_id
196  );
197 
198 /**
199  * Wait for a background scan to be completed by servers.
200  *
201  * ~~~~~~~~~~{.c}
202  * uint64_t scan_id = 1234;
203  * aerospike_scan_wait(&as, &err, NULL, scan_id, 0);
204  * ~~~~~~~~~~
205  *
206  * @param as The aerospike instance to use for this operation.
207  * @param err The as_error to be populated if an error occurs.
208  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
209  * @param scan_id The id for the scan job.
210  * @param interval_ms The polling interval in milliseconds. If zero, 1000 ms is used.
211  *
212  * @return AEROSPIKE_OK on success. Otherwise an error occurred.
213  */
214 as_status
216  aerospike* as, as_error* err, const as_policy_info* policy, uint64_t scan_id,
217  uint32_t interval_ms
218  );
219 
220 /**
221  * Check the progress of a background scan running on the database. The status
222  * of the scan running on the datatabse will be populated into an as_scan_info.
223  *
224  * ~~~~~~~~~~{.c}
225  * uint64_t scan_id = 1234;
226  * as_scan_info scan_info;
227  *
228  * if (aerospike_scan_info(&as, &err, NULL, &scan, scan_id, &scan_info) != AEROSPIKE_OK) {
229  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
230  * }
231  * else {
232  * printf("Scan id=%ll, status=%d percent=%d", scan_id, scan_info.status, scan_info.progress_pct);
233  * }
234  * ~~~~~~~~~~
235  *
236  * @param as The aerospike instance to use for this operation.
237  * @param err The as_error to be populated if an error occurs.
238  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
239  * @param scan_id The id for the scan job to check the status of.
240  * @param info Information about this scan, to be populated by this operation.
241  *
242  * @return AEROSPIKE_OK on success. Otherwise an error occurred.
243  *
244  * @ingroup scan_operations
245  */
246 as_status
248  aerospike* as, as_error* err, const as_policy_info* policy, uint64_t scan_id, as_scan_info* info
249  );
250 
251 /**
252  * Scan the records in the specified namespace and set in the cluster.
253  *
254  * Call the callback function for each record scanned. When all records have
255  * been scanned, then callback will be called with a NULL value for the record.
256  *
257  * Multiple threads will likely be calling the callback in parallel. Therefore,
258  * your callback implementation should be thread safe.
259  *
260  * ~~~~~~~~~~{.c}
261  * as_scan scan;
262  * as_scan_init(&scan, "test", "demo");
263  *
264  * if (aerospike_scan_foreach(&as, &err, NULL, &scan, callback, NULL) != AEROSPIKE_OK) {
265  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
266  * }
267  * as_scan_destroy(&scan);
268  * ~~~~~~~~~~
269  *
270  * @param as The aerospike instance to use for this operation.
271  * @param err The as_error to be populated if an error occurs.
272  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
273  * @param scan The scan to execute against the cluster.
274  * @param callback The function to be called for each record scanned.
275  * @param udata User-data to be passed to the callback.
276  *
277  * @return AEROSPIKE_OK on success. Otherwise an error occurred.
278  *
279  * @ingroup scan_operations
280  */
281 as_status
283  aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan,
284  aerospike_scan_foreach_callback callback, void* udata
285  );
286 
287 /**
288  * Scan the records in the specified namespace and set for a single node.
289  *
290  * The callback function will be called for each record scanned. When all records have
291  * been scanned, then callback will be called with a NULL value for the record.
292  *
293  * ~~~~~~~~~~{.c}
294  * char* node_names = NULL;
295  * int n_nodes = 0;
296  * as_cluster_get_node_names(as->cluster, &n_nodes, &node_names);
297  *
298  * if (n_nodes <= 0)
299  * return <error>;
300  *
301  * as_scan scan;
302  * as_scan_init(&scan, "test", "demo");
303  *
304  * if (aerospike_scan_node(&as, &err, NULL, &scan, node_names[0], callback, NULL) != AEROSPIKE_OK ) {
305  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
306  * }
307  *
308  * free(node_names);
309  * as_scan_destroy(&scan);
310  * ~~~~~~~~~~
311  *
312  * @param as The aerospike instance to use for this operation.
313  * @param err The as_error to be populated if an error occurs.
314  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
315  * @param scan The scan to execute against the cluster.
316  * @param node_name The node name to scan.
317  * @param callback The function to be called for each record scanned.
318  * @param udata User-data to be passed to the callback.
319  *
320  * @return AEROSPIKE_OK on success. Otherwise an error occurred.
321  *
322  * @ingroup scan_operations
323  */
324 as_status
326  aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan,
327  const char* node_name, aerospike_scan_foreach_callback callback, void* udata
328  );
329 
330 /**
331  * Asynchronously scan the records in the specified namespace and set in the cluster.
332  *
333  * Call the listener function for each record scanned. When all records have
334  * been scanned, then listener will be called with a NULL value for the record.
335  *
336  * Scans of each node will be run on the same event loop, so the listener's implementation does
337  * not need to be thread safe.
338  *
339  * ~~~~~~~~~~{.c}
340  * bool my_listener(as_error* err, as_record* record, void* udata, as_event_loop* event_loop)
341  * {
342  * if (err) {
343  * printf("Scan failed: %d %s\n", err->code, err->message);
344  * return false;
345  * }
346  *
347  * if (! record) {
348  * printf("Scan ended\n");
349  * return false;
350  * }
351  *
352  * // Process record
353  * // Do not call as_record_destroy() because the calling function will do that for you.
354  * return true;
355  * }
356  *
357  * as_scan scan;
358  * as_scan_init(&scan, "test", "demo");
359  *
360  * as_status status = aerospike_scan_async(&as, &err, NULL, &scan, NULL, my_listener, NULL, NULL);
361  * as_scan_destroy(&scan);
362  * ~~~~~~~~~~
363  *
364  * @param as The aerospike instance to use for this operation.
365  * @param err The as_error to be populated if an error occurs.
366  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
367  * @param scan The scan to execute against the cluster.
368  * @param scan_id The id for the scan job. Use NULL if the scan_id will not be used.
369  * @param listener The function to be called for each record scanned.
370  * @param udata User-data to be passed to the callback.
371  * @param event_loop Event loop assigned to run this command. If NULL, an event loop will be choosen by round-robin.
372  *
373  * @return AEROSPIKE_OK if async scan succesfully queued. Otherwise an error.
374  *
375  * @ingroup scan_operations
376  */
377 as_status
379  aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan, uint64_t* scan_id,
380  as_async_scan_listener listener, void* udata, as_event_loop* event_loop
381  );
382 
383 /**
384  * Asynchronously scan the records in the specified namespace and set for a single node.
385  *
386  * The listener function will be called for each record scanned. When all records have
387  * been scanned, then callback will be called with a NULL value for the record.
388  *
389  * ~~~~~~~~~~{.c}
390  * bool my_listener(as_error* err, as_record* record, void* udata, as_event_loop* event_loop)
391  * {
392  * if (err) {
393  * printf("Scan failed: %d %s\n", err->code, err->message);
394  * return false;
395  * }
396  *
397  * if (! record) {
398  * printf("Scan ended\n");
399  * return false;
400  * }
401  *
402  * // Process record
403  * // Do not call as_record_destroy() because the calling function will do that for you.
404  * return true;
405  * }
406  *
407  * char* node_names = NULL;
408  * int n_nodes = 0;
409  * as_cluster_get_node_names(as->cluster, &n_nodes, &node_names);
410  *
411  * if (n_nodes <= 0)
412  * return <error>;
413  *
414  * as_scan scan;
415  * as_scan_init(&scan, "test", "demo");
416  *
417  * as_status status = aerospike_scan_node_async(&as, &err, NULL, &scan, NULL, node_names[0], my_listener, NULL, NULL);
418  *
419  * free(node_names);
420  * as_scan_destroy(&scan);
421  * ~~~~~~~~~~
422  *
423  * @param as The aerospike instance to use for this operation.
424  * @param err The as_error to be populated if an error occurs.
425  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
426  * @param scan The scan to execute against the cluster.
427  * @param scan_id The id for the scan job. Use NULL if the scan_id will not be used.
428  * @param node_name The node name to scan.
429  * @param listener The function to be called for each record scanned.
430  * @param udata User-data to be passed to the callback.
431  * @param event_loop Event loop assigned to run this command. If NULL, an event loop will be choosen by round-robin.
432  *
433  * @return AEROSPIKE_OK if async scan succesfully queued. Otherwise an error.
434  *
435  * @ingroup scan_operations
436  */
437 as_status
439  aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan, uint64_t* scan_id,
440  const char* node_name, as_async_scan_listener listener, void* udata, as_event_loop* event_loop
441  );
442 
443 #ifdef __cplusplus
444 } // end extern "C"
445 #endif
as_status aerospike_scan_background(aerospike *as, as_error *err, const as_policy_scan *policy, const as_scan *scan, uint64_t *scan_id)
as_status aerospike_scan_info(aerospike *as, as_error *err, const as_policy_info *policy, uint64_t scan_id, as_scan_info *info)
as_status
Definition: as_status.h:30
as_status aerospike_scan_node_async(aerospike *as, as_error *err, const as_policy_scan *policy, const as_scan *scan, uint64_t *scan_id, const char *node_name, as_async_scan_listener listener, void *udata, as_event_loop *event_loop)
bool(* aerospike_scan_foreach_callback)(const as_val *val, void *udata)
Definition: as_val.h:57
as_status aerospike_scan_foreach(aerospike *as, as_error *err, const as_policy_scan *policy, const as_scan *scan, aerospike_scan_foreach_callback callback, void *udata)
bool(* as_async_scan_listener)(as_error *err, as_record *record, void *udata, as_event_loop *event_loop)
as_status aerospike_scan_wait(aerospike *as, as_error *err, const as_policy_info *policy, uint64_t scan_id, uint32_t interval_ms)
as_status aerospike_scan_node(aerospike *as, as_error *err, const as_policy_scan *policy, const as_scan *scan, const char *node_name, aerospike_scan_foreach_callback callback, void *udata)
as_status aerospike_scan_async(aerospike *as, as_error *err, const as_policy_scan *policy, const as_scan *scan, uint64_t *scan_id, as_async_scan_listener listener, void *udata, as_event_loop *event_loop)