Ejemplo n.º 1
0
bool
as_namespace_configure_sets(as_namespace *ns)
{
	for (uint32_t i = 0; i < ns->sets_cfg_count; i++) {
		uint32_t idx;
		cf_vmapx_err result = cf_vmapx_put_unique(ns->p_sets_vmap, &ns->sets_cfg_array[i], &idx);

		if (result == CF_VMAPX_ERR_NAME_EXISTS) {
			as_set* p_set = NULL;

			if ((result = cf_vmapx_get_by_index(ns->p_sets_vmap, idx, (void**)&p_set)) != CF_VMAPX_OK) {
				// Should be impossible - just verified idx.
				cf_warning(AS_NAMESPACE, "unexpected error %d", result);
				return false;
			}

			// Rewrite configurable metadata - config values may have changed.
			p_set->stop_writes_count = ns->sets_cfg_array[i].stop_writes_count;
			p_set->disable_eviction = ns->sets_cfg_array[i].disable_eviction;
			p_set->enable_xdr = ns->sets_cfg_array[i].enable_xdr;
		}
		else if (result != CF_VMAPX_OK) {
			// Maybe exceeded max sets allowed, but try failing gracefully.
			cf_warning(AS_NAMESPACE, "vmap error %d", result);
			return false;
		}
	}

	return true;
}
Ejemplo n.º 2
0
as_set *as_namespace_init_set(as_namespace *ns, const char *set_name)
{
	if (! set_name) {
		return NULL;
	}

	uint32_t idx;
	cf_vmapx_err result = cf_vmapx_get_index(ns->p_sets_vmap, set_name, &idx);

	if (result == CF_VMAPX_ERR_NAME_NOT_FOUND) {
		as_set set;

		memset(&set, 0, sizeof(set));

		// Check name length just once, here at insertion. (Other vmap calls are
		// safe if name is too long - they return CF_VMAPX_ERR_NAME_NOT_FOUND.)
		strncpy(set.name, set_name, AS_SET_NAME_MAX_SIZE);

		if (set.name[AS_SET_NAME_MAX_SIZE - 1]) {
			set.name[AS_SET_NAME_MAX_SIZE - 1] = 0;

			cf_info(AS_NAMESPACE, "set name %s... too long", set.name);
			return NULL;
		}

		result = cf_vmapx_put_unique(ns->p_sets_vmap, &set, &idx);

		// Since this function can be called via info, need to handle race with
		// as_namespace_get_create_set() that returns CF_VMAPX_ERR_NAME_EXISTS.
		if (result != CF_VMAPX_OK && result != CF_VMAPX_ERR_NAME_EXISTS) {
			cf_warning(AS_NAMESPACE, "unexpected error %d", result);
			return NULL;
		}
	}
	else if (result != CF_VMAPX_OK) {
		// Should be impossible.
		cf_warning(AS_NAMESPACE, "unexpected error %d", result);
		return NULL;
	}

	as_set *p_set = NULL;

	if ((result = cf_vmapx_get_by_index(ns->p_sets_vmap, idx, (void**)&p_set)) != CF_VMAPX_OK) {
		// Should be impossible - just verified idx.
		cf_warning(AS_NAMESPACE, "unexpected error %d", result);
		return NULL;
	}

	return p_set;
}
Ejemplo n.º 3
0
const char *as_namespace_get_set_name(as_namespace *ns, uint16_t set_id)
{
	// Note that set_id is 1-based, but cf_vmap index is 0-based.
	// (This is because 0 in the index structure means 'no set'.)

	if (set_id == INVALID_SET_ID) {
		return NULL;
	}

	as_set *p_set;

	return cf_vmapx_get_by_index(ns->p_sets_vmap, set_id - 1, (void**)&p_set) == CF_VMAPX_OK ?
			p_set->name : NULL;
}
Ejemplo n.º 4
0
void as_namespace_release_set_id(as_namespace *ns, uint16_t set_id)
{
	if (set_id == INVALID_SET_ID) {
		return;
	}

	as_set *p_set;

	if (cf_vmapx_get_by_index(ns->p_sets_vmap, set_id - 1, (void**)&p_set) != CF_VMAPX_OK) {
		return;
	}

	if (cf_atomic64_decr(&p_set->num_elements) < 0) {
		cf_warning(AS_NAMESPACE, "set_id %u - num_elements went negative!", set_id);
	}
}
Ejemplo n.º 5
0
const char *
as_bin_get_name_from_id(as_namespace *ns, uint16_t id)
{
	if (ns->single_bin) {
		cf_crash(AS_BIN, "single-bin call of as_bin_get_name_from_id()");
	}

	const char* name = NULL;

	if (cf_vmapx_get_by_index(ns->p_bin_name_vmap, id, (void**)&name) != CF_VMAPX_OK) {
		// TODO - Fail softly by returning forbidden bin name? (Empty string?)
		cf_crash(AS_BIN, "no bin name for id %u", id);
	}

	return name;
}
Ejemplo n.º 6
0
void
as_namespace_adjust_set_memory(as_namespace *ns, uint16_t set_id,
		int64_t delta_bytes)
{
	if (set_id == INVALID_SET_ID) {
		return;
	}

	as_set *p_set;

	if (cf_vmapx_get_by_index(ns->p_sets_vmap, set_id - 1, (void**)&p_set) != CF_VMAPX_OK) {
		cf_warning(AS_NAMESPACE, "set_id %u - failed to get as_set from vmap", set_id);
		return;
	}

	if (cf_atomic64_add(&p_set->n_bytes_memory, delta_bytes) < 0) {
		cf_warning(AS_NAMESPACE, "set_id %u - n_bytes_memory went negative!", set_id);
	}
}
Ejemplo n.º 7
0
void as_namespace_get_set_info(as_namespace *ns, const char *set_name, cf_dyn_buf *db)
{
	as_set *p_set;

	if (set_name) {
		if (cf_vmapx_get_by_name(ns->p_sets_vmap, set_name, (void**)&p_set) == CF_VMAPX_OK) {
			append_set_props(p_set, db);
		}

		return;
	}

	for (uint32_t idx = 0; idx < cf_vmapx_count(ns->p_sets_vmap); idx++) {
		if (cf_vmapx_get_by_index(ns->p_sets_vmap, idx, (void**)&p_set) == CF_VMAPX_OK) {
			cf_dyn_buf_append_string(db, "ns_name=");
			cf_dyn_buf_append_string(db, ns->name);
			cf_dyn_buf_append_char(db, ':');
			cf_dyn_buf_append_string(db, "set_name=");
			cf_dyn_buf_append_string(db, p_set->name);
			cf_dyn_buf_append_char(db, ':');
			append_set_props(p_set, db);
		}
	}
}
Ejemplo n.º 8
0
int as_namespace_get_create_set(as_namespace *ns, const char *set_name, uint16_t *p_set_id, bool apply_restrictions)
{
	if (! set_name) {
		// Should be impossible.
		cf_warning(AS_NAMESPACE, "null set name");
		return -1;
	}

	uint32_t idx;
	cf_vmapx_err result = cf_vmapx_get_index(ns->p_sets_vmap, set_name, &idx);
	bool already_in_vmap = false;

	if (result == CF_VMAPX_OK) {
		already_in_vmap = true;
	}
	else if (result == CF_VMAPX_ERR_NAME_NOT_FOUND) {
		as_set set;

		memset(&set, 0, sizeof(set));

		// Check name length just once, here at insertion. (Other vmap calls are
		// safe if name is too long - they return CF_VMAPX_ERR_NAME_NOT_FOUND.)
		strncpy(set.name, set_name, AS_SET_NAME_MAX_SIZE);

		if (set.name[AS_SET_NAME_MAX_SIZE - 1]) {
			set.name[AS_SET_NAME_MAX_SIZE - 1] = 0;

			cf_info(AS_NAMESPACE, "set name %s... too long", set.name);
			return -1;
		}

		set.num_elements = 1;
		result = cf_vmapx_put_unique(ns->p_sets_vmap, &set, &idx);

		if (result == CF_VMAPX_ERR_NAME_EXISTS) {
			already_in_vmap = true;
		}
		else if (result == CF_VMAPX_ERR_FULL) {
			cf_info(AS_NAMESPACE, "at set names limit, can't add %s", set.name);
			return -1;
		}
		else if (result != CF_VMAPX_OK) {
			// Currently, remaining errors are all some form of out-of-memory.
			cf_info(AS_NAMESPACE, "error %d, can't add %s", result, set.name);
			return -1;
		}
	}
	else {
		// Should be impossible.
		cf_warning(AS_NAMESPACE, "unexpected error %d", result);
		return -1;
	}

	if (already_in_vmap) {
		as_set *p_set;

		if ((result = cf_vmapx_get_by_index(ns->p_sets_vmap, idx, (void**)&p_set)) != CF_VMAPX_OK) {
			// Should be impossible - just verified idx.
			cf_warning(AS_NAMESPACE, "unexpected error %d", result);
			return -1;
		}

		// If requested, fail if emptying set or stop-writes limit is breached.
		if (apply_restrictions && (IS_SET_DELETED(p_set) || as_set_stop_writes(p_set))) {
			return -2;
		}

		// The set passed all tests - need to increment its num_elements.
		cf_atomic64_incr(&p_set->num_elements);
	}

	*p_set_id = (uint16_t)(idx + 1);

	return 0;
}