Beispiel #1
0
/* delete an node from tree */
static avl_node_t* avl_remove_node(avl_node_t* root, avl_key_t key)
{
    int factor = 0;
    int rotate = 0;
    if (root == NULL)
        return NULL;
    if (key < root->key)
    {
        root->left = avl_remove_node(root->left, key);
    }
    else if (key > root->key)
    {
        root->right = avl_remove_node(root->right, key);
    }
    else   /* this is the node to be deleted */
    {
        if ((root->left == NULL) || (root->right == NULL))
        {
            avl_node_t* node = (root->left ? root->left : root->right);
            if (node != NULL)  /* one child case */
            {
                *root = *node;
            }
            else  /* no child case */
            {
                node = root;
                root = NULL;
            }
            avl_free_node(node);
        }
        else  /* node with two children */
        {
            avl_node_t* node = avl_node_min(root->right);
            root->key = node->key;
            root->data = node->data;
            root->right = avl_remove_node(root->right, node->key);
        }
    }

    if (root == NULL)
        return NULL;
    root->height = MAX(HEIGHT(root->left), HEIGHT(root->right)) + 1;
    factor = avl_get_balance(root);
    if (factor > 1)
    {
        int left_balance = avl_get_balance(root->left);
        rotate = (left_balance >= 0 ? ROT_LEFT : ROT_RIGHT);
    }
    else if (factor < -1)
    {
        int right_balance = avl_get_balance(root->right);
        rotate = (right_balance <= 0 ? ROT_RIGHT : ROT_LEFT);
    }
    return avl_balance_node(root, factor, rotate);
}
Beispiel #2
0
int avl_remove(avl_node **r, void *key, avl_ft *ft){
	avl_node *n = avl_get(*r, key, ft);
	if(n){
		*r = avl_remove_node(n, ft);
	}
	return !!n;
}
Beispiel #3
0
int32_t bs_avl_remove(bs_avl_t* avl, avl_data_t data)
{
	avl->root = (void*)avl_remove_node(avl, (avl_node_t*)avl->root, data);

	bs_debug("height diff:%d\n", avl_get_balance((avl_node_t*)avl->root));
	return 0;
}
Beispiel #4
0
void *avl_remove(struct avltree *tree, void *item)
{
	struct avlnode *node;
	void *ret;
	node = avl_search(tree, item);
	if (!node) return NULL;
	ret = node->item;
	avl_remove_node(tree, node);
	return ret;
}
Beispiel #5
0
/* delete data from tree */
int avl_delete(avl_tree_t* tree, avl_key_t key)
{
    /* find before deletion, faster in missed case but slower in hit case */
    if (tree && avl_node_find(tree->root, key))
    {
        tree->root = avl_remove_node(tree->root, key);
        tree->size--;
        return 1;
    }
    return 0;
}
Beispiel #6
0
static avl_node_t* avl_remove_node(
	bs_avl_t* avl, 
	avl_node_t *parent, 
	avl_data_t data)
{
	avl_node_t* toRemove = NULL;
	avl_node_t* next = NULL;
	if(NULL == avl || NULL == avl->compare)
		return NULL;

	if(NULL == parent)
	{
		bs_debug("not found! \n");
		return NULL;
	}

	if(avl->compare(parent->data, data) < 0)
	{
		parent->right_child = avl_remove_node(avl, parent->right_child, data);
		return avl_rebalance(parent);
	}
	else if(avl->compare(parent->data, data) > 0)
	{
		parent->left_child = avl_remove_node(avl, parent->left_child, data);
		return avl_rebalance(parent);
	}
	else
	{
		bs_debug("remove :%d \n", parent->data);
		if(!parent->left_child && !parent->right_child)
		{
			bs_free((void*)parent);
			parent = NULL;
		}
		else if(!parent->left_child)
		{
			toRemove = parent;
			parent = parent->right_child;
			bs_free((void*)toRemove);

		}
		else if(!parent->right_child)
		{
			toRemove = parent;
			parent = parent->left_child;
			bs_free((void*)toRemove);
		}
		else
		{
			toRemove = parent;
			next = toRemove->right_child;
			if(next->left_child == NULL)
			{
				parent = next;
				parent->left_child = toRemove->left_child;
			}
			else
			{
				while(next->left_child->left_child)
					next = next->left_child;
				parent = next->left_child;
				next->left_child = parent->right_child;
				
				parent->left_child = toRemove->left_child;
				parent->right_child = toRemove->right_child;
			}

			bs_free(toRemove);
		}

		return avl_rebalance(parent);
	}
}
Beispiel #7
0
void ec_free(struct ecalloc *ecalloc, ADDR addr)
{
	struct ecalloc_header *header;
	struct ecalloc_header tmp;

	pthread_mutex_lock(&ecalloc->mutex);

	// find in used tree, free the node
	tmp.addr = addr;
	header = avl_remove(&ecalloc->used_tree, (void *)&tmp);

	if (!header) {
		printf("free a wrong addr %ld\n", addr);
		exit(-1);
	} else {
		ecalloc->used -= header->size;
		header->flag &= ~USING;
	}

	/* Combine neighbor behind */
	while (1) {
		struct ecalloc_header *next = header->next;

		/* If the next is in using, break */
		if (!next || next->flag & USING) break;
		assert(next->addr == header->addr + header->size);

		/* combine the two */
		header->size += next->size;
		header->next = next->next;
		if (header->next)
			header->next->prev = header;

		/* clean the next */
		avl_remove_node(&ecalloc->free_tree, next->node);
		free(next);
	}

	/* Combine neighbor front */
	while (1) {
		struct ecalloc_header *prev = header->prev;

		/* If the next is in using, break */
		if (!prev || prev->flag & USING) break;
		assert(prev->addr + prev->size == header->addr);

		/* combine the two */
		header->size += prev->size;
		header->addr = prev->addr;
		header->prev = prev->prev;
		if (header->prev)
			header->prev->next = header;

		/* clean the next */
		avl_remove_node(&ecalloc->free_tree, prev->node);
		free(prev);
	}

	header->node = avl_insert(&ecalloc->free_tree, header);
    pthread_mutex_unlock(&ecalloc->mutex);
}
Beispiel #8
0
ADDR ec_alloc(struct ecalloc *ecalloc, uint64_t size)
{
	ADDR ret;
	struct avlnode *node;
	struct ecalloc_header *header, *newer;
	struct ecalloc_header tmp;
	pthread_mutex_lock(&ecalloc->mutex);

	size = (size + 15) & (~15);
	ret = -1;

	/**
	 * Find the node containing enough space.
	 */
	tmp.size = size;
	node = avl_search_close(&ecalloc->free_tree, (void *)&tmp);
	if (!node) {
		perror("ec_alloc has no enough space");
		exit(-1);
	}
	header = (struct ecalloc_header *)node->item;
	if (header->size < size && node->next) {
		node = node->next;
		header = (struct ecalloc_header *)node->item;
	}
	if (header->size < size) {
		perror("ec_alloc has no enough space");
		exit(-1);
	} else {
		ret = header->addr;
		ecalloc->used += size;
	}

	/**
	 * Split the node into used and free
	 */
	avl_remove_node(&ecalloc->free_tree, node);
	if (header->size > size) {
		newer = safe_malloc(sizeof(struct ecalloc_header));
		newer->addr = header->addr;
		newer->size = size;
		newer->flag = USING;
		newer->node = avl_insert(&ecalloc->used_tree, newer);
		newer->next = header;

		newer->prev = header->prev;
		if (newer->prev) {
			newer->prev->next = newer;
		}

		header->prev = newer;
		header->addr += size;
		header->size -= size;
		header->node = avl_insert(&ecalloc->free_tree, header);
	} else {
		header->flag = USING;
		header->node = avl_insert(&ecalloc->used_tree, header);
	}

	pthread_mutex_unlock(&ecalloc->mutex);
	return ret;
}