/*
 * Recreate the addr tree of vm_map in local memory.
 */
struct vm_map_entry *
load_vm_map_entries(kvm_t *kd, struct vm_map_entry *kptr,
    struct vm_map_entry *parent)
{
	static struct kbit map_ent;
	struct vm_map_entry *result;

	if (kptr == NULL)
		return NULL;

	A(&map_ent) = (u_long)kptr;
	S(&map_ent) = sizeof(struct vm_map_entry);
	KDEREF(kd, &map_ent);

	result = malloc(sizeof(*result));
	if (result == NULL)
		err(1, "malloc");
	memcpy(result, D(&map_ent, vm_map_entry), sizeof(struct vm_map_entry));

	/*
	 * Recurse to download rest of the tree.
	 */
	RB_LEFT(result, daddrs.addr_entry) = load_vm_map_entries(kd,
	    RB_LEFT(result, daddrs.addr_entry), result);
	RB_RIGHT(result, daddrs.addr_entry) = load_vm_map_entries(kd,
	    RB_RIGHT(result, daddrs.addr_entry), result);
	RB_PARENT(result, daddrs.addr_entry) = parent;
	return result;
}
示例#2
0
/*
 * rb_print_preorder - print nodes of Red-black tree in preorder
 */
static void rb_print_preorder(){
    printf("rb_print_preorder() called\n");
    if(RB_LEFT(rb_root) == rb_null){
        printf("empty\n");
    }else{
        rb_print_preorder_impl(RB_LEFT(rb_root));
    }
}
示例#3
0
/*
 * rb_fix - restore properties of Red-black tree after deleting
 */
static void rb_fix(void *node){
    void *root, *sib;
    root = RB_LEFT(rb_root);
    while(!RB_RED(node) && node != root){
        if(node == RB_LEFT(RB_PARENT(node))){
            sib = RB_RIGHT(RB_PARENT(node));
            if(RB_RED(sib)){
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(node)) = 1;
                rb_rotate_left(RB_PARENT(node));
                sib = RB_RIGHT(RB_PARENT(node));
            }
            if(!RB_RED(RB_RIGHT(sib)) && !RB_RED(RB_LEFT(sib))){
                RB_RED(sib) = 1;
                node = RB_PARENT(node);
            }else{
                if(!RB_RED(RB_RIGHT(sib))){
                    RB_RED(RB_LEFT(sib)) = 0;
                    RB_RED(sib) = 1;
                    rb_rotate_right(sib);
                    sib = RB_RIGHT(RB_PARENT(node));
                }
                RB_RED(sib) = RB_RED(RB_PARENT(node));
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_RIGHT(sib)) = 0;
                rb_rotate_left(RB_PARENT(node));
                node = root;
            }
        }else{
            sib = RB_LEFT(RB_PARENT(node));
            if(RB_RED(sib)){
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(node)) = 1;
                rb_rotate_right(RB_PARENT(node));
                sib = RB_LEFT(RB_PARENT(node));
            }
            if(!RB_RED(RB_RIGHT(sib)) && !RB_RED(RB_LEFT(sib))){
                RB_RED(sib) = 1;
                node = RB_PARENT(node);
            }else{
                if(!RB_RED(RB_LEFT(sib))){
                    RB_RED(RB_RIGHT(sib)) = 0;
                    RB_RED(sib) = 1;
                    rb_rotate_left(sib);
                    sib = RB_LEFT(RB_PARENT(node));
                }
                RB_RED(sib) = RB_RED(RB_PARENT(node));
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_LEFT(sib)) = 0;
                rb_rotate_right(RB_PARENT(node));
                node = root;
            }
        }
        
    }
    RB_RED(node) = 0;
}
示例#4
0
/*
 * rb_print_preorder_impl - recursion implementation of rb_print_preorder
 */
static void rb_print_preorder_impl(void *node){
    if(RB_LEFT(node) != rb_null){
        rb_print_preorder_impl(RB_LEFT(node));
    }
    printf("%p : %u\n", node, CUR_SIZE_MASKED(node));
    if(RB_RIGHT(node) != rb_null){
        rb_print_preorder_impl(RB_RIGHT(node));
    }
}
示例#5
0
/*
 * rb_find - find the smallest free block which is bigger than or equal to size.
 */
