예제 #1
0
파일: l2hash.c 프로젝트: zloidemon/eblob
/**
 * eblob_l2hash_remove_nolock() - remove l2hash entry specified by @key
 *
 * Returns:
 *	0:		@key removed
 *	-ENOENT:	@key not found
 *	Other:		Error
 */
static int eblob_l2hash_remove_nolock(struct eblob_l2hash *l2h,
		struct eblob_key *key)
{
	struct eblob_l2hash_collision *collision;
	struct eblob_l2hash_entry *e;
	int err;

	assert(l2h != NULL);
	assert(key != NULL);
	assert(pthread_mutex_trylock(&l2h->root_lock) == EBUSY);

	/* Find entry in tree */
	if ((e = __eblob_l2hash_lookup(l2h, key)) == NULL)
		return -ENOENT;

	/*
	 * If there are no collisions check that key belongs to rctl and
	 * remove entry from tree
	 */
	if (e->collision == 0) {
		switch(err = eblob_l2hash_compare_index(key, &e->rctl)) {
		case 0:
			rb_erase(&e->node, &l2h->root);
			free(e);
			return 0;
		case 1:
			return -ENOENT;
		default:
			return err;
		}
	}

	/* If collision is set and entry is not present in collision tree */
	collision = __eblob_l2hash_resolve_collision(&l2h->collisions, key);
	if (collision == NULL)
		return -ENOENT;

	/* Otherwise - remove entry from collision tree */
	rb_erase(&collision->node, &l2h->collisions);
	free(collision);
	return 0;
}
예제 #2
0
파일: l2hash.c 프로젝트: abudnik/eblob
/**
 * eblob_l2hash_resolve_collision() - resolves possible collision in l2hash by
 * going to disk or walking collision tree.
 *
 * Returns:
 *	0:		@key resolved into @rctl
 *	-ENOENT:	@key not found
 *	Other:		Error
 */
static int eblob_l2hash_resolve_collision(struct rb_root *root,
		struct eblob_l2hash_entry *e,
		const struct eblob_key *key,
		struct eblob_ram_control *rctl)
{
	struct eblob_l2hash_collision *collision;
	int err;

	assert(root != NULL);
	assert(e != NULL);
	assert(key != NULL);
	assert(rctl != NULL);

	/*
	 * No collision detected so just check that key really belongs
	 * to cached ram control.
	 */
	if (e->collision == 0) {
		switch((err = eblob_l2hash_compare_index(key, &e->rctl))) {
		case 0:
			*rctl = e->rctl;
			return 0;
		case 1:
			return -ENOENT;
		default:
			return err;
		}
		/* NOT REACHED */
	}

	/*
	 * If there is collision then we should look in collision tree.
	 */
	if ((collision = __eblob_l2hash_resolve_collision(root, key)) == NULL)
		return -ENOENT;

	*rctl = collision->rctl;
	return 0;
}