Example #1
0
/**
 * Set the Record Type bits for a record. Typically, this is how we show that
 * a record is of type LDT (which requires special handling). This function
 * allows us to either SET the record type (the "bits" parm is positive), or
 * UNSET the record type (the "bits" parm is negative).  When we want to
 * turn an "LDT Record" back into a "Normal Record", then we UNSET the LDT
 * flag (with a negative bits value).
 */
static int
udf_record_set_type(const as_rec * rec,  int8_t ldt_rectype_bit_update)
{
	if (!rec || !ldt_rectype_bit_update) {
		cf_warning(AS_UDF, "Invalid Paramters: record=%p rec_type_bits=%d", rec, ldt_rectype_bit_update);
		return 2;
	}
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return ret;
	}

	if (!udf_record_ldt_enabled(rec)
			&& (as_ldt_flag_has_parent(ldt_rectype_bit_update)
				|| as_ldt_flag_has_sub(ldt_rectype_bit_update))) {
		cf_warning(AS_LDT, "Cannot Set Large Object Bits .. Not Enabled !!");
		return -2;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (!(urecord->flag & UDF_RECORD_FLAG_ALLOW_UPDATES)) {
		return -1;
	}

	urecord->ldt_rectype_bit_update = ldt_rectype_bit_update;
	cf_detail(AS_RW, "TO URECORD FROM LUA   Digest=%"PRIx64" bits %d",
			  *(uint64_t *)&urecord->rd->keyd.digest[8], urecord->ldt_rectype_bit_update);

	urecord->flag |= UDF_RECORD_FLAG_METADATA_UPDATED;

	return 0;
}
Example #2
0
static uint32_t
udf_record_ttl(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return 0;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);


	if (urecord->flag & UDF_RECORD_FLAG_IS_SUBRECORD) {
		cf_debug(AS_UDF, "Return 0 TTL for subrecord ");
		return 0;
	}

	if ((urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN)) {
		uint32_t now = as_record_void_time_get();

		return urecord->r_ref->r->void_time > now ?
				urecord->r_ref->r->void_time - now : 0;
	}
	else {
		cf_info(AS_UDF, "Error in getting ttl: no record found");
		return 0; // since we can't indicate the record doesn't exist
	}
	return 0;
}
Example #3
0
static uint16_t
udf_record_numbins(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return 0;
	}

	udf_record *urecord = (udf_record *) as_rec_source(rec);
	if (urecord && (urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN)) {

		if (urecord->rd->ns->single_bin) {
			return 1;
		}

		uint16_t i;
		as_storage_rd *rd = urecord->rd;
		for (i = 0; i < rd->n_bins; i++) {
			as_bin *b = &rd->bins[i];
			if (! as_bin_inuse(b)) {
				break;
			}
		}
		return i;
	}
	else {
		cf_warning(AS_UDF, "Error in getting numbins: no record found");
		return 0;
	}
}
Example #4
0
/**
 * Set the flags for a specific bin.  This is how LDTs mark Hidden Bins. Other
 * uses may also apply.
 */
static int
udf_record_set_flags(const as_rec * rec, const char * name, uint8_t flags)
{
	int ret = udf_record_param_check(rec, name, __FILE__, __LINE__);
	if (ret) {
		return ret;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (!(urecord->flag & UDF_RECORD_FLAG_ALLOW_UPDATES)) {
		return -1;
	}

	if ( urecord && name ) {
		if (flags & LDT_FLAG_HIDDEN_BIN || flags & LDT_FLAG_LDT_BIN || flags & LDT_FLAG_CONTROL_BIN ) {
			cf_debug(AS_UDF, "LDT flag(%d) Designates Hidden Bin", flags);
			udf_record_cache_sethidden(urecord, name);
		} else {
			cf_warning(AS_UDF, "Unidentified flag setting up %d", flags);
			return -2;
		}
	}

	urecord->flag |= UDF_RECORD_FLAG_METADATA_UPDATED;

	return 0;
}
/*
 * Check and validate parameter before performing operation
 *
 * return:
 *      UDF_ERR * in case of failure
 *      0 in case of success
 */
static int
udf_aerospike_param_check(const as_aerospike *as, const as_rec *rec, char *fname, int lineno)
{
	if (!as) {
		cf_debug(AS_UDF, "Invalid Paramters: aerospike=%p", as);
		return UDF_ERR_INTERNAL_PARAMETER;
	}

	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, fname, lineno);
	if (ret) {
		return ret;
	}
	return 0;
}
Example #6
0
/*********************************************************************
 * INTERFACE FUNCTIONS                                               *
 *																	 *
 * See the as_aerospike for the API definition						 *
 ********************************************************************/
