Exemplo n.º 1
0
void set_cores(struct device *processors[], int processors_count)
{
	int cores_count = get_cores_count();

	//NO CORES FOUND (add an sample???)
	if (cores_count == 0)
		return;

	if (processors_count == 0)
		return;

	//ONE PROCESSOR (all the cores belongs to him)
	int i;
	if (processors_count == 1) {
		for (i = 0; i < cores_count; i++)
			set_child(processors[0], get_core(i));
		return;
	}
	//INCOMPLATIBLE DMIDECODE and CPUINFO || physical_id_uniq_count == 0
	int physical_id_uniq_count = get_physical_id_uniq_count();
	if (physical_id_uniq_count != processors_count) {
		for (i = 0; i < processors_count; i++)
			set_child(processors[i], get_core(0));
		return;
	}

	char *physical_id[cores_count];
	for (i = 0; i < cores_count; i++) {
		physical_id[i] = get_core_physical_id_value(i);
	}

	for (i = 0; i < processors_count; i++) {
		char *physical_id_uniq = get_physical_id_uniq(i);
		int j;
		for (j = 0; j < cores_count; j++) {
			if (physical_id_uniq && physical_id[j]
			    && strcmp(physical_id_uniq, physical_id[j]) == 0) {
				set_child(processors[i], get_core(j));
			}
		}
		delete(&physical_id_uniq);
	}

	for (i = 0; i < cores_count; i++) {
		delete(&physical_id[i]);
	}
}
Exemplo n.º 2
0
void set_caches(struct device *processors[], int processors_count)
{
	int caches_count = get_caches_count();

	int i;
	//NO CACHES, ADD ONE CACHE WITH UNDEFINED_INFO FOR OUTPUT EXAMPLE
	if (caches_count == 0) {
		for (i = 0; i < processors_count; i++)
			set_child(processors[i], get_cache(0));
		return;
	}

	char *handle[caches_count];
	for (i = 0; i < caches_count; i++) {
		handle[i] = get_cache_handle_value(i);
	}

	for (i = 0; i < processors_count; i++) {
		int j;
		char *cache_handle_l1 = get_processor_l1_cache_handle(i);
		char *cache_handle_l2 = get_processor_l2_cache_handle(i);
		char *cache_handle_l3 = get_processor_l3_cache_handle(i);

		for (j = 0; j < caches_count; j++) {
			if (cache_handle_l1 && handle[j]
			    && strcmp(cache_handle_l1, handle[j]) == 0) {
				set_child(processors[i], get_cache(j));
			} else if (cache_handle_l2 && handle[j]
				   && strcmp(cache_handle_l2, handle[j]) == 0) {
				set_child(processors[i], get_cache(j));
			} else if (cache_handle_l3 && handle[j]
				   && strcmp(cache_handle_l3, handle[j]) == 0) {
				set_child(processors[i], get_cache(j));
			}
		}

		delete(&cache_handle_l1);
		delete(&cache_handle_l2);
		delete(&cache_handle_l3);
	}

	for (i = 0; i < caches_count; i++) {
		delete(&handle[i]);
	}
}
Exemplo n.º 3
0
void create() {

	NodeData data;
	memset(&data, 0, sizeof(NodeData));

	init();

	data.id = 0;
	strncpy(data.name, "root", sizeof(data.name) - 1);

	set_root(data);

	memset(&data, 0, sizeof(NodeData));
	data.id = 1;
	strncpy(data.name, "root-child-1", sizeof(data.name) - 1);

	set_child(0, 1, data);

	memset(&data, 0, sizeof(NodeData));
	data.id = 2;
	strncpy(data.name, "root-child-2", sizeof(data.name) - 1);

	set_child(0, 2, data);

	memset(&data, 0, sizeof(NodeData));
	data.id = 3;
	strncpy(data.name, "root-child-3", sizeof(data.name) - 1);

	set_child(0, 3, data);

	memset(&data, 0, sizeof(NodeData));
	data.id = 4;
	strncpy(data.name, "root-child-1-1", sizeof(data.name) - 1);

	set_child(1, 4, data);

	memset(&data, 0, sizeof(NodeData));
	data.id = 5;
	strncpy(data.name, "root-child-1-2", sizeof(data.name) - 1);

	set_child(1, 5, data);

	return;
}
Exemplo n.º 4
0
View::View(ViewRegistry* view_reg, const std::string& name, const bfs::path& dist_file)
	: DistributedObject(dist_file),
	  view_reg_(view_reg),
	  name_(name),
	  update_interval_(5 * 60),	/* 5 minutes */
	  extra_node_action_(ENA_REMOVE),
	  default_intrapid_pdistance_(0),
	  default_interpid_pdistance_(INFINITY),
	  default_interdomain_pdistance_(60),
	  default_pidlink_pdistance_(1),
	  interdomain_includes_intradomain_(true),
	  pid_ttl_(7 * 24 * 60 * 60),	/* 1 week */
	  pdistance_ttl_(2 * 60 * 60)	/* 2 hours */
{
	{
		BlockWriteLock lock(*this);
		set_child(CHILD_IDX_AGGREGATION, PIDAggregationPtr(new PIDAggregation()), lock);
		set_child(CHILD_IDX_PREFIXES, PIDMapPtr(new PIDMap()), lock);
		set_child(CHILD_IDX_INTRA_ROUTING, PIDRoutingPtr(new PIDRouting(DEFAULT_WEIGHT)), lock);
		set_child(CHILD_IDX_LINK_PDISTANCES, SparsePIDMatrixPtr(new SparsePIDMatrix()), lock);
		set_child(CHILD_IDX_INTRA_PDISTANCES, PIDMatrixPtr(new PIDMatrix()), lock);
		set_child(CHILD_IDX_INTER_PDISTANCES, SparsePIDMatrixPtr(new SparsePIDMatrix()), lock);
	}

	after_construct();
}
Exemplo n.º 5
0
Arquivo: avl.c Projeto: kuzmas/anytree
void avltree_replace(struct avltree_node *old, struct avltree_node *node, struct avltree *tree)
{
    struct avltree_node *parent = get_parent(old);

    if (parent)
        set_child(node, parent, parent->left == old);
    else
        tree->root = node;

    if (old->left)
        set_parent(node, old->left);
    if (old->right)
        set_parent(node, old->right);

    if (tree->first == old)
        tree->first = node;
    if (tree->last == old)
        tree->last = node;

    *node = *old;
}
Exemplo n.º 6
0
void set_processor_device(struct device *device)
{
	if (device == NULL)
		return;

	int processors_count = get_processors_count();	//returns at least 1;
	struct device *processors[processors_count];

	int i;
	for (i = 0; i < processors_count; i++) {
		processors[i] = new_device("Processor");
		add_info(processors[i], get_processor_family(i));
		add_info(processors[i], get_processor_version(i));
		add_info(processors[i], get_processor_socket_designation(i));
		add_info(processors[i], get_processor_manufacturer(i));
		add_info(processors[i], get_processor_id(i));
		add_info(processors[i], get_processor_voltage(i));
		add_info(processors[i], get_processor_external_clock(i));
		set_child(device, processors[i]);
	}

	set_caches(processors, processors_count);
	set_cores(processors, processors_count);
}
Exemplo n.º 7
0
static int 
thread_unsafe_avl_tree_remove (avl_tree_t *tree,
        void *data_to_be_removed,
        void **actual_data_removed)
{
    avl_node_t *node, *to_be_deleted;
    avl_node_t *parent, *unbalanced;
    avl_node_t *left;
    avl_node_t *right;
    avl_node_t *next;
    int is_left;

    /* being traversed, cannot access */
    if (tree->cannot_be_modified) return EBUSY;

    /* find the matching node first */
    node = avl_lookup_engine(tree, data_to_be_removed,
            &parent, &unbalanced, &is_left);

    /* not there */
    if (!node) {
        *actual_data_removed = NULL;
        return ENODATA;
    }

    /* if we are here, we found it */
    *actual_data_removed = node->user_data;

    /* cache it for later freeing */
    to_be_deleted = node;

    parent = node->parent;
    left = node->left;
    right = node->right;

#if 0
    if (node == tree->first_node)
        tree->first_node = avl_tree_next(node);
    if (node == tree->last_node)
        tree->last_node = avl_tree_prev(node);
#endif

    if (!left)
        next = right;
    else if (!right)
        next = left;
    else
        next = get_first(right);

    if (parent) {
        is_left = (parent->left == node);
        set_child(next, parent, is_left);
    } else
        tree->root_node = next;

    if (left && right) {
        next->balance = node->balance;
        next->left = left;
        left->parent = next;
        if (next != right) {
            parent = next->parent;
            next->parent = node->parent;
            node = next->right;
            parent->left = node;
            next->right = right;
            right->parent = next;
            is_left = 1;
        } else {
            next->parent = parent;
            parent = next;
            node = parent->right;
            is_left = 0;
        }
        assert(parent != NULL);
    } else
        node = next;

    if (node)
        node->parent = parent;

    while (parent) {

        int balance;
            
        node = parent;
        parent = parent->parent;
        if (is_left) {
            is_left = (parent && (parent->left == node));
            balance = ++node->balance;
            if (balance == 0)           /* case 1 */
                continue;
            if (balance == 1) {         /* case 2 */
                goto END_OF_DELETE;
            }
            right = node->right;
            switch (right->balance) {
            case 0:                             /* case 3.1 */
                node->balance = 1;
                right->balance = -1;
                rotate_left(node, tree);
                goto END_OF_DELETE;
            case 1:                             /* case 3.2 */
                node->balance = 0;
                right->balance = 0;
                break;
            case -1:                    /* case 3.3 */
                switch (right->left->balance) {
                case 1:
                    node->balance = -1;
                    right->balance = 0;
                    break;
                case 0:
                    node->balance = 0;
                    right->balance = 0;
                    break;
                case -1:
                    node->balance = 0;
                    right->balance = 1;
                    break;
                }
                right->left->balance = 0;
                rotate_right(right, tree);
            }
            rotate_left(node, tree);
        } else {
            is_left = (parent && (parent->left == node));
            balance = --node->balance;
            if (balance == 0)
                continue;
            if (balance == -1) {
                goto END_OF_DELETE;
            }
            left = node->left;
            switch (left->balance) {
            case 0:
                node->balance = -1;
                left->balance = 1;
                rotate_right(node, tree);
                goto END_OF_DELETE;
            case -1:
                node->balance = 0;
                left->balance = 0;
                break;
            case 1:
                switch (left->right->balance) {
                case 1:
                    node->balance = 0;
                    left->balance = -1;
                    break;
                case 0:
                    node->balance = 0;
                    left->balance = 0;
                    break;
                case -1:
                    node->balance = 1;
                    left->balance = 0;
                    break;
                }
                left->right->balance = 0;
                rotate_left(left, tree);
            }
            rotate_right(node, tree);
        }
    }

END_OF_DELETE:
                
    free_avl_node(tree, to_be_deleted);
    if (tree->n <= 0) {
        assert(tree->root_node == NULL);
    } else {
        assert(tree->root_node != NULL);
    }
    return 0;
}
Exemplo n.º 8
0
static int 
thread_unsafe_avl_tree_insert (avl_tree_t *tree,
    void *data_to_be_inserted,
    void **data_already_present)
{
    avl_node_t *found, *parent, *unbalanced, *node;
    int is_left;

    /* assume the entry is not present initially */
    *data_already_present = NULL;

    /* traversing the tree, access not allowed */
    if (tree->cannot_be_modified) return EBUSY;

    found = avl_lookup_engine(tree, data_to_be_inserted,
                &parent, &unbalanced, &is_left);

    if (found) {
        *data_already_present = found->user_data;
        return 0;
    }

    /* get a new node */
    node = new_avl_node(tree, data_to_be_inserted);
    if (NULL == node) {
        return ENOMEM;
    }

    if (!parent) {
        tree->root_node = node;
#if 0
        tree->first_node = tree->last_node = node;
#endif
        return 0;
    }

#if 0
    if (is_left) {
        if (parent == tree->first_node)
            tree->first_node = node;
    } else {
        if (parent == tree->last_node)
            tree->last_node = node;
    }
#endif

    node->parent = parent;
    set_child(node, parent, is_left);
    for (;;) {
        if (parent->left == node)
            (parent->balance)--;
        else
            (parent->balance)++;
        if (parent == unbalanced)
            break;
        node = parent;
        parent = parent->parent;
    }

    switch (unbalanced->balance) {
    case  1: 
    case -1:
    case 0:
        break;
        
    case 2: 
        {
            avl_node_t *right = unbalanced->right;

            if (right->balance == 1) {
                unbalanced->balance = 0;
                right->balance = 0;
            } else {
                switch (right->left->balance) {
                case 1:
                    unbalanced->balance = -1;
                    right->balance = 0;
                    break;
                case 0:
                    unbalanced->balance = 0;
                    right->balance = 0;
                    break;
                case -1:
                    unbalanced->balance = 0;
                    right->balance = 1;
                    break;
                }
                right->left->balance = 0;
                rotate_right(right, tree);
            }
            rotate_left(unbalanced, tree);
            break;
        }
    case -2: 
        {
            avl_node_t *left = unbalanced->left;

            if (left->balance == -1) {
                unbalanced->balance = 0;
                left->balance = 0;
            } else {
                switch (left->right->balance) {
                case 1:
                    unbalanced->balance = 0;
                    left->balance = -1;
                    break;
                case 0:
                    unbalanced->balance = 0;
                    left->balance = 0;
                    break;
                case -1:
                    unbalanced->balance = 1;
                    left->balance = 0;
                    break;
                }
                left->right->balance = 0;
                rotate_left(left, tree);
            }
            rotate_right(unbalanced, tree);
            break;
        }
    }
    return 0;
}
Exemplo n.º 9
0
void rbtree_remove(struct rbtree_node *node, struct rbtree *tree)
{
	struct rbtree_node *parent = get_parent(node);
	struct rbtree_node *left = node->left;
	struct rbtree_node *right = node->right;
	struct rbtree_node *next;
	enum rb_color color;

	if (node == tree->first)
		tree->first = rbtree_next(node);
	if (node == tree->last)
		tree->last = rbtree_prev(node);

	if (!left)
		next = right;
	else if (!right)
		next = left;
	else
		next = get_first(right);

	if (parent)
		set_child(next, parent, parent->left == node);
	else
		tree->root = next;

	if (left && right) {
		color = get_color(next);
		set_color(get_color(node), next);

		next->left = left;
		set_parent(next, left);

		if (next != right) {
			parent = get_parent(next);
			set_parent(get_parent(node), next);

			node = next->right;
			parent->left = node;

			next->right = right;
			set_parent(next, right);
		} else {
			set_parent(parent, next);
			parent = next;
			node = next->right;
		}
	} else {
		color = get_color(node);
		node = next;
	}
	/*
	 * 'node' is now the sole successor's child and 'parent' its
	 * new parent (since the successor can have been moved).
	 */
	if (node)
		set_parent(parent, node);

	/*
	 * The 'easy' cases.
	 */
	if (color == RB_RED)
		return;
	if (node && is_red(node)) {
		set_color(RB_BLACK, node);
		return;
	}

	do {
		if (node == tree->root)
			break;

		if (node == parent->left) {
			struct rbtree_node *sibling = parent->right;

			if (is_red(sibling)) {
				set_color(RB_BLACK, sibling);
				set_color(RB_RED, parent);
				rotate_left(parent, tree);
				sibling = parent->right;
			}
			if ((!sibling->left || is_black(sibling->left))
			    && (!sibling->right || is_black(sibling->right))) {
				set_color(RB_RED, sibling);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (!sibling->right || is_black(sibling->right)) {
				set_color(RB_BLACK, sibling->left);
				set_color(RB_RED, sibling);
				rotate_right(sibling, tree);
				sibling = parent->right;
			}
			set_color(get_color(parent), sibling);
			set_color(RB_BLACK, parent);
			set_color(RB_BLACK, sibling->right);
			rotate_left(parent, tree);
			node = tree->root;
			break;
		} else {
			struct rbtree_node *sibling = parent->left;

			if (is_red(sibling)) {
				set_color(RB_BLACK, sibling);
				set_color(RB_RED, parent);
				rotate_right(parent, tree);
				sibling = parent->left;
			}
			if ((!sibling->left || is_black(sibling->left))
			    && (!sibling->right || is_black(sibling->right))) {
				set_color(RB_RED, sibling);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (!sibling->left || is_black(sibling->left)) {
				set_color(RB_BLACK, sibling->right);
				set_color(RB_RED, sibling);
				rotate_left(sibling, tree);
				sibling = parent->left;
			}
			set_color(get_color(parent), sibling);
			set_color(RB_BLACK, parent);
			set_color(RB_BLACK, sibling->left);
			rotate_right(parent, tree);
			node = tree->root;
			break;
		}
	} while (is_black(node));

	if (node)
		set_color(RB_BLACK, node);
}
Exemplo n.º 10
0
struct rbtree_node *rbtree_insert(struct rbtree_node *node, struct rbtree *tree)
{
	struct rbtree_node *key, *parent;
	int is_left;

	key = do_lookup(node, tree, &parent, &is_left);
	if (key)
		return key;

	node->left = NULL;
	node->right = NULL;
	set_color(RB_RED, node);
	set_parent(parent, node);

	if (parent) {
		if (is_left) {
			if (parent == tree->first)
				tree->first = node;
		} else {
			if (parent == tree->last)
				tree->last = node;
		}
		set_child(node, parent, is_left);
	} else {
		tree->root = node;
		tree->first = node;
		tree->last = node;
	}

	/*
	 * Fixup the modified tree by recoloring nodes and performing
	 * rotations (2 at most) hence the red-black tree properties are
	 * preserved.
	 */
	while ((parent = get_parent(node)) && is_red(parent)) {
		struct rbtree_node *grandpa = get_parent(parent);

		if (parent == grandpa->left) {
			struct rbtree_node *uncle = grandpa->right;

			if (uncle && is_red(uncle)) {
				set_color(RB_BLACK, parent);
				set_color(RB_BLACK, uncle);
				set_color(RB_RED, grandpa);
				node = grandpa;
			} else {
				if (node == parent->right) {
					rotate_left(parent, tree);
					node = parent;
					parent = get_parent(node);
				}
				set_color(RB_BLACK, parent);
				set_color(RB_RED, grandpa);
				rotate_right(grandpa, tree);
			}
		} else {
			struct rbtree_node *uncle = grandpa->left;

			if (uncle && is_red(uncle)) {
				set_color(RB_BLACK, parent);
				set_color(RB_BLACK, uncle);
				set_color(RB_RED, grandpa);
				node = grandpa;
			} else {
				if (node == parent->left) {
					rotate_right(parent, tree);
					node = parent;
					parent = get_parent(node);
				}
				set_color(RB_BLACK, parent);
				set_color(RB_RED, grandpa);
				rotate_left(grandpa, tree);
			}
		}
	}
	set_color(RB_BLACK, tree->root);
	return NULL;
}
Exemplo n.º 11
0
struct rbtree_node* __rbtree_insert(struct rbtree_node* node,struct rbtree *tree)
{
    struct rbtree_node* samenode=NULL;
    struct rbtree_node*parent=NULL;

    samenode = do_lookup(node->key,tree,&parent);
    if(samenode != NULL)
        return samenode;

    node->left = node->right = NULL;
    set_color(RB_RED,node);
    set_parent(parent,node);

    if(parent == NULL)
        tree->root = node;
    else
    {
        set_child(tree,parent,node);
    }

    while((parent = get_parent(node)) != NULL && parent->color == RB_RED)
    {
        struct rbtree_node* grandpa = get_parent(parent);//grandpa must be existed 
        //because root is black ,and parent is red,
        //parent can not be root of tree. and parent is red,so grandpa must be black
        if(parent == grandpa->left)
        {
            struct rbtree_node* uncle = grandpa->right;
            if(uncle && get_color(uncle) == RB_RED)
            {
                set_color(RB_RED,grandpa);
                set_color(RB_BLACK,parent);
                set_color(RB_BLACK,uncle);
                node = grandpa;
            }
            else
            {
                if(node == parent->right )
                {
                    rotate_left(parent,tree);
                    node = parent;
                    parent = get_parent(parent);
                }
                set_color(RB_BLACK,parent);
                set_color(RB_RED,grandpa);
                rotate_right(grandpa,tree);
            }

        }
        else
        {
            struct rbtree_node* uncle = grandpa->left;
            if(uncle && uncle->color == RB_RED)
            {
                set_color(RB_RED,grandpa);
                set_color(RB_BLACK,parent);
                set_color(RB_BLACK,uncle);
                node = grandpa;
            }
            else
            {
                if(node == parent->left)
                {
                    rotate_right(parent,tree);
                    node = parent;
                    parent = get_parent(node);
                }
                set_color(RB_BLACK, parent);
                set_color(RB_RED, grandpa);
                rotate_left(grandpa, tree);
            }
        }
    }

    set_color(RB_BLACK,tree->root);
    return NULL;
}
Exemplo n.º 12
0
/**
 * Remove node from tree.
 *
 * @attention
 * It is assumed that the node is already part of the tree.
 */
void G_HOT
erbtree_remove(erbtree_t *tree, rbnode_t *node)
{
	rbnode_t *removed = node;
	rbnode_t *parent = get_parent(node);
	rbnode_t *left = node->left;
	rbnode_t *right = node->right;
	rbnode_t *next;
	enum rbcolor color;

	erbtree_check(tree);
	g_assert(size_is_positive(tree->count));
	g_assert(node != NULL);
	g_assert(is_valid(node));	/* Does not verify it is part of THIS tree */

	tree->count--;

	if (node == tree->first)
		tree->first = erbtree_next(node);
	if (node == tree->last)
		tree->last = erbtree_prev(node);

	if (NULL == left)
		next = right;
	else if (NULL == right)
		next = left;
	else
		next = get_first(right);

	if (parent != NULL)
		set_child(parent, next, parent->left == node);
	else
		tree->root = next;

	if (left != NULL && right != NULL) {
		color = get_color(next);
		set_color(next, get_color(node));

		next->left = left;
		set_parent(left, next);

		if (next != right) {
			parent = get_parent(next);
			set_parent(next, get_parent(node));

			node = next->right;
			parent->left = node;

			next->right = right;
			set_parent(right, next);
		} else {
			set_parent(next, parent);
			parent = next;
			node = next->right;
		}
	} else {
		color = get_color(node);
		node = next;
	}

	/*
	 * 'node' is now the sole successor's child and 'parent' its
	 * new parent (since the successor can have been moved).
	 */

	if (node != NULL)
		set_parent(node, parent);

	invalidate(removed);

	/*
	 * The "easy" cases.
	 */

	if (color == RB_RED)
		return;
	if (node != NULL && is_red(node)) {
		set_color(node, RB_BLACK);
		return;
	}

	do {
		if (node == tree->root)
			break;

		if (node == parent->left) {
			rbnode_t *sibling = parent->right;

			if (is_red(sibling)) {
				set_color(sibling, RB_BLACK);
				set_color(parent, RB_RED);
				rotate_left(tree, parent);
				sibling = parent->right;
			}
			if (
				(NULL == sibling->left  || is_black(sibling->left)) &&
			    (NULL == sibling->right || is_black(sibling->right))
			) {
				set_color(sibling, RB_RED);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (NULL == sibling->right || is_black(sibling->right)) {
				set_color(sibling->left, RB_BLACK);
				set_color(sibling, RB_RED);
				rotate_right(tree, sibling);
				sibling = parent->right;
			}
			set_color(sibling, get_color(parent));
			set_color(parent, RB_BLACK);
			set_color(sibling->right, RB_BLACK);
			rotate_left(tree, parent);
			node = tree->root;
			break;
		} else {
			rbnode_t *sibling = parent->left;

			if (is_red(sibling)) {
				set_color(sibling, RB_BLACK);
				set_color(parent, RB_RED);
				rotate_right(tree, parent);
				sibling = parent->left;
			}
			if (
				(NULL == sibling->left  || is_black(sibling->left)) &&
			    (NULL == sibling->right || is_black(sibling->right))
			) {
				set_color(sibling, RB_RED);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (NULL == sibling->left || is_black(sibling->left)) {
				set_color(sibling->right, RB_BLACK);
				set_color(sibling, RB_RED);
				rotate_left(tree, sibling);
				sibling = parent->left;
			}
			set_color(sibling, get_color(parent));
			set_color(parent, RB_BLACK);
			set_color(sibling->left, RB_BLACK);
			rotate_right(tree, parent);
			node = tree->root;
			break;
		}
	} while (is_black(node));

	if (node != NULL)
		set_color(node, RB_BLACK);
}
Exemplo n.º 13
0
/* 插入key, value */
int h_rbtree_insert(h_rbtree_st *tree, const void *key,
        uint32_t ksize, void *val)
{
    rbtree_node_st *parent;
    int is_left;
    rbtree_node_st *node = do_lookup(tree, key, ksize, &parent, &is_left);

    if (node) {
        if ((void *)tree->data_free)
            tree->data_free(node->cs.data);

        node->cs.data = val;
        return 0;
    }

    if ((node = h_calloc(1, sizeof(rbtree_node_st) + ksize)) == NULL)
        return -1;

    memcpy_s(node->cs.key, key, ksize);
    node->cs.ksize = ksize;
    node->cs.data = val;

    node->left = NULL;
    node->right = NULL;
    set_color(RB_RED, node);
    set_parent(parent, node);

    if (parent) {
        if (is_left) {
            if (parent == tree->first)
                tree->first = node;
        } else {
            if (parent == tree->last)
                tree->last = node;
        }
        set_child(node, parent, is_left);
    } else {
        tree->root = node;
        tree->first = node;
        tree->last = node;
    }

    /*
     * Fixup the modified tree by recoloring nodes and performing
     * rotations (2 at most) hence the red-black tree properties are
     * preserved.
     */
    while ((parent = get_parent(node)) && is_red(parent)) {
        rbtree_node_st *grandpa = get_parent(parent);

        if (parent == grandpa->left) {
            rbtree_node_st *uncle = grandpa->right;

            if (uncle && is_red(uncle)) {
                set_color(RB_BLACK, parent);
                set_color(RB_BLACK, uncle);
                set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == parent->right) {
                    rotate_left(tree, parent);
                    node = parent;
                    parent = get_parent(node);
                }
                set_color(RB_BLACK, parent);
                set_color(RB_RED, grandpa);
                rotate_right(tree, grandpa);
            }
        } else {
            rbtree_node_st *uncle = grandpa->left;

            if (uncle && is_red(uncle)) {
                set_color(RB_BLACK, parent);
                set_color(RB_BLACK, uncle);
                set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == parent->left) {
                    rotate_right(tree, parent);
                    node = parent;
                    parent = get_parent(node);
                }
                set_color(RB_BLACK, parent);
                set_color(RB_RED, grandpa);
                rotate_left(tree, grandpa);
            }
        }
    }
    set_color(RB_BLACK, tree->root);
    tree->nelem++;
    return 0;
}
Exemplo n.º 14
0
/* Insertion never needs more than 2 rotations */
struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree, avltree_cmp_fn_t cmp)
{
	struct avltree_node *key, *parent, *unbalanced;
	int is_left;

        cmp_fn = cmp;

	key = do_lookup(node, tree, &parent, &unbalanced, &is_left);
	if (key)
		return key;

	node->left = NULL;
	node->right = NULL;
	node->parent = NULL;
	node->balance = 0;

	if (!parent) {
		tree->root = node;
		tree->first = tree->last = node;
		tree->height++;
		return NULL;
	}
	if (is_left) {
		if (parent == tree->first)
			tree->first = node;
	} else {
		if (parent == tree->last)
			tree->last = node;
	}
	node->parent = parent;
	set_child(node, parent, is_left);

	for (;;) {
		if (parent->left == node)
			parent->balance--;
		else
			parent->balance++;

		if (parent == unbalanced)
			break;
		node = parent;
		parent = parent->parent;
	}

	switch (unbalanced->balance) {
	case  1: case -1:
		tree->height++;
		/* fall through */
	case 0:
		break;
	case 2: {
		struct avltree_node *right = unbalanced->right;

		if (right->balance == 1) {
			unbalanced->balance = 0;
			right->balance = 0;
		} else {
			switch (right->left->balance) {
			case 1:
				unbalanced->balance = -1;
				right->balance = 0;
				break;
			case 0:
				unbalanced->balance = 0;
				right->balance = 0;
				break;
			case -1:
				unbalanced->balance = 0;
				right->balance = 1;
				break;
			}
			right->left->balance = 0;

			rotate_right(right, tree);
		}
		rotate_left(unbalanced, tree);
		break;
	}
	case -2: {
		struct avltree_node *left = unbalanced->left;

		if (left->balance == -1) {
			unbalanced->balance = 0;
			left->balance = 0;
		} else {
			switch (left->right->balance) {
			case 1:
				unbalanced->balance =  0;
				left->balance = -1;
				break;
			case 0:
				unbalanced->balance = 0;
				left->balance = 0;
				break;
			case -1:
				unbalanced->balance = 1;
				left->balance = 0;
				break;
			}
			left->right->balance = 0;

			rotate_left(left, tree);
		}
		rotate_right(unbalanced, tree);
		break;
	}
	}
	return NULL;
}
Exemplo n.º 15
0
/* 删除key */
int h_rbtree_delete(h_rbtree_st *tree, const void *key, uint32_t ksize)
{
    rbtree_node_st *parent, *left, *right, *next;
    rb_color_t color;
    int is_left;
    rbtree_node_st *oldnode = do_lookup(tree, key, ksize, &parent, &is_left);
    rbtree_node_st *node;

    if (!oldnode)
        return -1;

    node = oldnode;
    left = node->left;
    right = node->right;

    if (node == tree->first)
        tree->first = rb_next(node);
    if (node == tree->last)
        tree->last = rb_prev(node);

    if (!left)
        next = right;
    else if (!right)
        next = left;
    else
        next = get_first(right);

    if (parent)
        set_child(next, parent, parent->left == node);
    else
        tree->root = next;

    if (left && right) {
        color = get_color(next);
        set_color(get_color(node), next);

        next->left = left;
        set_parent(next, left);

        if (next != right) {
            parent = get_parent(next);
            set_parent(get_parent(node), next);

            node = next->right;
            parent->left = node;

            next->right = right;
            set_parent(next, right);
        } else {
            set_parent(parent, next);
            parent = next;
            node = next->right;
        }
    } else {
        color = get_color(node);
        node = next;
    }
    /*
     * 'node' is now the sole successor's child and 'parent' its
     * new parent (since the successor can have been moved).
     */
    if (node)
        set_parent(parent, node);

    /*
     * The 'easy' cases.
     */
    if (color == RB_RED)
        goto end_delete;
    if (node && is_red(node)) {
        set_color(RB_BLACK, node);
        goto end_delete;
    }

    do {
        if (node == tree->root)
            break;

        if (node == parent->left) {
            rbtree_node_st *sibling = parent->right;

            if (is_red(sibling)) {
                set_color(RB_BLACK, sibling);
                set_color(RB_RED, parent);
                rotate_left(tree, parent);
                sibling = parent->right;
            }
            if ((!sibling->left  || is_black(sibling->left)) &&
                (!sibling->right || is_black(sibling->right))) {
                set_color(RB_RED, sibling);
                node = parent;
                parent = get_parent(parent);
                continue;
            }
            if (!sibling->right || is_black(sibling->right)) {
                set_color(RB_BLACK, sibling->left);
                set_color(RB_RED, sibling);
                rotate_right(tree, sibling);
                sibling = parent->right;
            }
            set_color(get_color(parent), sibling);
            set_color(RB_BLACK, parent);
            set_color(RB_BLACK, sibling->right);
            rotate_left(tree, parent);
            node = tree->root;
            break;
        } else {
            rbtree_node_st *sibling = parent->left;

            if (is_red(sibling)) {
                set_color(RB_BLACK, sibling);
                set_color(RB_RED, parent);
                rotate_right(tree, parent);
                sibling = parent->left;
            }
            if ((!sibling->left  || is_black(sibling->left)) &&
                (!sibling->right || is_black(sibling->right))) {
                set_color(RB_RED, sibling);
                node = parent;
                parent = get_parent(parent);
                continue;
            }
            if (!sibling->left || is_black(sibling->left)) {
                set_color(RB_BLACK, sibling->right);
                set_color(RB_RED, sibling);
                rotate_left(tree, sibling);
                sibling = parent->left;
            }
            set_color(get_color(parent), sibling);
            set_color(RB_BLACK, parent);
            set_color(RB_BLACK, sibling->left);
            rotate_right(tree, parent);
            node = tree->root;
            break;
        }
    } while (is_black(node));

    if (node)
        set_color(RB_BLACK, node);

end_delete:
    if ((void *)tree->data_free)
        tree->data_free(oldnode->cs.data);

    h_free(oldnode);
    tree->nelem--;

    return 0;
}
Exemplo n.º 16
0
/**
 * Insert node in tree.
 *
 * @return the existing key if the key already existed, NULL if the node
 * was properly inserted.
 */
void * G_HOT
erbtree_insert(erbtree_t *tree, rbnode_t *node)
{
	rbnode_t *key, *parent;
	const void *kbase;
	bool is_left;

	erbtree_check(tree);
	g_assert(node != NULL);

	kbase = const_ptr_add_offset(node, -tree->offset);

	if (erbtree_is_extended(tree)) {
		key = do_lookup_ext(ERBTREE_E(tree), kbase, &parent, &is_left);
	} else {
		key = do_lookup(tree, kbase, &parent, &is_left);
	}

	if (key != NULL)
		return ptr_add_offset(key, -tree->offset);

	g_assert(!is_valid(node));	/* Not yet part of the tree */

	node->left = NULL;
	node->right = NULL;
	set_color(node, RB_RED);
	set_parent(node, parent);
	tree->count++;

	if (parent != NULL) {
		if (is_left) {
			if (parent == tree->first)
				tree->first = node;
		} else {
			if (parent == tree->last)
				tree->last = node;
		}
		set_child(parent, node, is_left);
	} else {
		tree->root = node;
		tree->first = node;
		tree->last = node;
	}

	/*
	 * Fixup the modified tree by recoloring nodes and performing
	 * rotations (2 at most) hence the red-black tree properties are
	 * preserved.
	 */

	while (NULL != (parent = get_parent(node)) && is_red(parent)) {
		rbnode_t *grandpa = get_parent(parent);

		if (parent == grandpa->left) {
			rbnode_t *uncle = grandpa->right;

			if (uncle != NULL && is_red(uncle)) {
				set_color(parent, RB_BLACK);
				set_color(uncle, RB_BLACK);
				set_color(grandpa, RB_RED);
				node = grandpa;
			} else {
				if (node == parent->right) {
					rotate_left(tree, parent);
					node = parent;
					parent = get_parent(node);
				}
				set_color(parent, RB_BLACK);
				set_color(grandpa, RB_RED);
				rotate_right(tree, grandpa);
			}
		} else {
			rbnode_t *uncle = grandpa->left;

			if (uncle != NULL && is_red(uncle)) {
				set_color(parent, RB_BLACK);
				set_color(uncle, RB_BLACK);
				set_color(grandpa, RB_RED);
				node = grandpa;
			} else {
				if (node == parent->left) {
					rotate_right(tree, parent);
					node = parent;
					parent = get_parent(node);
				}
				set_color(parent, RB_BLACK);
				set_color(grandpa, RB_RED);
				rotate_left(tree, grandpa);
			}
		}
	}
	set_color(tree->root, RB_BLACK);
	return NULL;
}
Exemplo n.º 17
0
/* Insertion never needs more than 2 rotations */
struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree)
{
	struct avltree_node *key, *parent, *unbalanced;
	int is_left;

	key = do_lookup(node, tree, &parent, &unbalanced, &is_left);
	if (key)
		return key;

	INIT_NODE(node);

	if (!parent) {
		tree->root = node;
		tree->first = tree->last = node;
		tree->height++;
		return NULL;
	}
	if (is_left) {
		if (parent == tree->first)
			tree->first = node;
	} else {
		if (parent == tree->last)
			tree->last = node;
	}
	set_parent(parent, node);
	set_child(node, parent, is_left);

	for (;;) {
		if (parent->left == node)
			dec_balance(parent);
		else
			inc_balance(parent);

		if (parent == unbalanced)
			break;
		node = parent;
		parent = get_parent(parent);
	}

	switch (get_balance(unbalanced)) {
	case  1: case -1:
		tree->height++;
		/* fall through */
	case 0:
		break;
	case 2: {
		struct avltree_node *right = unbalanced->right;

		if (get_balance(right) == 1) {
			set_balance(0, unbalanced);
			set_balance(0, right);
		} else {
			switch (get_balance(right->left)) {
			case 1:
				set_balance(-1, unbalanced);
				set_balance( 0, right);
				break;
			case 0:
				set_balance(0, unbalanced);
				set_balance(0, right);
				break;
			case -1:
				set_balance(0, unbalanced);
				set_balance(1, right);
				break;
			}
			set_balance(0, right->left);

			rotate_right(right, tree);
		}
		rotate_left(unbalanced, tree);
		break;
	}
	case -2: {
		struct avltree_node *left = unbalanced->left;

		if (get_balance(left) == -1) {
			set_balance(0, unbalanced);
			set_balance(0, left);
		} else {
			switch (get_balance(left->right)) {
			case 1:
				set_balance( 0, unbalanced);
				set_balance(-1, left);
				break;
			case 0:
				set_balance(0, unbalanced);
				set_balance(0, left);
				break;
			case -1:
				set_balance(1, unbalanced);
				set_balance(0, left);
				break;
			}
			set_balance(0, left->right);

			rotate_left(left, tree);
		}
		rotate_right(unbalanced, tree);
		break;
	}
	}
	return NULL;
}
Exemplo n.º 18
0
void bstree_remove(struct bstree_node *node, struct bstree *tree)
{
	struct bstree_node *left, *right, *next;
	struct bstree_node fake_parent, *parent;
	int is_left;

	do_lookup(node, tree, &parent, &is_left);

	if (!parent) {
		INIT_NODE(&fake_parent);
		parent = &fake_parent;
		is_left = 0;
	}
	left  = get_left(node);
	right = get_right(node);

	if (!left && !right) {
		if (is_left)
			set_prev(get_prev(node), parent);
		else
			set_next(get_next(node), parent);
		next = parent;
		goto update_first_last;
	}
	if (!left) {
		next = get_first(right);
		set_prev(get_prev(node), next);
		set_child(right, parent, is_left);
		goto update_first_last;
	}
	if (!right) {
		next = get_last(left);
		set_next(get_next(node), next);
		set_child(left, parent, is_left);
		goto update_first_last;
	}

	next = get_first(right);
	if (next != right) {
		/* 'm' is the parent of 'next' */
		struct bstree_node *m = get_next(get_last(next));

		if (get_right(next))
			set_left(get_right(next), m);
		else
			set_prev(next, m);

		set_right(right, next);
	}
	set_child(next, parent, is_left);
	set_left(left, next);
	set_next(next, get_last(left));
out:
	if (parent == &fake_parent)
		tree->root = get_right(parent);
	return;

update_first_last:
	if (node == tree->first)
		tree->first = next;
	if (node == tree->last)
		tree->last = next;
	goto out;
}
Exemplo n.º 19
0
/* Deletion might require up to log(n) rotations */
void avltree_remove(struct avltree_node *node, struct avltree *tree)
{
	struct avltree_node *parent = get_parent(node);
	struct avltree_node *left = node->left;
	struct avltree_node *right = node->right;
	struct avltree_node *next;
	int is_left = is_left;

	if (node == tree->first)
		tree->first = avltree_next(node);
	if (node == tree->last)
		tree->last = avltree_prev(node);

	if (!left)
		next = right;
	else if (!right)
		next = left;
	else
		next = get_first(right);

	if (parent) {
		is_left = parent->left == node;
		set_child(next, parent, is_left);
	} else
		tree->root = next;

	if (left && right) {
		set_balance(get_balance(node), next);

		next->left = left;
		set_parent(next, left);

		if (next != right) {
			parent = get_parent(next);
			set_parent(get_parent(node), next);

			node = next->right;
			parent->left = node;
			is_left = 1;

			next->right = right;
			set_parent(next, right);
		} else {
			set_parent(parent, next);
			parent = next;
			node = parent->right;
			is_left = 0;
		}
		assert(parent != NULL);
	} else
		node = next;

	if (node)
		set_parent(parent, node);

	/*
	 * At this point, 'parent' can only be null, if 'node' is the
	 * tree's root and has at most one child.
	 *
	 * case 1: the subtree is now balanced but its height has
	 * decreased.
	 *
	 * case 2: the subtree is mostly balanced and its height is
	 * unchanged.
	 *
	 * case 3: the subtree is unbalanced and its height may have
	 * been changed during the rebalancing process, see below.
	 *
	 * case 3.1: after a left rotation, the subtree becomes mostly
	 * balanced and its height is unchanged.
	 *
	 * case 3.2: after a left rotation, the subtree becomes
	 * balanced but its height has decreased.
	 *
	 * case 3.3: after a left and a right rotation, the subtree
	 * becomes balanced or mostly balanced but its height has
	 * decreased for all cases.
	 */
	while (parent) {
		int balance;
		node   = parent;
		parent = get_parent(parent);

		if (is_left) {
			is_left = parent && parent->left == node;

			balance = inc_balance(node);
			if (balance == 0)		/* case 1 */
				continue;
			if (balance == 1)		/* case 2 */
				return;
			right = node->right;		/* case 3 */
			switch (get_balance(right)) {
			case 0:				/* case 3.1 */
				set_balance( 1, node);
				set_balance(-1, right);
				rotate_left(node, tree);
				return;
			case 1:				/* case 3.2 */
				set_balance(0, node);
				set_balance(0, right);
				break;
			case -1:			/* case 3.3 */
				switch (get_balance(right->left)) {
				case 1:
					set_balance(-1, node);
					set_balance( 0, right);
					break;
				case 0:
					set_balance(0, node);
					set_balance(0, right);
					break;
				case -1:
					set_balance(0, node);
					set_balance(1, right);
					break;
				}
				set_balance(0, right->left);

				rotate_right(right, tree);
			}
			rotate_left(node, tree);
		} else {
			is_left = parent && parent->left == node;

			balance = dec_balance(node);
			if (balance == 0)
				continue;
			if (balance == -1)
				return;
			left = node->left;
			switch (get_balance(left)) {
			case 0:
				set_balance(-1, node);
				set_balance(1, left);
				rotate_right(node, tree);
				return;
			case -1:
				set_balance(0, node);
				set_balance(0, left);
				break;
			case 1:
				switch (get_balance(left->right)) {
				case 1:
					set_balance(0, node);
					set_balance(-1, left);
					break;
				case 0:
					set_balance(0, node);
					set_balance(0, left);
					break;
				case -1:
					set_balance(1, node);
					set_balance(0, left);
					break;
				}
				set_balance(0, left->right);

				rotate_left(left, tree);
			}
			rotate_right(node, tree);
		}
	}
	tree->height--;
}
Exemplo n.º 20
0
int fwAvlInsert(uint32_t key, void* data, struct FwAvlTree* tree)
{
    int is_left;
    struct FwAvlNode* parent;
    struct FwAvlNode* right;
    struct FwAvlNode* left;
    struct FwAvlNode* unbalanced;
    struct FwAvlNode* node;

    if(do_lookup(key, tree, &parent, &unbalanced, &is_left) != NULL)
        return 1;

    if(!(node = new_node(key, data)))
        return -1;

    tree->count++;
    if(parent == NULL)
    {
        tree->root = node;
        tree->first = node;
        tree->last = node;
        return 0;
    }

    if(is_left != 0)
    {
        if(parent == tree->first)
            tree->first = node;
    }
    else
    {
        if(parent == tree->last)
            tree->last = node;
    }
    set_parent(parent, node);
    set_child(node, parent, is_left);

    while(1)
    {
        if(parent->left == node)
            dec_balance(parent);
        else
            inc_balance(parent);

        if(parent == unbalanced)
            break;

        node = parent;
        parent = get_parent(node);
    }

    switch(get_balance(unbalanced))
    {
        case 1:
        case -1:
            tree->height++;
            break;
        case 0:
            break;
        case 2:
            right = unbalanced->right;

            if(get_balance(right) == 1)
            {
                set_balance(0, unbalanced);
                set_balance(0, right);
            }
            else
            {
                switch(get_balance(right->left))
                {
                    case 1:
                        set_balance(-1, unbalanced);
                        set_balance(0, right);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, right);
                        break;
                    case -1:
                        set_balance(0, unbalanced);
                        set_balance(1, right);
                        break;
                }
                set_balance(0, right->left);
                rotate_right(right, tree);
            }
            rotate_left(unbalanced, tree);
            break;
        case -2:
            left = unbalanced->left;

            if(get_balance(left) == -1)
            {
                set_balance(0, unbalanced);
                set_balance(0, left);
            }
            else
            {
                switch(get_balance(left->right))
                {
                    case 1:
                        set_balance(0, unbalanced);
                        set_balance(-1, left);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, left);
                        break;
                    case -1:
                        set_balance(1, unbalanced);
                        set_balance(0, left);
                        break;
                }
                set_balance(0, left->right);
                rotate_left(left, tree);
            }
            rotate_right(unbalanced, tree);
            break;
    }
    return 0;
}
Exemplo n.º 21
0
/* Insertion never needs more than 2 rotations */
struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree) {
    struct avltree_node *parent = 0, *unbalanced = tree->root;
    bool is_left;

    // Find a suitable parent.
    for (struct avltree_node *next_parent = tree->root; next_parent != 0;) {
        parent = next_parent;
        if (get_balance(parent) != 0)
            unbalanced = parent;
        int cmp_r = tree->cmp_fn(parent, node);
        if (cmp_r == 0) {
            if (tree->unique_index)
                return parent;
            // For non unique indexes any insert direction is acceptable.
            if (parent->left == 0) {
                is_left = true;
                break;
            } else if (parent->right == 0) {
                is_left = false;
                break;
            } else {
                // Be smart and travel to the least balanced subtree to minimize balancing overhead.
                next_parent = (get_balance(parent) <= 0)? parent->left: parent->right;
            }
        } else {
            is_left = (cmp_r > 0);
            next_parent = is_left? parent->left: parent->right;
        }
    }

    INIT_NODE(node);

    if (!parent) {
        tree->root = node;
        tree->first = tree->last = node;
        tree->height++;
        return 0;
    }
    if (is_left) {
        if (parent == tree->first)
            tree->first = node;
    } else {
        if (parent == tree->last)
            tree->last = node;
    }
    set_parent(parent, node);
    set_child(node, parent, is_left);

    for (;;) {
        if (parent->left == node)
            dec_balance(parent);
        else
            inc_balance(parent);

        if (parent == unbalanced) {
            for (;;) {
                node = parent;
                node->count++;
                if (is_root(node))
                    break;
                parent = get_parent(parent);
            }
            break;
        }
        node = parent;
        node->count++;
        parent = get_parent(parent);
    }

    switch (get_balance(unbalanced)) {
        case 1: case -1:
            tree->height++;
            /* fall through */
        case 0:
            break;
        case 2:
        {
            struct avltree_node *right = unbalanced->right;

            if (get_balance(right) == 1) {
                set_balance(0, unbalanced);
                set_balance(0, right);
            } else {
                switch (get_balance(right->left)) {
                    case 1:
                        set_balance(-1, unbalanced);
                        set_balance(0, right);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, right);
                        break;
                    case -1:
                        set_balance(0, unbalanced);
                        set_balance(1, right);
                        break;
                }
                set_balance(0, right->left);

                rotate_right(right, tree);
            }
            rotate_left(unbalanced, tree);
            break;
        }
        case -2:
        {
            struct avltree_node *left = unbalanced->left;

            if (get_balance(left) == -1) {
                set_balance(0, unbalanced);
                set_balance(0, left);
            } else {
                switch (get_balance(left->right)) {
                    case 1:
                        set_balance(0, unbalanced);
                        set_balance(-1, left);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, left);
                        break;
                    case -1:
                        set_balance(1, unbalanced);
                        set_balance(0, left);
                        break;
                }
                set_balance(0, left->right);

                rotate_left(left, tree);
            }
            rotate_right(unbalanced, tree);
            break;
        }
    }
    return 0;
}