static void* rb_find(size_t size){
    void *node = RB_LEFT(rb_root), *best = rb_null;
    while(node != rb_null){
        if(CUR_SIZE_MASKED(node) < size){
            node = RB_RIGHT(node);
        }else{
            best = node;
            node = RB_LEFT(node);
        }
    }
    return best;
}
示例#6
0
static struct ttm_buffer_object *ttm_bo_vm_lookup_rb(struct ttm_bo_device *bdev,
						     unsigned long page_start,
						     unsigned long num_pages)
{
	unsigned long cur_offset;
	struct ttm_buffer_object *bo;
	struct ttm_buffer_object *best_bo = NULL;

	bo = RB_ROOT(&bdev->addr_space_rb);
	while (bo != NULL) {
		cur_offset = bo->vm_node->start;
		if (page_start >= cur_offset) {
			best_bo = bo;
			if (page_start == cur_offset)
				break;
			bo = RB_RIGHT(bo, vm_rb);
		} else
			bo = RB_LEFT(bo, vm_rb);
	}

	if (unlikely(best_bo == NULL))
		return NULL;

	if (unlikely((best_bo->vm_node->start + best_bo->num_pages) <
		     (page_start + num_pages)))
		return NULL;

	return best_bo;
}
示例#7
0
boolean_t vm_map_store_lookup_entry_rb( vm_map_t map, vm_map_offset_t address, vm_map_entry_t *vm_entry)
{
	struct vm_map_header hdr = map->hdr;
	struct vm_map_store *rb_entry = RB_ROOT(&(hdr.rb_head_store));
	vm_map_entry_t cur = vm_map_to_entry(map);
	vm_map_entry_t prev = VM_MAP_ENTRY_NULL;

	while (rb_entry != (struct vm_map_store*)NULL) {
       		cur =  VME_FOR_STORE(rb_entry);
		if(cur == VM_MAP_ENTRY_NULL)
			panic("no entry");
		if (address >= cur->vme_start) {
			if (address < cur->vme_end) {
				*vm_entry = cur;
				return TRUE;
			}
			rb_entry = RB_RIGHT(rb_entry, entry);
			prev = cur;
		} else {
			rb_entry = RB_LEFT(rb_entry, entry);
		}
	}
	if( prev == VM_MAP_ENTRY_NULL){
		prev = vm_map_to_entry(map);
	}
	*vm_entry = prev;
	return FALSE;
}
示例#8
0
/*
 * rb_rotate_right - rotate node and children of node to the right
 */
static void rb_rotate_right(void *node){
    void *left;

    left = RB_LEFT(node);
    RB_LEFT(node) = RB_RIGHT(left);
    if(RB_RIGHT(left) != rb_null)
        RB_PARENT(RB_RIGHT(left)) = node;

    RB_PARENT(left) = RB_PARENT(node);
    if(node == RB_LEFT(RB_PARENT(node))){
        RB_LEFT(RB_PARENT(node)) = left;
    }else{
        RB_RIGHT(RB_PARENT(node)) = left;
    }
    RB_RIGHT(left) = node;
    RB_PARENT(node) = left;
}
示例#9
0
/*
 * rb_check_preorder_impl - recursion implementation of rb_check_preorder
 */
static int rb_check_preorder_impl(void *node){
    if(RB_LEFT(node) != rb_null){
        if(!rb_check_preorder_impl(RB_LEFT(node))){
            return 0;
        }
    }
    if(!CUR_FREE(node)){
        printf("%p is in Red-black tree, but is not free block.\n", node);
        return 0;
    }
    if(RB_RIGHT(node) != rb_null){
        if(!rb_check_preorder_impl(RB_RIGHT(node))){
            return 0;
        }
    }
    return 1;
}
示例#10
0
/*
 * The algorithm is from
 *	I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline
 *  First: A Flexible and Accurate Mechanism for Proportional Share
 *  Resource Allocation,'' technical report.
 *
 *  http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf
 *
 *  - Partition the tree into two parts by ve:
 *  - One part contains nodes with ve smaller than vtime
 *  - The other part contains nodes with ve larger than vtime
 *  - In the first part, find the node with minimum vd, along the
 *    min_vd value path
 *
 *  Returns
 *	NULL, if no node with ve smaller than vtime
 *	or the elegible node with minimum vd.
 */
