Example #1
0
void
as_bin_allocate_bin_space(as_record *r, as_storage_rd *rd, int32_t delta) {
	if (rd->n_bins == 0) {
		rd->n_bins = (uint16_t)delta;

		as_bin_space* bin_space = (as_bin_space*)
				cf_malloc(sizeof(as_bin_space) + (rd->n_bins * sizeof(as_bin)));

		rd->bins = bin_space->bins;
		as_bin_set_all_empty(rd);

		bin_space->n_bins = rd->n_bins;
		as_index_set_bin_space(r, bin_space);
	}
	else {
		uint16_t new_n_bins = (uint16_t)((int32_t)rd->n_bins + delta);

		if (delta < 0) {
			as_record_clean_bins_from(rd, new_n_bins);
		}

		uint16_t old_n_bins = rd->n_bins;

		rd->n_bins = new_n_bins;

		if (new_n_bins != 0) {
			as_bin_space* bin_space = (as_bin_space*)
					cf_realloc((void*)as_index_get_bin_space(r), sizeof(as_bin_space) + (rd->n_bins * sizeof(as_bin)));

			rd->bins = bin_space->bins;

			if (delta > 0) {
				as_bin_set_empty_from(rd, old_n_bins);
			}

			bin_space->n_bins = rd->n_bins;
			as_index_set_bin_space(r, bin_space);
		}
		else {
			cf_free((void*)as_index_get_bin_space(r));
			as_index_set_bin_space(r, NULL);
			rd->bins = NULL;
		}
	}
}
Example #2
0
// Called only if data-in-memory, and not single-bin.
void
as_record_free_bin_space(as_record *r)
{
	as_bin_space *bin_space = as_index_get_bin_space(r);

	if (bin_space) {
		cf_free((void*)bin_space);
		as_index_set_bin_space(r, NULL);
	}
}
Example #3
0
// TODO - old pickle - remove in "six months".
int
old_record_apply_dim(as_remote_record *rr, as_storage_rd *rd, bool skip_sindex,
		bool *is_delete)
{
	as_namespace* ns = rr->rsv->ns;
	as_record* r = rd->r;

	// Set rd->n_bins!
	as_storage_rd_load_n_bins(rd);

	// Set rd->bins!
	as_storage_rd_load_bins(rd, NULL);

	// For memory accounting, note current usage.
	uint64_t memory_bytes = as_storage_record_get_n_bytes_memory(rd);

	// Keep old bins intact for sindex adjustment and unwinding.
	uint16_t n_old_bins = rd->n_bins;
	as_bin* old_bins = rd->bins;

	uint16_t n_new_bins = cf_swap_from_be16(*(uint16_t *)rr->pickle);
	as_bin new_bins[n_new_bins];

	memset(new_bins, 0, sizeof(new_bins));
	rd->n_bins = n_new_bins;
	rd->bins = new_bins;

	// Fill the new bins and particles.
	int result = unpickle_bins(rr, rd, NULL);

	if (result != 0) {
		cf_warning_digest(AS_RECORD, rr->keyd, "{%s} record replace: failed unpickle bins ", ns->name);
		destroy_stack_bins(new_bins, n_new_bins);
		return result;
	}

	// Apply changes to metadata in as_index needed for and writing.
	index_metadata old_metadata;

	update_index_metadata(rr, &old_metadata, r);

	// Prepare to store or drop key, as determined by message.
	rd->key = rr->key;
	rd->key_size = rr->key_size;

	// Write the record to storage.
	if ((result = as_record_write_from_pickle(rd)) < 0) {
		cf_warning_digest(AS_RECORD, rr->keyd, "{%s} record replace: failed write ", ns->name);
		unwind_index_metadata(&old_metadata, r);
		destroy_stack_bins(new_bins, n_new_bins);
		return -result;
	}

	// Success - adjust sindex, looking at old and new bins.
	if (! (skip_sindex &&
			next_generation(r->generation, (uint16_t)rr->generation, ns)) &&
					record_has_sindex(r, ns)) {
		write_sindex_update(ns, as_index_get_set_name(r, ns), rr->keyd,
				old_bins, n_old_bins, new_bins, n_new_bins);
	}

	// Cleanup - destroy relevant bins, can't unwind after.
	destroy_stack_bins(old_bins, n_old_bins);

	// Fill out new_bin_space.
	as_bin_space* new_bin_space = NULL;

	if (n_new_bins != 0) {
		new_bin_space = (as_bin_space*)
				cf_malloc_ns(sizeof(as_bin_space) + sizeof(new_bins));

		new_bin_space->n_bins = rd->n_bins;
		memcpy((void*)new_bin_space->bins, new_bins, sizeof(new_bins));
	}

	// Swizzle the index element's as_bin_space pointer.
	as_bin_space* old_bin_space = as_index_get_bin_space(r);

	if (old_bin_space) {
		cf_free(old_bin_space);
	}

	as_index_set_bin_space(r, new_bin_space);

	// Now ok to store or drop key, as determined by message.
	as_record_finalize_key(r, ns, rd->key, rd->key_size);

	as_storage_record_adjust_mem_stats(rd, memory_bytes);
	*is_delete = n_new_bins == 0;

	return AS_OK;
}