Example #1
0
/* actual insert: returns true -> insert ok or key found, false -> alloc failure */
bool cbtree_insert(struct CBTree *tree, void *obj)
{
	const void *key, *old_key;
	unsigned newbit, klen, old_klen;
	void *old_obj;

	if (!tree->root)
		return insert_first(tree, obj);

	/* current key */
	klen = get_key(tree, obj, &key);

	/* nearest key in tree */
	old_obj = raw_lookup(tree, key, klen);
	old_klen = get_key(tree, old_obj, &old_key);

	/* first differing bit is the target position */
	newbit = find_crit_bit(key, klen, old_key, old_klen);
	if (newbit == SAME_KEY)
		return true;
	return insert_at(tree, newbit, key, klen, obj);
}
Example #2
0
	/**
	 * Insert or update the given value under the given key.
	 *
	 * The map takes ownership of the value.
	 *
	 * @param key The key to insert under.
	 * @param value The value to be inserted.
	 *
	 * @return 0 on success, negative values on error.
	 */
	int
	insert(key_type key, value_type value)
	{
		auto dest_entry = root;
		while (dest_entry->inode != nullptr) {
			auto n = dest_entry->inode;
			dest_entry = n->entries[BIT_IS_SET(key, n->diff)];
		}

		entry e(key, value);
		auto pop = nvobj::pool_by_vptr(this);
		nvobj::transaction::exec_tx(pop, [&] {
			if (dest_entry->key == 0 || dest_entry->key == key) {
				nvobj::delete_persistent<T>(dest_entry->value);
				*dest_entry = e;
			} else {
				insert_leaf(&e, find_crit_bit(dest_entry->key,
							      key));
			}
		});

		return 0;
	}
Example #3
0
/*
 * ctree_insert -- inserts a new key into the tree
 */
int
ctree_insert(struct ctree *t, uint64_t key)
{
	void **dst = &t->root;
	struct node *a = NULL;
	int err;

	if ((err = pthread_mutex_lock(&t->lock)) != 0)
		return err;

	/* descend the path until a best matching key is found */
	while (NODE_IS_INTERNAL(*dst)) {
		a = NODE_INTERNAL_GET(*dst);
		dst = &a->slots[BIT_IS_SET(key, a->diff)];
	}

	uint64_t *dstkeyp = *dst;
	uint64_t *kp = Malloc(sizeof (uint64_t)); /* allocate leaf node */
	if (kp == NULL) {
		err = ENOMEM;
		goto error_leaf_malloc;
	}

	*kp = key;
	if (dstkeyp == NULL) { /* root */
		*dst = kp;
		goto out;
	}

	uint64_t dstkey = *dstkeyp;
	struct node *n = Malloc(sizeof (*n)); /* internal node */
	if (n == NULL) {
		err = ENOMEM;
		goto error_internal_Malloc;
	}

	if (dstkey == key) {
		err = EINVAL;
		goto error_duplicate;
	}

	n->diff = find_crit_bit(dstkey, key);

	/* insert the node at the direction based on the critical bit */
	int d = BIT_IS_SET(key, n->diff);
	n->slots[d] = kp;

	/* find the appropriate position in the tree to insert the node */
	dst = &t->root;
	while (NODE_IS_INTERNAL(*dst)) {
		a = NODE_INTERNAL_GET(*dst);

		/* the critical bits have to be sorted */
		if (a->diff < n->diff) break;
		dst = &a->slots[BIT_IS_SET(key, a->diff)];
	}

	/* insert the found destination in the other slot */
	n->slots[!d] = *dst;
	NODE_INTERNAL_SET(*dst, n);

out:
	if ((errno = pthread_mutex_unlock(&t->lock)) != 0)
		ERR("!pthread_mutex_unlock");

	return err;

error_internal_Malloc:
	Free(kp);
error_duplicate:
	Free(n);
error_leaf_malloc:
	if ((errno = pthread_mutex_unlock(&t->lock)) != 0)
		ERR("!pthread_mutex_unlock");

	return err;
}