// ---------------------------------------------------------------------------------- // // execute udf on record // // def execute_udf(key, module_name, func_name, udf_args = [], options = {}) // // params: // key - AeropsikeC::Key object // module_name - string, registered module name // func_name - string, function name in module to execute // udf_args - arguments passed to udf // options: // policy - AerospikeC::ApplyPolicy // // ------ // RETURN: // 1. data returned from udf // static VALUE execute_udf(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; VALUE key; VALUE module_name; VALUE func_name; VALUE udf_args; VALUE options; rb_scan_args(argc, argv, "32", &key, &module_name, &func_name, &udf_args, &options); // default values for optional arguments if ( NIL_P(options) ) options = rb_hash_new(); if ( NIL_P(udf_args) ) udf_args = rb_ary_new(); as_key * k = rb_aero_KEY; as_arraylist * args = array2as_list(udf_args); as_policy_apply * policy = get_policy(options); as_val * res = NULL; char * c_module_name = StringValueCStr(module_name); char * c_func_name = StringValueCStr(func_name); if ( ( status = aerospike_key_apply(as, &err, policy, k, c_module_name, c_func_name, (as_list *)args, &res) ) != AEROSPIKE_OK ) { as_arraylist_destroy(args); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 3, rb_str_new2("[Client][execute_udf] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO, rb_aero_MOD_INFO); return Qnil; } raise_as_error(err); } VALUE result = as_val2rb_val(res); as_val_destroy(&res); as_arraylist_destroy(args); VALUE key_info = rb_aero_KEY_INFO; rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 3, rb_str_new2("[Client][execute_udf] success"), rb_aero_KEY_INFO, rb_aero_MOD_INFO); return result; }
as_status aerospike_lset_exists( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, as_boolean *exists) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !exists) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSET) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not lset type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); // bump the ref count as_arraylist_append(&arglist, (as_val *)val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSET_PACKAGE, LDT_SET_OP_EXISTS, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } as_boolean_init(exists, ival==1 ? true: false); return err->code; } // aerospike_lset_exists()
/* ****************************************************************************************************** Applies a UDF to a record at the Aerospike DB. * * @param aerospike_obj_p The C client's aerospike object. * @param as_key_p The C client's as_key that identifies the * record on which UDF will be applied. * @param error_p The C client's as_error to be set to the encountered error. * @param module_p The name of the UDF module registered * against the Aerospike DB. * @param function_p The name of the function to be applied to * the record. * @param args_pp An array of arguments for the UDF. * @param return_value_p It will contain result value of calling the * UDF. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_udf_apply(Aerospike_object* aerospike_obj_p, as_key* as_key_p, as_error* error_p, char* module_p, char* function_p, zval** args_pp, zval* return_value_p, zval* options_p) { as_arraylist args_list; as_arraylist* args_list_p = NULL; as_static_pool udf_pool = {0}; as_val* udf_result_p = NULL; foreach_callback_udata udf_result_callback_udata; uint32_t serializer_policy = -1; as_policy_apply apply_policy; TSRMLS_FETCH_FROM_CTX(aerospike_obj_p->ts); set_policy_udf_apply(&aerospike_obj_p->as_ref_p->as_p->config, &apply_policy, &serializer_policy, options_p, error_p TSRMLS_CC); if (AEROSPIKE_OK != (error_p->code)) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } if ((*args_pp)) { as_arraylist_inita(&args_list, zend_hash_num_elements(Z_ARRVAL_PP(args_pp))); args_list_p = &args_list; AS_LIST_PUT(NULL, args_pp, args_list_p, &udf_pool, serializer_policy, error_p TSRMLS_CC); } if (AEROSPIKE_OK != (aerospike_key_apply(aerospike_obj_p->as_ref_p->as_p, error_p, &apply_policy, as_key_p, module_p, function_p, (as_list *) args_list_p, &udf_result_p))) { DEBUG_PHP_EXT_DEBUG("%s", error_p->message); goto exit; } if (return_value_p) { udf_result_callback_udata.udata_p = return_value_p; udf_result_callback_udata.error_p = error_p; AS_DEFAULT_GET(NULL, udf_result_p, &udf_result_callback_udata); } exit: if (udf_result_p) { as_val_destroy(udf_result_p); } if (args_list_p) { as_arraylist_destroy(args_list_p); } /* clean up the as_* objects that were initialised */ aerospike_helper_free_static_pool(&udf_pool); return error_p->code; }
// ======================================================================= // Pass in a value into the UDF -- and then get it back. Simple. // This is used to measure the performance of the end to end // call infrastructure. // Pass in LDT Bin and Value. // Return Value. // ======================================================================= as_status aerospike_lstack_same( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t in_val, uint32_t * out_valp) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !out_valp) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/out_valp cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not LSTACK type"); } // stack allocate the arg list. // Pass in the LDT Bin and the IN VALUE. as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_arraylist_append_int64(&arglist, in_val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, LDT_STACK_OP_SAME, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } if (ival !=0 ) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "same() Function Failed"); } *out_valp = (uint32_t)ival; return err->code; } // end as_status aerospike_lstack_same()
// ======================================================================= // Internal function to handle all of the functions that get an int back // from a call. // size() // one() // ======================================================================= as_status aerospike_lstack_ask_internal( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t *n, const char *operation ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !n) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); // All we need to pass in is the LDT Bin Name as_arraylist arglist; as_arraylist_inita(&arglist, 1); as_arraylist_append_string(&arglist, &ldt_bin); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, operation, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } *n = (uint32_t)ival; return err->code; } // end as_status aerospike_lstack_ask_internal()
// ======================================================================= static as_status aerospike_lstack_push_internal( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, const char *operation) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !val) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, ldt->module[0] == 0 ? 2 : 3); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); as_arraylist_append(&arglist, (as_val *) val); if (ldt->module[0] != 0) { as_string ldt_module; as_string_init(&ldt_module, (char *)ldt->module, false); as_arraylist_append_string(&arglist, &ldt_module); } as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, operation, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } // return value is the input if (p_return_val) { as_val_destroy(p_return_val); } return err->code; } // end aerospike_lstack_push_internal()
// ======================================================================= as_status aerospike_lstack_set_capacity( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t elements_capacity ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !elements_capacity) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/capacity cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_arraylist_append_int64(&arglist, elements_capacity); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, LDT_STACK_OP_CAPACITY_SET, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } if (ival !=0 ) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "capacity setting failed"); } return err->code; }
as_status aerospike_llist_find( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * search_val, as_list ** elements ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !search_val || !elements) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/search_val/elements cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } int list_argc = 2; /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, list_argc); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( search_val ); // bump the ref count so the arraylist_destroy will not reset the search_val as_arraylist_append(&arglist, (as_val *) search_val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, LDT_LIST_OP_FIND, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } *elements = (as_list *)p_return_val; return err->code; } // aerospike_llist_find()
static bool unpack_list(serial_context *ser_cont, uint32_t size, as_val **value) { if (VERBOSE) { ver("%sList, %u element(s)", indent(ser_cont), size); } as_arraylist *list = as_arraylist_new(size, 8); if (list == NULL) { err("Error while allocating list"); return false; } ser_cont->indent += 2; for (uint32_t i = 0; i < size; ++i) { as_val *element; if (!UNPACK_VALUE(ser_cont, &element)) { err("Error while unpacking list element"); as_arraylist_destroy(list); return false; } if (as_arraylist_set(list, i, element) != AS_ARRAYLIST_OK) { err("Error while populating list"); as_arraylist_destroy(list); return false; } } ser_cont->indent -= 2; *value = (as_val *)list; return true; }
as_status aerospike_llist_remove( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val *val ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/capacity cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); as_arraylist_append(&arglist, (as_val *) val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, LDT_LIST_OP_REMOVE, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (p_return_val != NULL) { as_val_destroy(p_return_val); } return err->code; }
as_status aerospike_lset_get( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, as_val **pp_return_val) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !pp_return_val) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/return cannot be null"); } if (ldt->type != AS_LDT_LSET) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not lset type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); // bump the ref count as_arraylist_append(&arglist, (as_val *)val); aerospike_key_apply( as, err, policy, key, DEFAULT_LSET_PACKAGE, LDT_SET_OP_GET, (as_list *)&arglist, pp_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (! *pp_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } return err->code; } // aerospike_lset_get()
int main(int argc, char* argv[]) { // Parse command line arguments. if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) { exit(-1); } // Connect to the aerospike database cluster. aerospike as; example_connect_to_aerospike(&as); // Start clean. example_remove_test_record(&as); // Register the UDF in the database cluster. if (! example_register_udf(&as, UDF_FILE_PATH)) { example_cleanup(&as); exit(-1); } // Write a record to the database. if (! write_record(&as)) { cleanup(&as); exit(-1); } as_error err; // Apply a simple UDF, with no arguments and no return value. if (aerospike_key_apply(&as, &err, NULL, &g_key, UDF_MODULE, "test_bin_1_add_1000", NULL, NULL) != AEROSPIKE_OK) { LOG("aerospike_key_apply() returned %d - %s", err.code, err.message); cleanup(&as); exit(-1); } LOG("test_bin_1_add_1000() was successfully applied"); if (! example_read_test_record(&as)) { example_cleanup(&as); exit(-1); } // Create an argument list for a (different) UDF. By using // as_arraylist_inita() we avoid some but not all internal heap usage, so we // must call as_arraylist_destroy(). as_arraylist args; as_arraylist_inita(&args, 3); as_arraylist_append_str(&args, "test-bin-2"); as_arraylist_append_int64(&args, 4); as_arraylist_append_int64(&args, 400); // Expect an integer return value. as_val* p_return_val = NULL; // Apply a UDF with arguments and a return value. if (aerospike_key_apply(&as, &err, NULL, &g_key, UDF_MODULE, "bin_transform", (as_list*)&args, &p_return_val) != AEROSPIKE_OK) { LOG("aerospike_key_apply() returned %d - %s", err.code, err.message); as_arraylist_destroy(&args); cleanup(&as); exit(-1); } as_arraylist_destroy(&args); if (! p_return_val) { LOG("aerospike_key_apply() retrieved null as_val object"); cleanup(&as); exit(-1); } // Extract an integer from the as_val returned. int64_t i_val = as_integer_getorelse(as_integer_fromval(p_return_val), -1); // Caller's responsibility to destroy as_val returned. as_val_destroy(p_return_val); if (i_val == -1) { LOG("aerospike_key_apply() retrieved non-as_integer object"); cleanup(&as); exit(-1); } LOG("bin_transform() was successfully applied - returned %" PRId64, i_val); if (! example_read_test_record(&as)) { example_cleanup(&as); exit(-1); } // Cleanup and disconnect from the database cluster. cleanup(&as); LOG("udf example successfully completed"); return 0; }
as_status aerospike_llist_filter( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_udf_function_name filter, const as_list *filter_args, as_list ** elements ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (filter_args && !filter) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "filter arguments without filter name specification"); } if (!as || !key || !ldt || !elements) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/peek_count/elements cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } int list_argc = filter ? 3 : 1; /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, list_argc); as_arraylist_append_string(&arglist, &ldt_bin); if (filter){ as_string filter_name; as_string_init(&filter_name, (char *)filter, false); as_arraylist_append_string(&arglist, &filter_name ); as_val_reserve( filter_args ); // bump the ref count as_arraylist_append(&arglist, (as_val *) filter_args ); } as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, filter ? LDT_LIST_OP_FILTER : LDT_LIST_OP_SCAN, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } *elements = (as_list *)p_return_val; return err->code; } // aerospike_llist_filter()
int main(int argc, char* argv[]) { // Parse command line arguments. if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) { exit(-1); } // Connect to the aerospike database cluster. aerospike as; example_connect_to_aerospike(&as); // Start clean. example_remove_test_record(&as); as_ldt lstack; // Create a large stack bin to use. No need to destroy as_ldt if using // as_ldt_init() on stack object. if (! as_ldt_init(&lstack, "mystack", AS_LDT_LSTACK, NULL)) { LOG("unable to initialize ldt"); example_cleanup(&as); exit(-1); } as_error err; // No need to destroy as_integer if using as_integer_init() on stack object. as_integer ival; as_integer_init(&ival, 123); // Push a few values onto the stack. if (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&ival) != AEROSPIKE_OK) { LOG("first aerospike_lstack_push() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } // No need to destroy as_string if using as_string_init() on stack object. as_string sval; as_string_init(&sval, "string stack value", false); if (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&sval) != AEROSPIKE_OK) { LOG("second aerospike_lstack_push() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } LOG("2 values pushed"); uint32_t n_elements = 0; // Look at the stack size right now. if (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) != AEROSPIKE_OK) { LOG("aerospike_lstack_size() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } if (n_elements != 2) { LOG("unexpected stack size %u", n_elements); example_cleanup(&as); exit(-1); } LOG("stack size confirmed to be %u", n_elements); as_ldt lstack2; as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL); uint32_t peek_count = 3; as_list* p_list = NULL; // Peek a few values back. if (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, peek_count, &p_list) != AEROSPIKE_OK) { LOG("first aerospike_lstack_peek() returned %d - %s", err.code, err.message); as_list_destroy(p_list); example_cleanup(&as); exit(-1); } as_arraylist_iterator it; as_arraylist_iterator_init(&it, (const as_arraylist*)p_list); // See if the elements match what we expect. while (as_arraylist_iterator_has_next(&it)) { const as_val* p_val = as_arraylist_iterator_next(&it); char* p_str = as_val_tostring(p_val); LOG(" peek - type = %d, value = %s", as_val_type(p_val), p_str); free(p_str); } as_list_destroy(p_list); p_list = NULL; // Push 3 more items onto the stack. By using as_arraylist_inita() we avoid // some but not all internal heap usage, so we must call // as_arraylist_destroy(). as_arraylist vals; as_arraylist_inita(&vals, 3); as_arraylist_append_int64(&vals, 1000); as_arraylist_append_int64(&vals, 2000); as_arraylist_append_int64(&vals, 3000); if (aerospike_lstack_push_all(&as, &err, NULL, &g_key, &lstack, (const as_list*)&vals) != AEROSPIKE_OK) { LOG("aerospike_lstack_pushall() returned %d - %s", err.code, err.message); as_arraylist_destroy(&vals); example_cleanup(&as); exit(-1); } as_arraylist_destroy(&vals); LOG("3 more values pushed"); as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL); peek_count = 10; // Peek all the values back again. if (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, peek_count, &p_list) != AEROSPIKE_OK) { LOG("second aerospike_lstack_peek() returned %d - %s", err.code, err.message); as_list_destroy(p_list); example_cleanup(&as); exit(-1); } // See if the elements match what we expect. as_arraylist_iterator_init(&it, (const as_arraylist*)p_list); while (as_arraylist_iterator_has_next(&it)) { const as_val* p_val = as_arraylist_iterator_next(&it); char* p_str = as_val_tostring(p_val); LOG(" peek - type = %d, value = %s", as_val_type(p_val), p_str); free(p_str); } as_list_destroy(p_list); // Set capacity for the lstack. if (aerospike_lstack_set_capacity(&as, &err, NULL, &g_key, &lstack, 10000) != AEROSPIKE_OK) { LOG("aerospike_lstack_set_capacity() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } uint32_t cap_size = 0; // Get capacity from the lstack. if (aerospike_lstack_get_capacity(&as, &err, NULL, &g_key, &lstack, &cap_size) != AEROSPIKE_OK) { LOG("aerospike_lstack_get_capacity() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } if (cap_size != 10000) { LOG("unexpected capacity size %u", cap_size); example_cleanup(&as); exit(-1); } // Destroy the lstack. if (aerospike_lstack_destroy(&as, &err, NULL, &g_key, &lstack) != AEROSPIKE_OK) { LOG("aerospike_lstack_destroy() returned %d - %s", err.code, err.message); example_cleanup(&as); exit(-1); } n_elements = 0; // See if we can still do any lstack operations. if (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) == AEROSPIKE_OK) { LOG("aerospike_lstack_size() did not return error"); example_cleanup(&as); exit(-1); } // Cleanup and disconnect from the database cluster. example_cleanup(&as); LOG("lstack example successfully completed"); return 0; }
int main(int argc, char* argv[]) { aerospike as; as_error err; as_boolean ldt_exists; as_ldt lstack, lstack2; as_integer ival; as_string sval; as_bytes bval; uint32_t n_elements, cap_size; as_arraylist_iterator it; as_list* p_list = NULL; // Parse command line arguments. if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) { exit(-1); } // Connect to the aerospike database cluster. example_connect_to_aerospike(&as); // Start clean. example_remove_test_record(&as); // Create a large stack object to use. No need to destroy lstack if using // as_ldt_init() on stack object. as_ldt_init(&lstack, "mystack", AS_LDT_LSTACK, NULL); // Verify that the LDT is not already there. as_boolean_init(&ldt_exists, false); assert (aerospike_lstack_ldt_exists(&as, &err, NULL, &g_key, &lstack, &ldt_exists) == AEROSPIKE_OK); assert (as_boolean_get(&ldt_exists) == false); LOG("verified that lstack ldt is not present"); // Push a few values onto the stack. // No need to destroy sval if using as_string_init() on stack object. // Push an integer as_integer_init(&ival, 123); assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&ival) == AEROSPIKE_OK); // Push a string as_string_init(&sval, "string stack value", false); assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&sval) == AEROSPIKE_OK); // Push bytes uint8_t buf[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; as_bytes_init_wrap(&bval, buf, 16, false); assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&bval) == AEROSPIKE_OK); // Look at the stack size right now. assert (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) == AEROSPIKE_OK); LOG("%d values pushed", n_elements); // Peek a few values back. as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL); assert (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, 3, &p_list) == AEROSPIKE_OK); // See if the elements match what we expect. as_arraylist_iterator_init(&it, (const as_arraylist*)p_list); while (as_arraylist_iterator_has_next(&it)) { const as_val* p_val = as_arraylist_iterator_next(&it); char* p_str = as_val_tostring(p_val); LOG(" peek - type = %d, value = %s", as_val_type(p_val), p_str); free(p_str); } as_list_destroy(p_list); p_list = NULL; // Push 3 more items onto the stack. By using as_arraylist_inita() we avoid // some but not all internal heap usage, so we must call // as_arraylist_destroy(). as_arraylist vals; as_arraylist_inita(&vals, 3); as_arraylist_append_int64(&vals, 1000); as_arraylist_append_int64(&vals, 2000); as_arraylist_append_int64(&vals, 3000); assert (aerospike_lstack_push_all(&as, &err, NULL, &g_key, &lstack, (const as_list*)&vals) == AEROSPIKE_OK); as_arraylist_destroy(&vals); LOG("3 more values pushed"); // Peek all the values back again. as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL); assert (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, 10, &p_list) == AEROSPIKE_OK); // See if the elements match what we expect. #if 0 as_arraylist_iterator_init(&it, (const as_arraylist*)p_list); while (as_arraylist_iterator_has_next(&it)) { const as_val* p_val = as_arraylist_iterator_next(&it); char* p_str = as_val_tostring(p_val); LOG(" peek - type = %d, value = %s", as_val_type(p_val), p_str); free(p_str); } #else const as_arraylist* p_array = (const as_arraylist*)p_list; int i; for (i = 0; i < p_array->size; i++) { const as_val* p_val = p_array->elements[i]; char* p_str = as_val_tostring(p_val); LOG(" peek - type = %d, value = %s", as_val_type(p_val), p_str); free(p_str); } #endif as_list_destroy(p_list); p_list = NULL; // Set capacity for the lstack. assert (aerospike_lstack_set_capacity(&as, &err, NULL, &g_key, &lstack, 10000) == AEROSPIKE_OK); // Get capacity from the lstack. assert (aerospike_lstack_get_capacity(&as, &err, NULL, &g_key, &lstack, &cap_size) == AEROSPIKE_OK); assert (cap_size == 10000); // Verify that the LDT is now present. as_boolean_init(&ldt_exists, false); assert (aerospike_lstack_ldt_exists(&as, &err, NULL, &g_key, &lstack, &ldt_exists) == AEROSPIKE_OK); assert (as_boolean_get(&ldt_exists) == true); LOG("verified that lstack ldt is present"); // Destroy the lstack. assert (aerospike_lstack_destroy(&as, &err, NULL, &g_key, &lstack) == AEROSPIKE_OK); // See if we can still do any lstack operations. assert (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) != AEROSPIKE_OK); // Cleanup and disconnect from the database cluster. example_cleanup(&as); LOG("lstack example successfully completed"); return 0; }
/** * Call with AS_OPERATIONS_CDT_OP only. */ static bool as_operations_cdt_op(as_operations *ops, const as_bin_name name, as_cdt_optype op, size_t n, ...) { if (op >= cdt_op_table_size) { return false; } const cdt_op_table_entry *entry = &cdt_op_table[op]; if (n < entry->count - entry->opt_args || n > entry->count) { return false; } va_list vl; if (n > 0) { va_start(vl, n); } as_arraylist list; as_arraylist_inita(&list, (uint32_t)n + 1); // +1 to avoid alloca(0) undefined behavior for (size_t i = 0; i < n; i++) { as_cdt_paramtype type = entry->args[i]; switch (type) { case AS_CDT_PARAM_PAYLOAD: { as_val *arg = va_arg(vl, as_val *); if (as_arraylist_append(&list, arg) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } case AS_CDT_PARAM_COUNT: { uint64_t arg = va_arg(vl, uint64_t); if (as_arraylist_append(&list, (as_val *)as_integer_new(arg)) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } case AS_CDT_PARAM_INDEX: { int64_t arg = va_arg(vl, int64_t); if (as_arraylist_append(&list, (as_val *)as_integer_new(arg)) != AS_ARRAYLIST_OK) { va_end(vl); as_arraylist_destroy(&list); return false; } break; } default: break; } } if (n > 0) { va_end(vl); } as_serializer ser; as_msgpack_init(&ser); uint32_t list_size = as_serializer_serialize_getsize(&ser, (as_val *) &list); as_bytes *bytes = as_bytes_new(sizeof(uint16_t) + list_size); uint8_t *list_write = as_bytes_get(bytes); uint16_t *list_write_op = (uint16_t *)list_write; *list_write_op = cf_swap_to_be16(op); list_write += sizeof(uint16_t); as_serializer_serialize_presized(&ser, (const as_val *) &list, list_write); as_serializer_destroy(&ser); as_arraylist_destroy(&list); bytes->size = bytes->capacity; // as_bytes->type default to AS_BYTES_BLOB if (entry->rw_type == CDT_RW_TYPE_MODIFY) { return as_operations_add_cdt_modify(ops, name, (as_bin_value *) bytes); } return as_operations_add_cdt_read(ops, name, (as_bin_value *) bytes); }
PyObject * AerospikeQuery_Foreach(AerospikeQuery * self, PyObject * args, PyObject * kwds) { // Python Function Arguments PyObject * py_callback = NULL; PyObject * py_policy = NULL; // Python Function Keyword Arguments static char * kwlist[] = {"callback", "policy", NULL}; // Python Function Argument Parsing if ( PyArg_ParseTupleAndKeywords(args, kwds, "O|O:foreach", kwlist, &py_callback, &py_policy) == false ) { as_query_destroy(&self->query); return NULL; } // Initialize callback user data LocalData data; data.callback = py_callback; as_error_init(&data.error); // Aerospike Client Arguments as_error err; as_policy_query query_policy; as_policy_query * query_policy_p = NULL; // Initialize error as_error_init(&err); if (!self || !self->client->as) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if (!self->client->is_conn_16) { as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster"); goto CLEANUP; } // Convert python policy object to as_policy_exists pyobject_to_policy_query(&err, py_policy, &query_policy, &query_policy_p, &self->client->as->config.policies.query); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // We are spawning multiple threads PyThreadState * _save = PyEval_SaveThread(); // Invoke operation aerospike_query_foreach(self->client->as, &err, query_policy_p, &self->query, each_result, &data); // We are done using multiple threads PyEval_RestoreThread(_save); if (data.error.code != AEROSPIKE_OK) { goto CLEANUP; } CLEANUP: if ( self->query.apply.arglist ){ as_arraylist_destroy( (as_arraylist *) self->query.apply.arglist ); } self->query.apply.arglist = NULL; if ( err.code != AEROSPIKE_OK || data.error.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; if ( err.code != AEROSPIKE_OK ){ error_to_pyobject(&err, &py_err); } if ( data.error.code != AEROSPIKE_OK ){ error_to_pyobject(&data.error, &py_err); } PyErr_SetObject(PyExc_Exception, py_err); Py_DECREF(py_err); return NULL; } Py_INCREF(Py_None); return Py_None; }