All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
aerospike_batch.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2017 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 batch_operations Batch Operations
21  * @ingroup client_operations
22  *
23  * Aerospike provides a batch API to access data in the cluster.
24  *
25  * The Batch API is a collection of APIs that use as_keyset as for looking up
26  * records for accessing in the cluster.
27  *
28  */
29 
30 #include <aerospike/aerospike.h>
31 #include <aerospike/as_batch.h>
32 #include <aerospike/as_listener.h>
33 #include <aerospike/as_error.h>
34 #include <aerospike/as_key.h>
35 #include <aerospike/as_list.h>
37 #include <aerospike/as_policy.h>
38 #include <aerospike/as_record.h>
39 #include <aerospike/as_status.h>
40 #include <aerospike/as_val.h>
41 #include <aerospike/as_vector.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /******************************************************************************
48  * TYPES
49  *****************************************************************************/
50 
51 /**
52  * Key and bin names used in batch commands where variables bins are needed for each key.
53  * The returned records are located in the same batch record.
54  */
55 typedef struct as_batch_read_record_s {
56  /**
57  * The key requested.
58  */
60 
61  /**
62  * Bin names requested for this key.
63  */
64  char** bin_names;
65 
66  /**
67  * Count of bin names requested for this key.
68  */
69  uint32_t n_bin_names;
70 
71  /**
72  * If true, ignore bin_names and read all bins.
73  * If false and bin_names are set, read specified bin_names.
74  * If false and bin_names are not set, read record header (generation, expiration) only.
75  */
77 
78  /**
79  * The result of the read transaction.
80  * <p>
81  * Values:
82  * <ul>
83  * <li>
84  * AEROSPIKE_OK: record found
85  * </li>
86  * <li>
87  * AEROSPIKE_ERR_RECORD_NOT_FOUND: record not found
88  * </li>
89  * <li>
90  * Other: transaction error code
91  * </li>
92  * </ul>
93  */
95 
96  /**
97  * The record for the key requested. For "exists" calls, the record will never contain bins
98  * but will contain metadata (generation and expiration) when the record exists.
99  */
102 
103 /**
104  * List of as_batch_read_record(s).
105  */
106 typedef struct as_batch_read_records_s {
107  /**
108  * List of as_batch_read_record(s).
109  */
112 
113 /**
114  * This callback will be called with the results of aerospike_batch_get(),
115  * or aerospike_batch_exists() functions.
116  *
117  * The `results` argument will be an array of `n` as_batch_read entries. The
118  * `results` argument is on the stack and is only available within the context
119  * of the callback. To use the data outside of the callback, copy the data.
120  *
121  * ~~~~~~~~~~{.c}
122  * bool my_callback(const as_batch_read * results, uint32_t n, void * udata) {
123  * return true;
124  * }
125  * ~~~~~~~~~~
126  *
127  * @param results The results from the batch request.
128  * @param n The number of results from the batch request.
129  * @param udata User-data provided to the calling function.
130  *
131  * @return `true` on success. Otherwise, an error occurred.
132  *
133  * @ingroup batch_operations
134  */
135 typedef bool (*aerospike_batch_read_callback)(const as_batch_read* results, uint32_t n, void* udata);
136 
137 /**
138  * @private
139  * This callback is used by aerospike_batch_get_xdr() to send one batch record at a time
140  * as soon as they are received in no particular order.
141  */
142 typedef bool (*as_batch_callback_xdr)(as_key* key, as_record* record, void* udata);
143 
144 /**
145  * Asynchronous batch user callback. This function is called once when the batch completes or an
146  * error has occurred.
147  *
148  * @param err This error structure is only populated when the command fails. Null on success.
149  * @param records Returned records. Records must be destroyed with as_batch_read_destroy() when done.
150  * @param udata User data that is forwarded from asynchronous command function.
151  * @param event_loop Event loop that this command was executed on. Use this event loop when running
152  * nested asynchronous commands when single threaded behavior is desired for the
153  * group of commands.
154  *
155  * @ingroup batch_operations
156  */
157 typedef void (*as_async_batch_listener)(as_error* err, as_batch_read_records* records, void* udata, as_event_loop* event_loop);
158 
159 /******************************************************************************
160  * FUNCTIONS
161  *****************************************************************************/
162 
163 /**
164  * Initialize `as_batch_read_records` with specified capacity on the stack using alloca().
165  *
166  * When the batch is no longer needed, then use as_batch_destroy() to
167  * release the batch and associated resources.
168  *
169  * @param __records Batch record list.
170  * @param __capacity Initial capacity of batch record list. List will resize when necessary.
171  *
172  * @relates as_batch_read_record
173  * @ingroup batch_operations
174  */
175 #define as_batch_read_inita(__records, __capacity) \
176  as_vector_inita(&((__records)->list), sizeof(as_batch_read_record), __capacity);
177 
178 /**
179  * Initialize `as_batch_read_records` with specified capacity on the heap.
180  *
181  * When the batch is no longer needed, then use as_batch_destroy() to
182  * release the batch and associated resources.
183  *
184  * @param records Batch record list.
185  * @param capacity Initial capacity of batch record list. List will resize when necessary.
186  *
187  * @relates as_batch_read_record
188  * @ingroup batch_operations
189  */
190 static inline void
191 as_batch_read_init(as_batch_read_records* records, uint32_t capacity)
192 {
193  as_vector_init(&records->list, sizeof(as_batch_read_record), capacity);
194 }
195 
196 /**
197  * Create `as_batch_read_records` on heap with specified list capacity on the heap.
198  *
199  * When the batch is no longer needed, then use as_batch_destroy() to
200  * release the batch and associated resources.
201  *
202  * @param capacity Initial capacity of batch record list. List will resize when necessary.
203  * @return Batch record list.
204  *
205  * @relates as_batch_read_record
206  * @ingroup batch_operations
207  */
208 static inline as_batch_read_records*
209 as_batch_read_create(uint32_t capacity)
210 {
211  return (as_batch_read_records*) as_vector_create(sizeof(as_batch_read_record), capacity);
212 }
213 
214 /**
215  * Reserve a new `as_batch_read_record` slot. Capacity will be increased when necessary.
216  * Return reference to record. The record is already initialized to zeroes.
217  *
218  * @param records Batch record list.
219  *
220  * @relates as_batch_read_record
221  * @ingroup batch_operations
222  */
223 static inline as_batch_read_record*
225 {
226  return (as_batch_read_record*)as_vector_reserve(&records->list);
227 }
228 
229 /**
230  * Destroy keys and records in record list. It's the responsility of the caller to
231  * free `as_batch_read_record.bin_names` when necessary.
232  *
233  * @param records Batch record list.
234  *
235  * @relates as_batch_read_record
236  * @ingroup batch_operations
237  */
238 void
240 
241 /**
242  * Do the connected servers support the new batch index protocol.
243  * The cluster must already be connected (aerospike_connect()) prior to making this call.
244  */
245 bool
247 
248 /**
249  * Read multiple records for specified batch keys in one batch call.
250  * This method allows different namespaces/bins to be requested for each key in the batch.
251  * The returned records are located in the same batch array.
252  * This method requires Aerospike Server version >= 3.6.0.
253  *
254  * ~~~~~~~~~~{.c}
255  * as_batch_read_records records;
256  * as_batch_read_inita(&records, 10);
257  *
258  * char* bin_names[] = {"bin1", "bin2"};
259  * char* ns = "ns";
260  * char* set = "set";
261  *
262  * as_batch_read_record* record = as_batch_read_reserve(&records);
263  * as_key_init(&record->key, ns, set, "key1");
264  * record->bin_names = bin_names;
265  * record->n_bin_names = 2;
266  *
267  * record = as_batch_read_reserve(&records);
268  * as_key_init(&record->key, ns, set, "key2");
269  * record->read_all_bins = true;
270  *
271  * if (aerospike_batch_read(&as, &err, NULL, &records) != AEROSPIKE_OK) {
272  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
273  * }
274  *
275  * as_batch_read_destroy(&records);
276  * ~~~~~~~~~~
277  *
278  * @param as The aerospike instance to use for this operation.
279  * @param err The as_error to be populated if an error occurs.
280  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
281  * @param records List of keys and bins to retrieve.
282  * The returned records are located in the same array.
283  *
284  * @return AEROSPIKE_OK if successful. Otherwise an error.
285  *
286  * @ingroup batch_operations
287  */
288 as_status
290  aerospike* as, as_error* err, const as_policy_batch* policy, as_batch_read_records* records
291  );
292 
293 /**
294  * Asynchronously read multiple records for specified batch keys in one batch call.
295  * This method allows different namespaces/bins to be requested for each key in the batch.
296  * The returned records are located in the same batch array.
297  * This method requires Aerospike Server version >= 3.6.0.
298  *
299  * ~~~~~~~~~~{.c}
300  * void my_listener(as_error* err, as_batch_read_records* records, void* udata, as_event_loop* event_loop)
301  * {
302  * if (err) {
303  * fprintf(stderr, "Command failed: %d %s\n", err->code, err->message);
304  * }
305  * else {
306  * as_vector* list = &records->list;
307  * for (uint32_t i = 0; i < list->size; i++) {
308  * as_batch_read_record* record = as_vector_get(list, i);
309  * // Process record
310  * }
311  * }
312  * // Must free batch records on both success and error conditions because it was created
313  * // before calling aerospike_batch_read_async().
314  * as_batch_read_destroy(records);
315  * }
316  *
317  * as_batch_read_records* records = as_batch_read_create(10);
318  *
319  * // bin_names can be placed on stack because it's only referenced before being queued on event loop.
320  * char* bin_names[] = {"bin1", "bin2"};
321  * char* ns = "ns";
322  * char* set = "set";
323  *
324  * as_batch_read_record* record = as_batch_read_reserve(records);
325  * as_key_init(&record->key, ns, set, "key1");
326  * record->bin_names = bin_names;
327  * record->n_bin_names = 2;
328  *
329  * record = as_batch_read_reserve(records);
330  * as_key_init(&record->key, ns, set, "key2");
331  * record->read_all_bins = true;
332  *
333  * as_status status = aerospike_batch_read_async(&as, &err, NULL, records, NULL, my_listener, NULL);
334  *
335  * if (status != AEROSPIKE_OK) {
336  * // Must free batch records on queue error because the callback will not be called.
337  * as_batch_read_destroy(records);
338  * }
339  *
340  * ~~~~~~~~~~
341  *
342  * @param as The aerospike instance to use for this operation.
343  * @param err The as_error to be populated if an error occurs.
344  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
345  * @param records List of keys and bins to retrieve. The returned records are located in the same array.
346  * Must create using as_batch_read_create() (which allocates memory on heap) because
347  * async method will return immediately after queueing command.
348  * @param listener User function to be called with command results.
349  * @param udata User data to be forwarded to user callback.
350  * @param event_loop Event loop assigned to run this command. If NULL, an event loop will be choosen by round-robin.
351  *
352  * @return AEROSPIKE_OK if async command succesfully queued. Otherwise an error.
353  *
354  * @ingroup batch_operations
355  */
356 as_status
358  aerospike* as, as_error* err, const as_policy_batch* policy, as_batch_read_records* records,
359  as_async_batch_listener listener, void* udata, as_event_loop* event_loop
360  );
361 
362 /**
363  * Look up multiple records by key, then return all bins.
364  *
365  * ~~~~~~~~~~{.c}
366  * as_batch batch;
367  * as_batch_inita(&batch, 3);
368  *
369  * as_key_init(as_batch_keyat(&batch,0), "ns", "set", "key1");
370  * as_key_init(as_batch_keyat(&batch,1), "ns", "set", "key2");
371  * as_key_init(as_batch_keyat(&batch,2), "ns", "set", "key3");
372  *
373  * if ( aerospike_batch_get(&as, &err, NULL, &batch, callback, NULL) != AEROSPIKE_OK ) {
374  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
375  * }
376  *
377  * as_batch_destroy(&batch);
378  * ~~~~~~~~~~
379  *
380  * @param as The aerospike instance to use for this operation.
381  * @param err The as_error to be populated if an error occurs.
382  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
383  * @param batch The batch of keys to read.
384  * @param callback The callback to invoke for each record read.
385  * @param udata The user-data for the callback.
386  *
387  * @return AEROSPIKE_OK if successful. Otherwise an error.
388  *
389  * @ingroup batch_operations
390  */
391 as_status
393  aerospike * as, as_error * err, const as_policy_batch * policy, const as_batch * batch,
394  aerospike_batch_read_callback callback, void * udata
395  );
396 
397 /**
398  * @private
399  * Perform batch reads for XDR. The callback will be called for each record as soon as it's
400  * received in no particular order.
401  */
402 as_status
404  aerospike* as, as_error* err, const as_policy_batch* policy, const as_batch* batch,
405  as_batch_callback_xdr callback, void* udata
406  );
407 
408 /**
409  * Look up multiple records by key, then return specified bins.
410  *
411  * ~~~~~~~~~~{.c}
412  * as_batch batch;
413  * as_batch_inita(&batch, 3);
414  *
415  * as_key_init(as_batch_keyat(&batch,0), "ns", "set", "key1");
416  * as_key_init(as_batch_keyat(&batch,1), "ns", "set", "key2");
417  * as_key_init(as_batch_keyat(&batch,2), "ns", "set", "key3");
418  *
419  * const char* bin_filters[] = {"bin1", "bin2"};
420  *
421  * if ( aerospike_batch_get_bins(&as, &err, NULL, &batch, bin_filters, 2, callback, NULL) != AEROSPIKE_OK ) {
422  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
423  * }
424  *
425  * as_batch_destroy(&batch);
426  * ~~~~~~~~~~
427  *
428  * @param as The aerospike instance to use for this operation.
429  * @param err The as_error to be populated if an error occurs.
430  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
431  * @param batch The batch of keys to read.
432  * @param bins Bin filters. Only return these bins.
433  * @param n_bins The number of bin filters.
434  * @param callback The callback to invoke for each record read.
435  * @param udata The user-data for the callback.
436  *
437  * @return AEROSPIKE_OK if successful. Otherwise an error.
438  *
439  * @ingroup batch_operations
440  */
441 as_status
443  aerospike* as, as_error* err, const as_policy_batch* policy, const as_batch* batch,
444  const char** bins, uint32_t n_bins, aerospike_batch_read_callback callback, void* udata
445  );
446 
447 /**
448  * Test whether multiple records exist in the cluster.
449  *
450  * ~~~~~~~~~~{.c}
451  * as_batch batch;
452  * as_batch_inita(&batch, 3);
453  *
454  * as_key_init(as_batch_keyat(&batch,0), "ns", "set", "key1");
455  * as_key_init(as_batch_keyat(&batch,1), "ns", "set", "key2");
456  * as_key_init(as_batch_keyat(&batch,2), "ns", "set", "key3");
457  *
458  * if ( aerospike_batch_exists(&as, &err, NULL, &batch, callback, NULL) != AEROSPIKE_OK ) {
459  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
460  * }
461  *
462  * as_batch_destroy(&batch);
463  * ~~~~~~~~~~
464  *
465  * @param as The aerospike instance to use for this operation.
466  * @param err The as_error to be populated if an error occurs.
467  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
468  * @param batch The batch of keys to read.
469  * @param callback The callback to invoke for each record read.
470  * @param udata The user-data for the callback.
471  *
472  * @return AEROSPIKE_OK if successful. Otherwise an error.
473  *
474  * @ingroup batch_operations
475  */
476 as_status
478  aerospike * as, as_error * err, const as_policy_batch * policy, const as_batch * batch,
479  aerospike_batch_read_callback callback, void * udata
480  );
481 
482 #ifdef __cplusplus
483 } // end extern "C"
484 #endif