static as_rec * ldt_aerospike_crec_open(const as_aerospike * as, const as_rec *rec, const char *bdig) { static char * meth = "ldt_aerospike_crec_open()"; if (!as || !rec || !bdig) { cf_warning(AS_LDT, "ldt_aerospike_crec_open: Invalid Parameters [as=%p, record=%p digest=%p]... Fail", meth, as, rec, bdig); return NULL; } cf_digest keyd; if (as_ldt_string_todigest(bdig, &keyd)) { return NULL; } ldt_record *lrecord = (ldt_record *)as_rec_source(rec); if (!lrecord) { return NULL; } if (!udf_record_ldt_enabled(lrecord->h_urec)) { cf_warning(AS_LDT, "Large Object Not Enabled... Fail"); return NULL; } as_ldt_subdigest_setversion(&keyd, lrecord->version); ldt_slot *lslotp = NULL; int rv = crec_open(lrecord, &keyd, &lslotp); if (rv) { // This basically means the record is not found. // Do we need to propagate error message rv // back somehow cf_info_digest(AS_LDT, &keyd, "%s Failed to open Sub Record rv=%d %ld", bdig, rv, lrecord->version); return NULL; } else { as_val_reserve(lslotp->c_urec_p); return lslotp->c_urec_p; } }
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 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_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()
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()
as_rec * crec_create(ldt_record *lrecord) { // Generate Key Digest udf_record *h_urecord = (udf_record *) as_rec_source(lrecord->h_urec); cf_digest keyd = h_urecord->r_ref->r->key; as_namespace *ns = h_urecord->tr->rsv.ns; int retry_cnt = 0; ldt_slot *lslotp = slot_lookup_free(lrecord, "crec_create"); if (!lslotp) { cf_crash(AS_LDT, "Allocation error !!!"); } slot_init(lslotp, lrecord); while (retry_cnt++ < LDT_SUBRECORD_RANDOMIZER_MAX_RETRIES) { as_ldt_digest_randomizer(&keyd); as_ldt_subdigest_setversion(&keyd, lrecord->version); slot_setup_digest(lslotp, &keyd); int rv = as_aerospike_rec_create(lrecord->as, lslotp->c_urec_p); // rv == 0 if successful // rv == 1 if record is already found retry // other wise failure if (rv == 0) { cf_detail_digest(AS_LDT, &keyd, "Crec Create:Ptr(%p) Digest: version %ld", lslotp->c_urec_p, lrecord->version); as_val_reserve(lslotp->c_urec_p); return lslotp->c_urec_p; } if (rv != 1) { cf_warning(AS_LDT, "crec_create: LDT Sub-Record Create Error [rv=%d]... Fail", rv); break; } cf_atomic64_incr(&ns->lstats.ldt_randomizer_retry); } slot_destroy(lslotp, lrecord); cf_warning_digest(AS_LDT, &keyd, "ldt_aerospike_crec_create : Create failed after %d retries", retry_cnt); return NULL; }
/* * Internal Function: To create new chunk record * * Parameters: * lr : Parent ldt record * * Return value : * crec (as_val) in case of success * NULL in case of failure * * Description: * 1. Search for empty chunk slot. * 2. Read the record into it * * Callers: * ldt_aerospike_crec_create */ as_rec * ldt_crec_create(ldt_record *lrecord) { // Generate Key Digest udf_record *h_urecord = (udf_record *) as_rec_source(lrecord->h_urec); cf_digest keyd = h_urecord->r_ref->r->key; cf_detail(AS_LDT, "ldt_aerospike_crec_create %"PRIx64"", *(uint64_t *)&keyd); as_ldt_digest_randomizer(h_urecord->tr->rsv.ns, &keyd); as_ldt_subdigest_setversion(&keyd, lrecord->version); // Setup Chunk int slot = ldt_crec_find_freeslot(lrecord); if (slot == -1) { cf_warning(AS_LDT, "ldt_crec_create: Cannot open more than (%d) records in a single UDF", s_max_open_subrecs); return NULL; } cf_detail(AS_LDT, "ldt_crec_create: Popped slot %d", slot); lrecord->chunk[slot].slot = slot; ldt_chunk *lchunk = &lrecord->chunk[slot]; ldt_chunk_init (lchunk, lrecord); ldt_chunk_setup(lchunk, lrecord->h_urec, &keyd); // Create Record int rv = as_aerospike_rec_create(lrecord->as, lchunk->c_urec_p); if (rv < 0) { // Mark Slot as free ldt_chunk_destroy(&lrecord->chunk[slot]); cf_warning(AS_LDT, "ldt_crec_create: Record Create Failed rv=%d ... ", rv); return NULL; } cf_debug_digest(AS_LDT, &(lchunk->c_urecord.keyd), "Crec Create:Ptr(%p) Digest: ", lchunk->c_urec_p); as_val_reserve(lchunk->c_urec_p); return lchunk->c_urec_p; }
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()
static as_record add_bins_to_rec(lua_State *L, int index, int numBins) { as_record rec; as_record_init(&rec, numBins); // Push another reference to the table on top of the stack (so we know // where it is, and this function can work for negative, positive and // pseudo indices lua_pushvalue(L, index); // stack now contains: -1 => table lua_pushnil(L); // stack now contains: -1 => nil; -2 => table while (lua_next(L, -2)) { // stack now contains: -1 => value; -2 => key; -3 => table // copy the key so that lua_tostring does not modify the original lua_pushvalue(L, -2); // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table const char *binName = lua_tostring(L, -1); // add to record if (lua_isnumber(L, -2)){ int intValue = lua_tointeger(L, -2); as_record_set_int64(&rec, binName, intValue); } else if (lua_isstring(L, -2)){ const char *value = lua_tostring(L, -2); as_record_set_str(&rec, binName, value); } else if (lua_istable(L, -2)){ // make a as_list and populate it as_arraylist *list = as_arraylist_new(3, 3); lua_pushvalue(L, -2); lua_pushnil(L); // This is needed for it to even get the first value while (lua_next(L, -2)) { lua_pushvalue(L, -2); //const char *key = lua_tostring(L, -1); const char *value = lua_tostring(L, -2); // populate the as_list as_arraylist_append_str(list, value); //printf("%s => %s\n", key, value); lua_pop(L, 2); } lua_pop(L, 1); // put the list in a bin as_record_set_list(&rec, binName, (as_list*)as_val_reserve(list)); } // pop value + copy of key, leaving original key lua_pop(L, 2); // stack now contains: -1 => key; -2 => table } // stack now contains: -1 => table (when lua_next returns 0 it pops the key // but does not push anything.) // Pop table lua_pop(L, 1); // Stack is now the same as it was on entry to this function return rec; }