static struct bfq_thread_io *
wf2q_augtree_get_eligible_with_min_vd(struct wf2q_augtree_t *tree, int vtime)
{
	struct bfq_thread_io *node = RB_ROOT(tree), *st_tree = NULL, *path_req = NULL;
	while (node) {
		if (node->ve <= vtime) {
			/* update node with earliest deadline along path. */
			if ((!path_req) || (path_req->vd > node->vd))
				path_req = node;
			/* update root of subtree containing earliest deadline */
			if ((!st_tree) || (RB_LEFT(node,entry) && st_tree->min_vd > RB_LEFT(node,entry)->min_vd))
				st_tree = RB_LEFT(node,entry);
			node = RB_RIGHT(node, entry);
		} else
			node = RB_LEFT(node, entry);
	}
	/* check whether node with earliest deadline was along path */
	if ((!st_tree) || (st_tree->min_vd >= path_req->vd))
		return path_req;
	/* return node with earliest deadline from subtree */
	for (node = st_tree; node; ) {
		/* if node found, return it */
		if (st_tree->min_vd == node->vd)
			return node;
		/* XXX: modified temporarily */
		if (RB_LEFT(node, entry) && node->min_vd == RB_LEFT(node, entry)->min_vd)
			node = RB_LEFT(node, entry);
		else
			node = RB_RIGHT(node, entry);
	}
	return NULL;
}
/*
 * Release the addr tree of vm_map.
 */
void
unload_vm_map_entries(struct vm_map_entry *ent)
{
	if (ent == NULL)
		return;

	unload_vm_map_entries(RB_LEFT(ent, daddrs.addr_entry));
	unload_vm_map_entries(RB_RIGHT(ent, daddrs.addr_entry));
	free(ent);
}
示例#12
0
struct rb_node *rb_prev(struct rb_node *elm)
{
	if (RB_LEFT(elm)) {
		elm = RB_LEFT(elm);
		while (RB_RIGHT(elm))
			elm = RB_RIGHT(elm);
	} else {
		if (RB_PARENT(elm) &&
		    (elm == RB_RIGHT(RB_PARENT(elm))))
			elm = RB_PARENT(elm);
		else {
			while (RB_PARENT(elm) &&
			    (elm == RB_LEFT(RB_PARENT(elm))))
				elm = RB_PARENT(elm);
			elm = RB_PARENT(elm);
		}
	}
	return (elm);
}
示例#13
0
/*
 * rb_find_exact - check whether block is in Red-black tree or not.
 */
