void as_record_release(as_record * rec) { if ( rec ) { if ( rec->bins.entries ) { for ( int i = 0; i < rec->bins.size; i++ ) { as_val_destroy((as_val *) rec->bins.entries[i].valuep); rec->bins.entries[i].valuep = NULL; } if ( rec->bins._free ) { free(rec->bins.entries); } } rec->bins.entries = NULL; rec->bins.capacity = 0; rec->bins.size = 0; rec->key.ns[0] = '\0'; rec->key.set[0] = '\0'; as_val_destroy((as_val *) rec->key.valuep); rec->key.valuep = NULL; rec->key.digest.init = false; } }
void udf_record_cache_free(udf_record * urecord) { cf_debug(AS_UDF, "[ENTER] NumUpdates(%d) ", urecord->nupdates ); for (uint32_t i = 0; i < urecord->nupdates; i ++ ) { udf_record_bin * bin = &urecord->updates[i]; if ( bin->name[0] != '\0' && bin->value != NULL ) { bin->name[0] = '\0'; as_val_destroy(bin->value); bin->value = NULL; } if ( bin->name[0] != '\0' && bin->oldvalue != NULL ) { bin->name[0] = '\0'; as_val_destroy(bin->oldvalue); bin->oldvalue = NULL; } } for (uint32_t i = 0; i < UDF_RECORD_BIN_ULIMIT; i++) { if (urecord->updates[i].particle_buf) { cf_free(urecord->updates[i].particle_buf); urecord->updates[i].particle_buf = NULL; } } urecord->nupdates = 0; urecord->flag &= ~UDF_RECORD_FLAG_TOO_MANY_BINS; }
int lset_create_test (char * keystr, char * ldt_bin ){ static char * meth = "lset_create_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; char * create_package = "StandardList"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); citrusleaf_object_init_str( &o_key, keystr ); cl_rv rv = 0; rv = aerospike_lset_create( c, ns, set, &o_key, bname, create_spec, lset_g_config->timeout_ms); citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rv; }
static bool udf_arglist_foreach(const as_list * l, as_list_foreach_callback callback, void * context) { as_msg_field * field = (as_msg_field *) l->data; if ( field != NULL ) { as_unpacker unpacker; unpacker.buffer = (const unsigned char*)field->data; unpacker.length = as_msg_field_get_value_sz(field); unpacker.offset = 0; if ( unpacker.length == 0 ) return true; as_val* val = 0; int ret = as_unpack_val(&unpacker, &val); if (ret == 0 && as_val_type(val) == AS_LIST) { as_list_iterator list_iter; as_iterator* iter = (as_iterator*) &list_iter; as_list_iterator_init(&list_iter, (as_list*)val); while (as_iterator_has_next(iter)) { const as_val* v = as_iterator_next(iter); callback((as_val *) v, context); } as_iterator_destroy(iter); } as_val_destroy(val); return ret == 0; } return true; }
static as_status as_command_parse_udf_failure(uint8_t* p, as_error* err, as_msg* msg, as_status status) { p = as_command_ignore_fields(p, msg->n_fields); as_bin_name name; for (uint32_t i = 0; i < msg->n_ops; i++) { uint32_t op_size = cf_swap_from_be32(*(uint32_t*)p); p += 5; uint8_t type = *p; p += 2; uint8_t name_size = *p++; uint8_t name_len = (name_size <= AS_BIN_NAME_MAX_LEN)? name_size : AS_BIN_NAME_MAX_LEN; memcpy(name, p, name_len); name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); if (strcmp(name, "FAILURE") == 0) { as_val* val = 0; as_command_parse_value(p, type, value_size, &val); status = as_command_parse_udf_error(err, status, val); as_val_destroy(val); return status; } p += value_size; } return as_error_set_message(err, status, as_error_string(status)); }
void as_ldt_clean_store_args(ErlNifEnv* env, ldt_store_args_t* args) { DEBUG_TRACE("begin clean args"); as_val_destroy(args->p_value); as_ldt_destroy(&args->ldt); as_key_destroy(&args->key); DEBUG_TRACE("end clean args"); }
/* ****************************************************************************************************** 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; }
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()
static int mod_lua_map_newindex(lua_State * l) { as_map * map = mod_lua_checkmap(l, 1); if ( map ) { as_val * key = mod_lua_takeval(l, 2); as_val * val = mod_lua_takeval(l, 3); if ( !key ) { as_val_destroy(key); as_val_destroy(val); } else if ( !val ) { as_map_remove(map, key); as_val_destroy(key); } else { as_map_set(map, key, val); } } return 0; }
// ======================================================================= // 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()
/** * Destory the `as_key`, releasing resources. */ void as_key_destroy(as_key * key) { if ( !key ) return; if ( !key->valuep ) return; as_val_destroy((as_val *) key->valuep); if ( key->_free ) { free(key); } }
static int mod_lua_map_remove(lua_State * l) { as_map * map = mod_lua_checkmap(l, 1); if ( map ) { as_val * key = mod_lua_takeval(l, 2); if ( key ) { as_map_remove(map, key); as_val_destroy(key); } } return 0; }
// ======================================================================= // 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()
// ======================================================================= 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; }
// ======================================================================= 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()
static int mod_lua_map_cons(lua_State * l) { as_map * map = (as_map *) as_hashmap_new(32); int n = lua_gettop(l); if ( n == 2 && lua_type(l, 2) == LUA_TTABLE) { lua_pushnil(l); while ( lua_next(l, 2) != 0 ) { // this will leak or crash if these are not as_val, or k is and v isn't as_val * k = mod_lua_takeval(l, -2); as_val * v = mod_lua_takeval(l, -1); if ( !k || !v ) { as_val_destroy(k); as_val_destroy(v); } else { as_map_set(map, k, v); } lua_pop(l, 1); } } mod_lua_pushmap(l, map); return 1; }
/** * Set the cache value for a bin, including flags. */ static void udf_record_cache_set(udf_record * urecord, const char * name, as_val * value, bool dirty) { cf_debug(AS_UDF, "[ENTER] urecord(%p) name(%p)[%s] dirty(%d)", urecord, name, name, dirty); bool modified = false; for ( uint32_t i = 0; i < urecord->nupdates; i++ ) { udf_record_bin * bin = &(urecord->updates[i]); // bin exists, then we will release old value and set new value. if ( strncmp(name, bin->name, AS_ID_BIN_SZ) == 0 ) { cf_detail(AS_UDF, "udf_record_set: %s found", name); // release previously set value as_val_destroy(bin->value); // set new value, with dirty flag if( value != NULL ) { bin->value = (as_val *) value; } bin->dirty = dirty; cf_detail(AS_UDF, "udf_record_set: %s set for %p:%p", name, urecord, bin->value); modified = true; break; } } // If not modified, then we will add the bin to the cache if ( ! modified ) { if ( urecord->nupdates < UDF_RECORD_BIN_ULIMIT ) { udf_record_bin * bin = &(urecord->updates[urecord->nupdates]); strncpy(bin->name, name, AS_ID_BIN_SZ); bin->value = (as_val *) value; bin->dirty = dirty; bin->ishidden = false; urecord->nupdates++; cf_detail(AS_UDF, "udf_record_set: %s not modified, add for %p:%p", name, urecord, bin->value); } else { cf_warning(AS_UDF, "UDF bin limit (%d) exceeded (bin %s)", UDF_RECORD_BIN_ULIMIT, name); urecord->flag |= UDF_RECORD_FLAG_TOO_MANY_BINS; } } }
// ---------------------------------------------------------------------------------- // // 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 as_command_parse_success_failure_bins(uint8_t** pp, as_error* err, as_msg* msg, as_val** value) { uint8_t* p = *pp; p = as_command_ignore_fields(p, msg->n_fields); as_bin_name name; for (uint32_t i = 0; i < msg->n_ops; i++) { uint32_t op_size = cf_swap_from_be32(*(uint32_t*)p); p += 5; uint8_t type = *p; p += 2; uint8_t name_size = *p++; uint8_t name_len = (name_size <= AS_BIN_NAME_MAX_LEN)? name_size : AS_BIN_NAME_MAX_LEN; memcpy(name, p, name_len); name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); if (strcmp(name, "SUCCESS") == 0) { if (value) { as_command_parse_value(p, type, value_size, value); } *pp = p + value_size; return AEROSPIKE_OK; } if (strcmp(name, "FAILURE") == 0) { as_val* val = 0; as_command_parse_value(p, type, value_size, &val); if (val == 0) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Received null FAILURE bin."); } else if (val->type == AS_STRING) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, ((as_string*)val)->value); } else { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Expected string for FAILURE bin. Received %d", val->type); } as_val_destroy(val); return err->code; } p += value_size; } return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find SUCCESS or FAILURE bin."); }
bool udf_put(const char * filename) { FILE * file = fopen(filename,"r"); if ( !file ) { error("cannot open script file %s : %s", filename, strerror(errno)); return -1; } uint8_t * content = (uint8_t *) malloc(SCRIPT_LEN_MAX); if ( content == NULL ) { error("malloc failed"); return -1; } int size = 0; uint8_t * buff = content; int read = (int)fread(buff, 1, 512, file); while ( read ) { size += read; buff += read; read = (int)fread(buff, 1, 512, file); } fclose(file); as_bytes udf_content; as_bytes_init_wrap(&udf_content, content, size, true); as_error err; as_error_reset(&err); as_string filename_string; const char * base = as_basename(&filename_string, filename); if ( aerospike_udf_put(as, &err, NULL, base, AS_UDF_TYPE_LUA, &udf_content) == AEROSPIKE_OK ) { aerospike_udf_put_wait(as, &err, NULL, base, 100); } else { error("error caused by aerospike_udf_put(): (%d) %s @ %s[%s:%d]", err.code, err.message, err.func, err.file, err.line); } as_string_destroy(&filename_string); as_val_destroy(&udf_content); return err.code == AEROSPIKE_OK; }
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; }
bool as_event_command_parse_success_failure(as_event_command* cmd) { as_msg* msg = (as_msg*)cmd->buf; as_msg_swap_header_from_be(msg); uint8_t* p = cmd->buf + sizeof(as_msg); as_status status = msg->result_code; switch (status) { case AEROSPIKE_OK: { as_error err; as_val* val = 0; status = as_command_parse_success_failure_bins(&p, &err, msg, &val); if (status == AEROSPIKE_OK) { as_event_response_complete(cmd); ((as_async_value_command*)cmd)->listener(0, val, cmd->udata, cmd->event_loop); as_event_command_release(cmd); as_val_destroy(val); } else { as_event_response_error(cmd, &err); } break; } case AEROSPIKE_ERR_UDF: { as_error err; as_command_parse_udf_failure(p, &err, msg, status); as_event_response_error(cmd, &err); break; } default: { as_error err; as_error_set_message(&err, status, as_error_string(status)); as_event_response_error(cmd, &err); break; } } return true; }
static int mod_lua_map_index(lua_State * l) { mod_lua_box * box = mod_lua_checkbox(l, 1, CLASS_NAME); as_map * map = (as_map *) mod_lua_box_value(box); as_val * val = NULL; if ( map ) { as_val * key = mod_lua_takeval(l, 2); if ( key ) { val = as_map_get(map, key); as_val_destroy(key); } } if ( val ) { mod_lua_pushval(l, val); } else { lua_pushnil(l); } return 1; }
/** * Execute a query and call the callback function for each result item. * * @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 query - the query to execute against the cluster * @param udata - user-data to be passed to the callback * @param callback - the callback function to call for each result item. * * @return AEROSPIKE_OK on success, otherwise an error. */ as_status aerospike_query_foreach( aerospike * as, as_error * err, const as_policy_query * policy, const as_query * query, aerospike_query_foreach_callback callback, void * udata) { // we want to reset the error so, we have a clean state as_error_reset(err); as_val * err_val = NULL; // resolve policies // as_policy_query p; // as_policy_query_resolve(&p, &as->config.policies, policy); if ( aerospike_query_init(as, err) != AEROSPIKE_OK ) { return err->code; } cl_query * clquery = as_query_toclquery(query); clquery_bridge bridge = { .udata = udata, .callback = callback }; cl_rv rc = citrusleaf_query_foreach(as->cluster, clquery, &bridge, clquery_callback, &err_val); as_status ret = as_error_fromrc(err, rc); if (CITRUSLEAF_OK != rc && err_val) { char * err_str = as_val_tostring(err_val); if(err_str) { strncat(err->message," : ",sizeof(err->message) - strlen(err->message)); strncat(err->message,err_str,sizeof(err->message) - strlen(err->message)); cf_free(err_str); } as_val_destroy(err_val); } cl_query_destroy(clquery); return ret; }
void cl_scan_destroy(cl_scan *scan) { if ( scan == NULL ) return; cl_scan_udf_destroy(&scan->udf); if (scan->ns) free(scan->ns); if (scan->setname) free(scan->setname); if ( scan->res_streamq ) { as_val *val = NULL; while (CF_QUEUE_OK == cf_queue_pop (scan->res_streamq, &val, CF_QUEUE_NOWAIT)) { as_val_destroy(val); val = NULL; } cf_queue_destroy(scan->res_streamq); scan->res_streamq = NULL; } free(scan); scan = NULL; }
static as_val *udf_arglist_get(const as_list * l, const uint32_t idx) { as_msg_field * field = (as_msg_field *) l->data; if ( field != NULL ) { as_unpacker unpacker; unpacker.buffer = (const unsigned char*)field->data; unpacker.length = as_msg_field_get_value_sz(field); unpacker.offset = 0; if ( unpacker.length == 0 ) return NULL; as_val* item = 0; as_val* val = 0; int ret = as_unpack_val(&unpacker, &val); if (ret == 0 && as_val_type(val) == AS_LIST) { item = as_list_get((as_list*)val, idx); } as_val_destroy(val); return item; } return NULL; }
/** * Find a bin for updating. * Either return an existing bin of given name, or return an empty entry. * If no more entries available or precondition failed, then returns NULL. */ static as_bin * as_record_bin_forupdate(as_record * rec, const as_bin_name name) { if ( ! (rec && name && strlen(name) < AS_BIN_NAME_MAX_SIZE) ) { return NULL; } // look for bin of same name for(int i = 0; i < rec->bins.size; i++) { if ( strcmp(rec->bins.entries[i].name, name) == 0 ) { as_val_destroy(rec->bins.entries[i].valuep); rec->bins.entries[i].valuep = NULL; return &rec->bins.entries[i]; } } // bin not found, then append if ( rec->bins.size < rec->bins.capacity ) { // Note - caller must successfully populate bin once we increment size. return &rec->bins.entries[rec->bins.size++]; } return NULL; }
/** ******************************************************************************************************* * This function invokes csdk's API's. * * @param self AerospikeClient object * @param err The as_error to be populated by the function * with the encountered error if any. * @param key The C client's as_key that identifies the record. * @param py_list The list containing op, bin and value. * @param py_meta The metadata for the operation. * @param operate_policy_p The value for operate policy. ******************************************************************************************************* */ static PyObject * AerospikeClient_Operate_Invoke( AerospikeClient * self, as_error *err, as_key * key, PyObject * py_list, PyObject * py_meta, as_policy_operate * operate_policy_p) { as_val* put_val = NULL; char* bin = NULL; char* val = NULL; long offset = 0; double double_offset = 0.0; uint32_t ttl = 0; long operation = 0; int i = 0; PyObject * py_rec = NULL; PyObject * py_ustr = NULL; PyObject * py_ustr1 = NULL; PyObject * py_bin = NULL; as_record * rec = NULL; as_static_pool static_pool; memset(&static_pool, 0, sizeof(static_pool)); as_operations ops; Py_ssize_t size = PyList_Size(py_list); as_operations_inita(&ops, size); if (!self || !self->as) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if(py_meta) { AerospikeClient_CheckForMeta(py_meta, &ops, err); } if (err->code != AEROSPIKE_OK) { goto CLEANUP; } for ( i = 0; i < size; i++) { PyObject * py_val = PyList_GetItem(py_list, i); operation = -1; offset = 0; double_offset = 0.0; if ( PyDict_Check(py_val) ) { PyObject *key_op = NULL, *value = NULL; PyObject * py_value = NULL; Py_ssize_t pos = 0; while (PyDict_Next(py_val, &pos, &key_op, &value)) { if ( ! PyString_Check(key_op) ) { as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string."); goto CLEANUP; } else { char * name = PyString_AsString(key_op); if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) { operation = PyInt_AsLong(value); } else if (!strcmp(name, "bin")) { py_bin = value; } else if(!strcmp(name, "val")) { py_value = value; } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys"); goto CLEANUP; } } } if (py_bin) { if (PyUnicode_Check(py_bin)) { py_ustr = PyUnicode_AsUTF8String(py_bin); bin = PyString_AsString(py_ustr); } else if (PyString_Check(py_bin)) { bin = PyString_AsString(py_bin); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string"); goto CLEANUP; } } else if (!py_bin && operation != AS_OPERATOR_TOUCH) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given"); goto CLEANUP; } if (py_value) { if (check_type(self, py_value, operation, err)) { goto CLEANUP; } else if (PyString_Check(py_value) && (operation == AS_OPERATOR_INCR)) { char * incr_string = PyString_AsString(py_value); int incr_value = 0, sign = 1; if (strlen(incr_string) > 15) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported string length for increment operation"); goto CLEANUP; } if (*incr_string == '-') { incr_string = incr_string + 1; sign = -1; } else if (*incr_string == '+') { incr_string = incr_string + 1; sign = 1; } while (*incr_string != '\0') { if (*incr_string >= 48 && *incr_string <= 57) { incr_value = (incr_value * 10) + (*incr_string ^ 0x30); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for +: 'int' and 'str'"); goto CLEANUP; } incr_string = incr_string + 1; } incr_value = incr_value * sign; py_value = PyInt_FromLong(incr_value); } } else if ((!py_value) && (operation != AS_OPERATOR_READ)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given"); goto CLEANUP; } switch(operation) { case AS_OPERATOR_APPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); } else { val = PyString_AsString(py_value); } as_operations_add_append_str(&ops, bin, val); break; case AS_OPERATOR_PREPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); } else { val = PyString_AsString(py_value); } as_operations_add_prepend_str(&ops, bin, val); break; case AS_OPERATOR_INCR: if (PyInt_Check(py_value)) { offset = PyInt_AsLong(py_value); as_operations_add_incr(&ops, bin, offset); } else if ( PyLong_Check(py_value) ) { offset = PyLong_AsLong(py_value); if(-1 == offset) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize"); goto CLEANUP; } as_operations_add_incr(&ops, bin, offset); } else if (PyFloat_Check(py_value)) { double_offset = PyFloat_AsDouble(py_value); as_operations_add_incr_double(&ops, bin, double_offset); } break; case AS_OPERATOR_TOUCH: if (PyInt_Check(py_value)) { ops.ttl = PyInt_AsLong(py_value); } else if ( PyLong_Check(py_value) ) { ttl = PyLong_AsLong(py_value); if((uint32_t)-1 == ttl) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize"); goto CLEANUP; } ops.ttl = ttl; } as_operations_add_touch(&ops); break; case AS_OPERATOR_READ: as_operations_add_read(&ops, bin); break; case AS_OPERATOR_WRITE: pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops, &static_pool, SERIALIZER_PYTHON); if (err->code != AEROSPIKE_OK) { goto CLEANUP; } as_operations_add_write(&ops, bin, (as_bin_value *) put_val); break; default: as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given"); } } } // Initialize record as_record_init(rec, 0); aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec); if (err->code != AEROSPIKE_OK) { as_error_update(err, err->code, NULL); goto CLEANUP; } if(rec) { record_to_pyobject(err, rec, key, &py_rec); } CLEANUP: if (py_ustr) { Py_DECREF(py_ustr); } if (py_ustr1) { Py_DECREF(py_ustr1); } if (rec) { as_record_destroy(rec); } if (key->valuep) { as_key_destroy(key); } if (put_val) { as_val_destroy(put_val); } if ( err->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(err, &py_err); PyObject *exception_type = raise_exception(err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } if (py_rec) { return py_rec; } else { return PyLong_FromLong(0); } }
/** * LSET INSERT TEST * For a single record, perform a series of SET insert. * Create a new record, then repeatedly call lset insert. * This should work for data that is a NUMBER, a STRING or a LIST. * Parms: * + keystr: String Key to find the record * + ldt_bin: Bin Name of the LDT * + iterations: Number of iterations to run this test * + seed: Seed value for the random number pattern * + data_format: Type of value (number, string, list) */ int lset_insert_test(char * keystr, char * ldt_bin, int iterations, int seed, int data_format ) { static char * meth = "lset_insert_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = CITRUSLEAF_OK; int i; as_val *valp; time_t cur_t; cur_t = time(NULL); // INFO("[ENTER]:<%s:%s>: It(%d) Key(%s) LSOBin(%s) Seed(%d)", // MOD, meth, iterations, keystr, ldt_bin, seed); // We have two choices: We can create the LSO bin here, and then // do a bunch of inserts into it -- or we can just do the combined // "create_and_insert" insert, which upon reflection, is really the // most likely mode we'll be in. We'll choose the later. // Set up the Creation Spec parameter -- mostly setting the Package // (which is the name for a canned set of settings). char * create_package = "StandardList"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); cl_cluster * c = lset_g_config->asc; cl_object o_key; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; int iseed; //INFO("[DEBUG]:<%s:%s>: Run insert() iterations(%d)", MOD, meth, iterations ); citrusleaf_object_init_str( &o_key, keystr ); for ( i = 0; i < iterations; i++ ) { iseed = i * 10; lset_generate_value( &valp, iseed, data_format ); rc = aerospike_lset_create_and_insert( c, ns, set, &o_key, bname, valp, create_spec, lset_g_config->timeout_ms); if ( rc != CITRUSLEAF_OK ) { //INFO("[ERROR]:<%s:%s>:H Error: i(%d) rc(%d)", MOD, meth,i,rc ); as_val_destroy ( valp ); goto cleanup; } // Count the write operation for stats gathering lset_g_config->write_ops_counter += 1; lset_g_config->write_vals_counter += 1; as_val_destroy( valp ); // must destroy every iteration. valp = NULL; // unnecessary insurance } // end for cleanup: citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rc; } // end lset_insert_test()
/** * LSET Insert WITH_TRANSFORM TEST * For a single record, perform a series of SET Insert of BYTE-PACKED data. * Create a new record, then repeatedly call stack insert. */ int lset_insert_with_transform_test(char * keystr, char * ldt_bin, int iterations) { static char * meth = "lset_insert_with_transform_test()"; if( LSET_DEBUG ) { INFO(" [ENTER]:<%s:%s>:From %s", MOD, LDT, meth ); } int rc = 0; int i; INFO("[ENTER]:<%s:%s>: It(%d) Key(%s) LSOBin(%s)", MOD, meth, iterations, keystr, ldt_bin ); // Abbreviate for simplicity. cl_cluster * c = lset_g_config->asc; char * ns = lset_g_config->ns; char * set = lset_g_config->set; char * bname = ldt_bin; cl_object o_key; // Set up the Creation Spec parameter -- mostly setting the Package // (which is the name for a canned set of settings). char * create_package = "ProdListValBinStore"; as_map *create_spec = as_hashmap_new(2); as_map_set(create_spec, (as_val *) as_string_new("Package", false), (as_val *) as_string_new( create_package, false)); INFO("[DEBUG]:<%s:%s>: Run insert_with_transform() iterations(%d)", MOD, meth, iterations ); citrusleaf_object_init_str( &o_key, keystr ); for ( i = 0; i < iterations; i++ ) { int val = i * 10; as_list * listp = as_arraylist_new( 5, 5 ); int64_t urlid = val + 1; as_list_add_integer( listp, urlid ); int64_t created = val + 2; as_list_add_integer( listp, created ); int64_t meth_a = val + 3; as_list_add_integer( listp, meth_a ); int64_t meth_b = val + 4; as_list_add_integer( listp, meth_b ); int64_t status = val + 5; as_list_add_integer( listp, status ); rc = aerospike_lset_create_and_insert( c, ns, set, &o_key, bname, (as_val *)listp, create_spec, lset_g_config->timeout_ms); if ( rc != CITRUSLEAF_OK ) { INFO("[ERROR]:<%s:%s>:LSO PUSH WITH TRANSFROM Error: i(%d) rc(%d)", MOD, meth, i, rc ); as_val_destroy ( listp ); goto cleanup; } // Count the write operation for stats gathering lset_g_config->write_ops_counter += 1; lset_g_config->write_vals_counter += 1; as_val_destroy( listp ); // must destroy every iteration. listp = NULL; } // end for cleanup: citrusleaf_object_free( &o_key ); as_val_destroy( create_spec ); return rc; } // end lset_insert_with_transform_test()