static as_val *
udf_record_get(const as_rec * rec, const char * name)
{
	if (udf_record_param_check(rec, name, __FILE__, __LINE__)) {
		return NULL;
	}
	udf_record  *   urecord = (udf_record *) as_rec_source(rec);
	as_val *        value   = NULL;

	cf_debug(AS_UDF, "[ENTER] rec(%p) name(%s)", rec, name );

	// Get from cache
	value = udf_record_cache_get(urecord, name);

	// If value not NULL, then return it.
	if ( value != NULL ) {
		return value;
	}

	// Check in the cache before trying to look up in record
	// Note: Record may not have been created yet ... Do not
	// change the order unless you fully understand what you
	// are doing
	if ( !(urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN) ) {
		if (udf_record_open(urecord)) { // lazy read the record from storage
			return NULL;
		}
	}

	// Check if storage is available
	if ( !urecord->rd->ns ) {
		cf_detail(AS_UDF, "udf_record_get: storage unavailable");
		return NULL;
	}

	value = udf_record_storage_get(urecord, name);

	// We have a value, so we will cache it.
	// DO NOT remove this. We need to cache copy to makes sure ref count 
	// gets decremented post handing this as_val over to the lua world
	if ( urecord && value ) {
		udf_record_cache_set(urecord, name, value, false);
	}

	cf_detail(AS_UDF, "udf_record_get: end (%s) [%p,%p]", name, urecord, value);
	return value;
}
Example #7
0
static uint16_t
udf_record_gen(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return 0;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (urecord && urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN) {
		return urecord->r_ref->r->generation;
	}
	else {
		cf_warning(AS_UDF, "Error in getting generation: no record found");
		return 0;
	}
}
Example #8
0
static int
udf_record_set(const as_rec * rec, const char * name, const as_val * value)
{
	int ret = udf_record_param_check(rec, name, __FILE__, __LINE__);
	if (ret) {
		return ret;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	cf_detail(AS_UDF, "udf_record_set: begin (%s)", name);
	if ( urecord && name ) {
		udf_record_cache_set(urecord, name, (as_val *) value, true);
	}
	cf_detail(AS_UDF, "udf_record_set: end (%s)", name);

	return 0;
}
Example #9
0
static const char *
udf_record_setname(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return NULL;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (urecord && (urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN)) {
		return as_index_get_set_name(urecord->r_ref->r, urecord->rd->ns);
	}
	else {
		cf_warning(AS_UDF, "Error in getting set name: no record found");
		return NULL;
	}
}
Example #10
0
static int
udf_record_set_ttl(const as_rec * rec,  uint32_t  ttl)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return ret;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (!(urecord->flag & UDF_RECORD_FLAG_ALLOW_UPDATES)) {
		return -1;
	}

	urecord->tr->msgp->msg.record_ttl = ttl;
	urecord->flag |= UDF_RECORD_FLAG_METADATA_UPDATED;

	return 0;
}
Example #11
0
static int
udf_record_bin_names(const as_rec *rec, as_rec_bin_names_callback callback, void * udata)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return 1;
	}

	udf_record *urecord = (udf_record *)as_rec_source(rec);
	char * bin_names = NULL;
	if (urecord && (urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN)) {
		uint16_t nbins;

		if (urecord->rd->ns->single_bin) {
			nbins = 1;
			bin_names = alloca(1);
			*bin_names = 0;
		}
		else {
			nbins = urecord->rd->n_bins;
			bin_names = alloca(nbins * AS_ID_BIN_SZ);
			for (uint16_t i = 0; i < nbins; i++) {
				as_bin *b = &urecord->rd->bins[i];
				if (! as_bin_inuse(b)) {
					nbins = i;
					break;
				}
				const char * name = as_bin_get_name_from_id(urecord->rd->ns, b->id);
				strcpy(bin_names + (i * AS_ID_BIN_SZ), name);
			}
		}
		callback(bin_names, nbins, AS_ID_BIN_SZ, udata);
		return 0;
	}
	else {
		cf_warning(AS_UDF, "Error in getting bin names: no record found");
		bin_names = alloca(1);
		*bin_names = 0;
		callback(bin_names, 1, AS_ID_BIN_SZ, udata);
		return -1;
	}
}
Example #12
0
static as_bytes *
udf_record_digest(const as_rec *rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return NULL;
	}

	udf_record *urecord = (udf_record *)as_rec_source(rec);
	if (urecord && urecord->flag & UDF_RECORD_FLAG_OPEN) {
		cf_digest *keyd = cf_malloc(sizeof(cf_digest));
		if (!keyd) {
			return NULL;
		}
		memcpy(keyd, &urecord->keyd, CF_DIGEST_KEY_SZ);
		as_bytes *b = as_bytes_new_wrap(keyd->digest, CF_DIGEST_KEY_SZ, true);
		return b;
	}
	return NULL;
}
Example #13
0
static as_val *
udf_record_key(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return NULL;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (urecord && (urecord->flag & UDF_RECORD_FLAG_STORAGE_OPEN)) {
		if (urecord->rd->key) {
			return as_val_from_flat_key(urecord->rd->key, urecord->rd->key_size);
		}
		// TODO - perhaps look for the key in the message.
		return NULL;
	}
	else {
		cf_warning(AS_UDF, "Error in getting key: no record found");
		return NULL;
	}
}
Example #14
0
static int
udf_record_drop_key(const as_rec * rec)
{
	int ret = udf_record_param_check(rec, UDF_BIN_NONAME, __FILE__, __LINE__);
	if (ret) {
		return ret;
	}

	udf_record * urecord = (udf_record *) as_rec_source(rec);
	if (!(urecord->flag & UDF_RECORD_FLAG_ALLOW_UPDATES)) {
		return -1;
	}

	// Flag the key to be dropped.
	if (urecord->rd->key) {
		urecord->rd->key = NULL;
		urecord->rd->key_size = 0;
	}

	urecord->flag |= UDF_RECORD_FLAG_METADATA_UPDATED;

	return 0;
}