Пример #1
0
/**
 * 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, &params);
			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, &params);
			rc = process_node_response(v, err);
		}

	}
	else {
		// If the user want to execute only on a single node...
		if (node) {
Пример #2
0
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;
		}
	}
}