static int rb_find_exact(void *block){
    void *node = RB_LEFT(rb_root);
    while(node != rb_null){
        if(node == block){
            return 1;
        }else if(CUR_SIZE_MASKED(node) > CUR_SIZE_MASKED(block)){
            node = RB_LEFT(node);
        }else if(CUR_SIZE_MASKED(node) == CUR_SIZE_MASKED(block)){
            if(node > block){
                node = RB_LEFT(node);
            }else{
                node = RB_RIGHT(node);
            }
        }else{
            node = RB_RIGHT(node);
        }
    }
    return 0;
}
示例#14
0
/* Note args swapped to match Linux */
void rb_insert_color(struct rb_node *elm, struct rb_root *head)
{
	struct rb_node *parent, *gparent, *tmp;
	while ((parent = RB_PARENT(elm)) &&
	    RB_COLOR(parent) == RB_RED) {
		gparent = RB_PARENT(parent);
		if (parent == RB_LEFT(gparent)) {
			tmp = RB_RIGHT(gparent);
			if (tmp && RB_COLOR(tmp) == RB_RED) {
				RB_COLOR(tmp) = RB_BLACK;
				RB_SET_BLACKRED(parent, gparent);
				elm = gparent;
				continue;
			}
			if (RB_RIGHT(parent) == elm) {
				RB_ROTATE_LEFT(head, parent, tmp);
				tmp = parent;
				parent = elm;
				elm = tmp;
			}
			RB_SET_BLACKRED(parent, gparent);
			RB_ROTATE_RIGHT(head, gparent, tmp);
		} else {
			tmp = RB_LEFT(gparent);
			if (tmp && RB_COLOR(tmp) == RB_RED) {
				RB_COLOR(tmp) = RB_BLACK;
				RB_SET_BLACKRED(parent, gparent);
				elm = gparent;
				continue;
			}
			if (RB_LEFT(parent) == elm) {
				RB_ROTATE_RIGHT(head, parent, tmp);
				tmp = parent;
				parent = elm;
				elm = tmp;
			}
			RB_SET_BLACKRED(parent, gparent);
			RB_ROTATE_LEFT(head, gparent, tmp);
		}
	}
	RB_COLOR(head->rb_node) = RB_BLACK;
}
示例#15
0
static void
wf2q_tree_dump(struct bfq_thread_io *root, int level)
{
	int i;
	if (!root) return;
	for (i = 0; i < level; i++)
		kprintf("-");
	kprintf("vd: %d; ve: %d; min_vd: %d\n", root->vd, root->ve, root->min_vd);
	wf2q_tree_dump(RB_LEFT(root,entry), level + 1);
	wf2q_tree_dump(RB_RIGHT(root, entry), level + 1);
}
示例#16
0
void vm_map_store_walk_rb( vm_map_t map, vm_map_entry_t *wrong_vme, vm_map_entry_t *vm_entry)
{
	struct vm_map_header hdr = map->hdr;
	struct vm_map_store *rb_entry = RB_ROOT(&(hdr.rb_head_store));
	vm_map_entry_t cur = *vm_entry;

	rb_entry = RB_FIND( rb_head, &(hdr.rb_head_store), &(cur->store));	
	if(rb_entry == NULL)
		panic("NO SUCH ENTRY %p. Gave back %p", *vm_entry, *wrong_vme);
	else
		panic("Cur: %p, L: %p, R: %p",  VME_FOR_STORE(rb_entry),  VME_FOR_STORE(RB_LEFT(rb_entry,entry)),  VME_FOR_STORE(RB_RIGHT(rb_entry,entry)));
}
示例#17
0
static void
wf2q_augment_func(struct bfq_thread_io *node)
{
	struct bfq_thread_io *tmp = node, *tmp2;
	int min_vd;
	do{
		min_vd = tmp->vd;
		tmp2 = RB_LEFT(tmp, entry);
		min_vd = tmp2 ? MIN(tmp2->min_vd, min_vd) : min_vd;
		tmp2 = RB_RIGHT(tmp, entry);
		min_vd = tmp2 ? MIN(tmp2->min_vd, min_vd) : min_vd;
		tmp->min_vd = min_vd;
	}while((tmp = RB_PARENT(tmp,entry)));
}
示例#18
0
/*
 * mm_init - initialize the malloc package.
 */
int mm_init(range_t **ranges)
{
    /* allocate root and nil nodes */
    if((rb_root = rb_null = mem_sbrk(4 + MIN_BLOCK_SIZE)) == FAIL) return -1;
    /* assign sentinel values */
    RB_LEFT(rb_root) = RB_RIGHT(rb_root) = rb_null;
    RB_RED(rb_root) = 0;
    /* prevent coalesce by setting free bit to 0*/
    PREV_SIZE(NEXT_BLOCK(rb_null, MIN_BLOCK_SIZE)) = 0;

    /* DON't MODIFY THIS STAGE AND LEAVE IT AS IT WAS */
    gl_ranges = ranges;

    return 0;
}
示例#19
0
/*
 * rb_successor - find the next node of node in ascending order.
 */
static void* rb_successor(void *node){
    void *succ, *left;
    if((succ = RB_RIGHT(node)) != rb_null){
        while((left = RB_LEFT(succ)) != rb_null){
            succ = left;
        }
        return succ;
    }else{
        succ = RB_PARENT(node);
        while(RB_RIGHT(succ) == node){
            node = succ;
            succ = RB_PARENT(succ);
        }
        if(succ == rb_root) return rb_null;
        return succ;
    }
}
示例#20
0
struct ieee80211_node *
ieee80211_find_node(struct ieee80211com *ic, const u_int8_t *macaddr)
{
	struct ieee80211_node *ni;
	int cmp;

	/* similar to RB_FIND except we compare keys, not nodes */
	ni = RB_ROOT(&ic->ic_tree);
	while (ni != NULL) {
		cmp = memcmp(macaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN);
		if (cmp < 0)
			ni = RB_LEFT(ni, ni_node);
		else if (cmp > 0)
			ni = RB_RIGHT(ni, ni_node);
		else
			break;
	}
	return ni;
}
示例#21
0
/*
 * rb_rotate_left - rotate node and children of node to the left
 */
