Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
aerospike
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
193
aerospike_scan_background
(
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
215
aerospike_scan_wait
(
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
247
aerospike_scan_info
(
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
282
aerospike_scan_foreach
(
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
325
aerospike_scan_node
(
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
378
aerospike_scan_async
(
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
438
aerospike_scan_node_async
(
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