/** * This is the main driver function which can cater to different types of * scan interfaces exposed to the outside world. This functions should not be * exposed to the outside world. This generic function exists because we dont * want to duplicate too much of code. * * @param as - the aerospike cluster to connect to. * @param err - the error is populated if the return value is not AEROSPIKE_OK. * @param policy - the policy to use for this operation. If NULL, then the default policy will be used. * @param node - the name of the node to perform the scan on. * @param scan - the scan to perform * @param callback - the function to be called for each record scanned. * @param udata - user-data to be passed to the callback * * @return AEROSPIKE_OK on success. Otherwise an error occurred. */ static as_status aerospike_scan_generic( aerospike * as, as_error * err, const as_policy_scan * policy, const char * node, const as_scan * scan, aerospike_scan_foreach_callback callback, void * udata) { cl_rv clrv; as_status rc = AEROSPIKE_OK; cl_scan clscan; as_scan_toclscan(scan, policy, &clscan, false, NULL); if ( clscan.udf.type == CL_SCAN_UDF_NONE ) { scan_bridge bridge_udata = { .udata = udata, .callback = callback }; struct cl_scan_parameters_s params = { .fail_on_cluster_change = clscan.params.fail_on_cluster_change, .priority = clscan.params.priority, .concurrent = clscan.params.concurrent, .threads_per_node = 0 }; int n_bins = scan->select.size; cl_bin * bins = NULL; if ( n_bins > 0 ) { bins = (cl_bin *) alloca(sizeof(cl_bin) * n_bins); for( int i = 0; i < n_bins; i++ ) { strcpy(bins[i].bin_name, scan->select.entries[i]); citrusleaf_object_init_null(&bins[i].object); } } // If the user want to execute only on a single node... if (node) { clrv = citrusleaf_scan_node(as->cluster, (char *) node, (char *) scan->ns, (char *) scan->set, bins, n_bins, scan->no_bins, scan->percent, simplescan_cb, &bridge_udata, ¶ms); rc = as_error_fromrc(err, clrv); } else { // We are not using the very old citrusleaf_scan() call here. First of all, its // very inefficient. It makes a single node on the cluster coordinate the job // of scan. Moreover, it does not accept params like priority etc. cf_vector *v = citrusleaf_scan_all_nodes(as->cluster, (char *) scan->ns, (char *) scan->set, bins, n_bins, scan->no_bins, scan->percent, simplescan_cb, &bridge_udata, ¶ms); rc = process_node_response(v, err); } } else { // If the user want to execute only on a single node... if (node) {
void asval_to_clobject(as_val * val, cl_object * obj) { switch(val->type) { case AS_NIL: { citrusleaf_object_init_null(obj); break; } case AS_INTEGER: { as_integer * v = as_integer_fromval(val); citrusleaf_object_init_int(obj, as_integer_toint(v)); break; } case AS_STRING: { as_string * v = as_string_fromval(val); citrusleaf_object_init_str(obj, as_string_get(v)); break; } case AS_BYTES: { as_bytes * v = as_bytes_fromval(val); citrusleaf_object_init_blob2(obj, v->value, v->size, (cl_type)v->type); break; } case AS_LIST:{ as_buffer buffer; as_buffer_init(&buffer); as_serializer ser; as_msgpack_init(&ser); as_serializer_serialize(&ser, val, &buffer); as_serializer_destroy(&ser); citrusleaf_object_init_blob_handoff(obj, buffer.data, buffer.size, CL_LIST); break; } case AS_MAP: { as_buffer buffer; as_buffer_init(&buffer); as_serializer ser; as_msgpack_init(&ser); as_serializer_serialize(&ser, val, &buffer); as_serializer_destroy(&ser); citrusleaf_object_init_blob_handoff(obj, buffer.data, buffer.size, CL_MAP); break; } default: { // raise an error break; } } }