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]); } }
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]); } }
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; }
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(); }
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; }
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); }
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; }
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; }
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); }
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; }
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; }
/** * 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); }
/* 插入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; }
/* 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; }
/* 删除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; }
/** * 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; }
/* 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; }
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; }
/* 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--; }
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; }
/* 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; }