static void rb_rotate_left(void *node){
    void *right;

    right = RB_RIGHT(node);
    RB_RIGHT(node) = RB_LEFT(right);
    if(RB_LEFT(right) != rb_null)
        RB_PARENT(RB_LEFT(right)) = node;

    RB_PARENT(right) = RB_PARENT(node);
    if(node == RB_LEFT(RB_PARENT(node))){
        RB_LEFT(RB_PARENT(node)) = right;
    }else{
        RB_RIGHT(RB_PARENT(node)) = right;
    }
    RB_LEFT(right) = node;
    RB_PARENT(node) = right;
}
示例#22
0
/**
 * Find next route in the table. There is no such RB_ macro, so must
 * dig into the innards of the RB stuff.
 */
static struct sroute *
sroute_getnext(struct asn_oid *oid, u_int sub)
{
	u_int i;
	int comp;
	struct sroute key;
	struct sroute *best;
	struct sroute *s;

	/*
	 * We now, that the OID is at least the tableEntry OID. If it is,
	 * the user wants the first route.
	 */
	if (oid->len == sub)
		return (RB_MIN(sroutes, &sroutes));

	/*
	 * This is also true for any index that consists of zeros and is
	 * shorter than the full index.
	 */
	if (oid->len < sub + 13) {
		for (i = sub; i < oid->len; i++)
			if (oid->subs[i] != 0)
				break;
		if (i == oid->len)
			return (RB_MIN(sroutes, &sroutes));

		/*
		 * Now if the index is too short, we fill it with zeros and then
		 * subtract one from the index. We can do this, because we now,
		 * that there is at least one index element that is not zero.
		 */
		for (i = oid->len; i < sub + 13; i++)
			oid->subs[i] = 0;

		for (i = sub + 13 - 1; i >= sub; i--) {
			if (oid->subs[i] != 0) {
				oid->subs[i]--;
				break;
			}
			oid->subs[i] = ASN_MAXID;
		}
		oid->len = sub + 13;
	}

	/* build the index */
	for (i = sub; i < sub + 13; i++)
		key.index[i - sub] = oid->subs[i];

	/* now find the element */
	best = NULL;
	s = RB_ROOT(&sroutes);

	while (s != NULL) {
		comp = sroute_compare(&key, s);
		if (comp >= 0) {
			/* The current element is smaller than what we search.
			 * Forget about it and move to the right subtree. */
			s = RB_RIGHT(s, link);
			continue;
		}
		/* the current element is larger than what we search.
		 * forget about the right subtree (its even larger), but
		 * the current element may be what we need. */
		if (best == NULL || sroute_compare(s, best) < 0)
			/* this one's better */
			best = s;

		s = RB_LEFT(s, link);
	}
	return (best);
}
示例#23
0
/*
 * rb_check_preorder
 *
 * return 0 if there exists allocated block in Red-black tree, 1 otherwise.
 */
