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;
}
示例#2
0
/*
 * 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;
}