/*
 * Internal Function: udf_aerospike_delbin
 *
 * Parameters:
 * 		r 		- udf_record to be manipulated
 * 		bname 	- name of the bin to be deleted
 *
 * Return value:
 * 		0  on success
 * 	   -1  on failure
 *
 * Description:
 * 		The function deletes the bin with the name
 * 		passed in as parameter. The as_bin_destroy function
 * 		which is called here, only frees the data and
 * 		the bin is marked as not in use. The bin can then be reused later.
 *
 * 		Synchronization : object lock acquired by the transaction thread executing UDF.
 * 		Partition reservation takes place just before the transaction starts executing
 * 		( look for as_partition_reserve_udf in thr_tsvc.c )
 *
 * 		Callers:
 * 		udf_aerospike__apply_update_atomic
 * 		In this function, if it fails at the time of update, the record is set
 * 		to rollback all the updates till this point. The case where it fails in
 * 		rollback is not handled.
 *
 * 		Side Notes:
 * 		i.	write_to_device will be set to true on a successful bin destroy.
 * 		If all the updates from udf_aerospike__apply_update_atomic (including this) are
 * 		successful, the record will be written to disk and reopened so that the rest of
 * 		sets of updates can be applied.
 *
 * 		ii.	If delete from sindex fails, we do not handle it.
 */
static int
udf_aerospike_delbin(udf_record * urecord, const char * bname)
{
	// Check that bname is not completely invalid
	if ( !bname || !bname[0] ) {
		cf_warning(AS_UDF, "delete bin: no bin name supplied");
		return -1;
	}

	size_t          blen    = strlen(bname);
	as_storage_rd  *rd      = urecord->rd;
	as_transaction *tr      = urecord->tr;

	// Check quality of bname -- first check that it is proper length, then
	// check that we're not over quota for bins, then finally make sure that
	// the bin exists.
	if (blen > (AS_ID_BIN_SZ - 1 ) || !as_bin_name_within_quota(rd->ns, (byte *)bname, blen)) {
		// Can't read bin if name too large or over quota
		cf_warning(AS_UDF, "bin name(%s) too big. Bin not added", bname);
		return -1;
	}

	as_bin * b = as_bin_get(rd, (byte *)bname, blen);
	if ( !b ) {
		cf_warning(AS_UDF, "as_bin_get failed: bin name(%s) not found", bname);
		return -1;
	}

	SINDEX_BINS_SETUP(delbin, 1);
	int sindex_ret = AS_SINDEX_OK;

	bool has_sindex = as_sindex_ns_has_sindex(rd->ns);
	if (has_sindex) {
		sindex_ret = as_sindex_sbin_from_bin(rd->ns, as_index_get_set_name(rd->r, rd->ns), b, delbin);
	}

	int32_t i = as_bin_get_index(rd, (byte *)bname, blen);
	if (i != -1) {
		if (has_sindex) {
			tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED;
			if (AS_SINDEX_OK ==  sindex_ret) {
				as_sindex_delete_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), 1, delbin, rd);
				//TODO: Check the error code returned through sindex_ret. (like out of sync )
			}
		}
		as_bin_destroy(rd, i);
	} else {
		cf_warning(AS_UDF, "deleting non-existing bin %s ignored", bname);
	}

	if (has_sindex) {
		as_sindex_sbin_freeall(delbin, 1);
	}

	return 0;
}
Example #2
0
/*
 * Internal Function: udf_aerospike_delbin
 *
 * Parameters:
 * 		r 		- udf_record to be manipulated
 * 		bname 	- name of the bin to be deleted
 *
 * Return value:
 * 		0  on success
 * 	   -1  on failure
 *
 * Description:
 * 		The function deletes the bin with the name
 * 		passed in as parameter. The as_bin_destroy function
 * 		which is called here, only frees the data and
 * 		the bin is marked as not in use. The bin can then be reused later.
 *
 * 		Synchronization : object lock acquired by the transaction thread executing UDF.
 * 		Partition reservation takes place just before the transaction starts executing
 * 		( look for as_partition_reserve_udf in thr_tsvc.c )
 *
 * 		Callers:
 * 		udf_aerospike__apply_update_atomic
 * 		In this function, if it fails at the time of update, the record is set
 * 		to rollback all the updates till this point. The case where it fails in
 * 		rollback is not handled.
 *
 * 		Side Notes:
 * 		i.	write_to_device will be set to true on a successful bin destroy.
 * 		If all the updates from udf_aerospike__apply_update_atomic (including this) are
 * 		successful, the record will be written to disk and reopened so that the rest of
 * 		sets of updates can be applied.
 *
 * 		ii.	If delete from sindex fails, we do not handle it.
 */
static int
udf_aerospike_delbin(udf_record * urecord, const char * bname)
{
	// Check that bname is not completely invalid
	if ( !bname || !bname[0] ) {
		cf_warning(AS_UDF, "udf_aerospike_delbin: Invalid Parameters [No bin name supplied]... Fail");
		return -1;
	}

	as_storage_rd  *rd      = urecord->rd;
	as_transaction *tr      = urecord->tr;

	// Check quality of bname -- check that it is proper length, then make sure
	// that the bin exists.
	if (strlen(bname) >= AS_ID_BIN_SZ) {
		// Can't read bin if name too large.
		cf_warning(AS_UDF, "udf_aerospike_delbin: Invalid Parameters [bin name(%s) too big]... Fail", bname);
		return -1;
	}

	as_bin * b = as_bin_get(rd, bname);
	if ( !b ) {
		cf_debug(AS_UDF, "udf_aerospike_delbin: Invalid Operation [Bin name(%s) not found of delete]... Fail", bname);
		return -1;
	}

	const char * set_name = as_index_get_set_name(rd->r, rd->ns);
	
	bool has_sindex = as_sindex_ns_has_sindex(rd->ns);
	if (has_sindex) {
		SINDEX_GRLOCK();
	}
	SINDEX_BINS_SETUP(sbins, rd->ns->sindex_cnt);
	as_sindex * si_arr[rd->ns->sindex_cnt];
	int si_arr_index = 0;
	int sbins_populated  = 0;
	if (has_sindex) {
		si_arr_index += as_sindex_arr_lookup_by_set_binid_lockfree(rd->ns, set_name, b->id, &si_arr[si_arr_index]);
		sbins_populated += as_sindex_sbins_from_bin(rd->ns, set_name, b, sbins, AS_SINDEX_OP_DELETE);
		SINDEX_GUNLOCK();
	}

	int32_t i = as_bin_get_index(rd, bname);
	if (i != -1) {
		if (has_sindex) {
			if (sbins_populated > 0) {	
				tr->flags |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED;
				as_sindex_update_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), sbins, sbins_populated, &rd->keyd);
			}
		}
		as_bin_destroy(rd, i);
	} else {
		cf_warning(AS_UDF, "udf_aerospike_delbin: Internal Error [Deleting non-existing bin %s]... Fail", bname);
	}

	if (has_sindex) {
		as_sindex_sbin_freeall(sbins, sbins_populated);
		as_sindex_release_arr(si_arr, si_arr_index);
	}

	return 0;
}