static int rb_check_preorder(){
    if(RB_LEFT(rb_root) != rb_null){
        return rb_check_preorder_impl(RB_LEFT(rb_root));
    }
    return 1;
}
示例#24
0
static void rb_remove_color(struct rb_root *head, struct rb_node *parent,
			    struct rb_node *elm) {
	struct rb_node *tmp;
	while ((elm == NULL || RB_COLOR(elm) == RB_BLACK) &&
	    elm != RB_HEAD(head)) {
		if (RB_LEFT(parent) == elm) {
			tmp = RB_RIGHT(parent);
			if (RB_COLOR(tmp) == RB_RED) {
				RB_SET_BLACKRED(tmp, parent);
				RB_ROTATE_LEFT(head, parent, tmp);
				tmp = RB_RIGHT(parent);
			}
			if ((RB_LEFT(tmp) == NULL ||
			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
			    (RB_RIGHT(tmp) == NULL ||
			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
				RB_COLOR(tmp) = RB_RED;
				elm = parent;
				parent = RB_PARENT(elm);
			} else {
				if (RB_RIGHT(tmp) == NULL ||
				    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK) {
					struct rb_node *oleft;
					if ((oleft = RB_LEFT(tmp)))
						RB_COLOR(oleft) = RB_BLACK;
					RB_COLOR(tmp) = RB_RED;
					RB_ROTATE_RIGHT(head, tmp, oleft);
					tmp = RB_RIGHT(parent);
				}
				RB_COLOR(tmp) = RB_COLOR(parent);
				RB_COLOR(parent) = RB_BLACK;
				if (RB_RIGHT(tmp))
					RB_COLOR(RB_RIGHT(tmp)) = RB_BLACK;
				RB_ROTATE_LEFT(head, parent, tmp);
				elm = RB_HEAD(head);
				break;
			}
		} else {
			tmp = RB_LEFT(parent);
			if (RB_COLOR(tmp) == RB_RED) {
				RB_SET_BLACKRED(tmp, parent);
				RB_ROTATE_RIGHT(head, parent, tmp);
				tmp = RB_LEFT(parent);
			}
			if ((RB_LEFT(tmp) == NULL ||
			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
			    (RB_RIGHT(tmp) == NULL ||
			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
				RB_COLOR(tmp) = RB_RED;
				elm = parent;
				parent = RB_PARENT(elm);
			} else {
				if (RB_LEFT(tmp) == NULL ||
				    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) {
					struct rb_node *oright;
					if ((oright = RB_RIGHT(tmp)))
						RB_COLOR(oright) = RB_BLACK;
					RB_COLOR(tmp) = RB_RED;
					RB_ROTATE_LEFT(head, tmp, oright);
					tmp = RB_LEFT(parent);
				}
				RB_COLOR(tmp) = RB_COLOR(parent);
				RB_COLOR(parent) = RB_BLACK;
				if (RB_LEFT(tmp))
					RB_COLOR(RB_LEFT(tmp)) = RB_BLACK;
				RB_ROTATE_RIGHT(head, parent, tmp);
				elm = RB_HEAD(head);
				break;
			}
		}
	}
	if (elm)
		RB_COLOR(elm) = RB_BLACK;
}
示例#25
0
/*
 * rb_insert - insert node into Red-black tree
 */
static void rb_insert(void *node){
    void *parent, *child, *sib;

    RB_LEFT(node) = RB_RIGHT(node) = rb_null;
    parent = rb_root;
    child = RB_LEFT(rb_root);
    while(child != rb_null){
        parent = child;
        if(CUR_SIZE_MASKED(child) > CUR_SIZE_MASKED(node)){
            child = RB_LEFT(child);
        }else if(CUR_SIZE_MASKED(child) == CUR_SIZE_MASKED(node)){
            if(child > node){
                child = RB_LEFT(child);
            }else{
                child = RB_RIGHT(child);
            }
        }else{
            child = RB_RIGHT(child);
        }
    }
    RB_PARENT(node) = parent;
    if(parent == rb_root || CUR_SIZE_MASKED(parent) > CUR_SIZE_MASKED(node)){
        RB_LEFT(parent) = node;
    }else if(CUR_SIZE_MASKED(parent) == CUR_SIZE_MASKED(node)){
        if(parent > node){
            RB_LEFT(parent) = node;
        }else{
            RB_RIGHT(parent) = node;
        }
    }else{
        RB_RIGHT(parent) = node;
    }

    RB_RED(node) = 1;
    while(RB_RED(RB_PARENT(node))){
        if(RB_PARENT(node) == RB_LEFT(RB_PARENT(RB_PARENT(node)))){
            sib = RB_RIGHT(RB_PARENT(RB_PARENT(node)));
            if(RB_RED(sib)){
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                node = RB_PARENT(RB_PARENT(node));
            }else{
                if(node == RB_RIGHT(RB_PARENT(node))){
                    node = RB_PARENT(node);
                    rb_rotate_left(node);
                }
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                rb_rotate_right(RB_PARENT(RB_PARENT(node)));
            }
        }else{
            sib = RB_LEFT(RB_PARENT(RB_PARENT(node)));
            if(RB_RED(sib)){
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(sib) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                node = RB_PARENT(RB_PARENT(node));
            }else{
                if(node == RB_LEFT(RB_PARENT(node))){
                    node = RB_PARENT(node);
                    rb_rotate_right(node);
                }
                RB_RED(RB_PARENT(node)) = 0;
                RB_RED(RB_PARENT(RB_PARENT(node))) = 1;
                rb_rotate_left(RB_PARENT(RB_PARENT(node)));
            }
        }
    }
    RB_RED(RB_LEFT(rb_root)) = 0;
}
示例#26
0
/*
 * rb_delete - delete node from Red-black tree
 */
static void rb_delete(void *node){
    void *m, *c;
    m = RB_LEFT(node) == rb_null || RB_RIGHT(node) == rb_null ? node : rb_successor(node);
    c = RB_LEFT(m) == rb_null ? RB_RIGHT(m) : RB_LEFT(m);
    if((RB_PARENT(c) = RB_PARENT(m)) == rb_root){
        RB_LEFT(rb_root) = c;
    }else{
        if(RB_LEFT(RB_PARENT(m)) == m){
            RB_LEFT(RB_PARENT(m)) = c;
        }else{
            RB_RIGHT(RB_PARENT(m)) = c;
        }
    }
    if(m != node){
        if(!RB_RED(m)) rb_fix(c);
        RB_LEFT(m) = RB_LEFT(node);
        RB_RIGHT(m) = RB_RIGHT(node);
        RB_PARENT(m) = RB_PARENT(node);
        RB_RED(m) = RB_RED(node);
        RB_PARENT(RB_LEFT(node)) = RB_PARENT(RB_RIGHT(node)) = m;
        if(node == RB_LEFT(RB_PARENT(node))){
            RB_LEFT(RB_PARENT(node)) = m;
        }else{
            RB_RIGHT(RB_PARENT(node)) = m;
        }
    }else{
        if(!RB_RED(m)) rb_fix(c);
    }
}
示例#27
0
/* Note name changed. Guess why :) */
void rb_erase(struct rb_node *elm, struct rb_root *head) {
	struct rb_node *child, *parent, *old = elm;
	int color;
	if (RB_LEFT(elm) == NULL) {
		child = RB_RIGHT(elm);
	} else if (RB_RIGHT(elm) == NULL) {
		child = RB_LEFT(elm);
	} else {
		struct rb_node *left;
		elm = RB_RIGHT(elm);
		while ((left = RB_LEFT(elm))) {
			elm = left;
		}
		child = RB_RIGHT(elm);
		parent = RB_PARENT(elm);
		color = RB_COLOR(elm);
		if (child) {
			RB_PARENT(child) = parent;
		}
		if (parent) {
			if (RB_LEFT(parent) == elm) {
				RB_LEFT(parent) = child;
			} else {
				RB_RIGHT(parent) = child;
			}
			RB_AUGMENT(parent);
		} else {
			RB_HEAD(head) = child;
		}
		if (RB_PARENT(elm) == old) {
			parent = elm;
		}
		*(elm) = *(old);
		if (RB_PARENT(old)) {
			if (RB_LEFT(RB_PARENT(old)) == old) {
				RB_LEFT(RB_PARENT(old)) = elm;
			} else {
				RB_RIGHT(RB_PARENT(old)) = elm;
			}
			RB_AUGMENT(RB_PARENT(old));
		} else {
			RB_HEAD(head) = elm;
		}
		RB_PARENT(RB_LEFT(old)) = elm;
		if (RB_RIGHT(old)) {
			RB_PARENT(RB_RIGHT(old)) = elm;
		}
		if (parent) {
			left = parent;
			do {
				RB_AUGMENT(left);
			} while ((left = RB_PARENT(left)));
		}
		goto color;
	}
	parent = RB_PARENT(elm);
	color = RB_COLOR(elm);
	if (child) {
		RB_PARENT(child) = parent;
	}
	if (parent) {
		if (RB_LEFT(parent) == elm) {
			RB_LEFT(parent) = child;
		} else {
			RB_RIGHT(parent) = child;
		}
		RB_AUGMENT(parent);
	} else {
		RB_HEAD(head) = child;
	}
color:
	if (color == RB_BLACK) {
		rb_remove_color(head, parent, child);
	}
}