Example #1
0
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
{
	struct rb_node		*left = node->rb_left;
	struct rb_node		*parent = rb_parent(node);

	if((node->rb_left = left->rb_right)) {
		rb_set_parent(left->rb_right, node);
	}
	left->rb_right = node;

	rb_set_parent(left, parent);

	if(parent) {
		if(node == parent->rb_right) {
			parent->rb_right = left;
		} else {
			parent->rb_left = left;
		}
	} else {
		root->rb_node = left;
	}

	rb_set_parent(node, left);

}
Example #2
0
static void rb_rotate_right(struct rb_node* x, struct rb_root* root)
{
    struct rb_node *y = x->left, *px = rb_parent(x);

    x->left = y->right;
    rb_set_parent(y, px);
    if (y->right)
        rb_set_parent(y->right, x);

    if (px) {
        if (x == px->left)
            px->left = y;
        else
            px->right = y;
    } else
        root->node = y;

    y->right = x;
    rb_set_parent(x, y);
}
Example #3
0
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
{
	struct rb_node *left = node->rb_left;
	struct rb_node *parent = rb_parent(node);

	node->rb_left = left->rb_right;
	if (node->rb_left)
		rb_set_parent(left->rb_right, node);
	left->rb_right = node;

	rb_set_parent(left, parent);

	if (parent) {
		if (node == parent->rb_right)
			parent->rb_right = left;
		else
			parent->rb_left = left;
	} else
		root->rb_node = left;
	rb_set_parent(node, left);
}
Example #4
0
static void rb_rotate_right(char *node, char **tree)
{
    char *p = node;
    char *q = rbtree_get_left(node); /* can't be NULL */
    char *parent = rb_get_parent(p);

    if (!rb_is_root(p)) {
        if (rbtree_get_left(parent) == p)
            rb_set_left(q, parent);
        else
            rb_set_right(q, parent);
    } else
        *tree = q;
    rb_set_parent(parent, q);
    rb_set_parent(q, p);

    rb_set_left(rbtree_get_right(q), p);
    if (rbtree_get_left(p))
        rb_set_parent(p, rbtree_get_left(p));
    rb_set_right(p, q);
}
Example #5
0
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
{
    struct rb_node *right = node->rb_right;
    struct rb_node *parent = rb_parent(node);

    if ((node->rb_right = right->rb_left))
        rb_set_parent(right->rb_left, node);
    right->rb_left = node;

    rb_set_parent(right, parent);

    if (parent) {
        if (node == parent->rb_left)
            parent->rb_left = right;
        else
            parent->rb_right = right;
    }
    else
        root->rb_node = right;
    rb_set_parent(node, right);
}
Example #6
0
static void __rb_rotate_right(LPRB_NODE node, LPRB_ROOT root)
{
	LPRB_NODE left = node->rb_left;
	LPRB_NODE parent = rb_parent(node);

	if ((node->rb_left = left->rb_right))
		rb_set_parent(left->rb_right, node);
	left->rb_right = node;

	rb_set_parent(left, parent);

	if (parent)
	{
		if (node == parent->rb_right)
			parent->rb_right = left;
		else
			parent->rb_left = left;
	}
	else
		root->rb_node = left;
	rb_set_parent(node, left);
}
Example #7
0
void rb_replace_node(struct rb_node *victim, struct rb_node *new_node,
		     struct rb_root *root)
{
	struct rb_node *parent = rb_parent(victim);

	/* Set the surrounding nodes to point to the replacement */
	if (parent) {
		if (victim == parent->rb_left)
			parent->rb_left = new_node;
		else
			parent->rb_right = new_node;
	} else {
		root->rb_node = new_node;
	}
	if (victim->rb_left)
		rb_set_parent(victim->rb_left, new_node);
	if (victim->rb_right)
		rb_set_parent(victim->rb_right, new_node);

	/* Copy the pointers/colour from the victim to the replacement */
	*new_node = *victim;
}
Example #8
0
void rb_erase(LPRB_NODE node, LPRB_ROOT root)
{
	LPRB_NODE child, parent;
	int color;

	if (!node->rb_left)
		child = node->rb_right;
	else if (!node->rb_right)
		child = node->rb_left;
	else
	{
		LPRB_NODE old = node, left;

		node = node->rb_right;
		while ((left = node->rb_left) != NULL)
			node = left;

		if (rb_parent(old)) {
			if (rb_parent(old)->rb_left == old)
				rb_parent(old)->rb_left = node;
			else
				rb_parent(old)->rb_right = node;
		} else
			root->rb_node = node;

		child = node->rb_right;
		parent = rb_parent(node);
		color = rb_color(node);

		if (parent == old) {
			parent = node;
		} else {
			if (child)
				rb_set_parent(child, parent);
			parent->rb_left = child;

			node->rb_right = old->rb_right;
			rb_set_parent(old->rb_right, node);
		}

		node->rb_parent_color = old->rb_parent_color;
		node->rb_left = old->rb_left;
		rb_set_parent(old->rb_left, node);

		goto color;
	}

	parent = rb_parent(node);
	color = rb_color(node);

	if (child)
		rb_set_parent(child, parent);
	if (parent)
	{
		if (parent->rb_left == node)
			parent->rb_left = child;
		else
			parent->rb_right = child;
	}
	else
		root->rb_node = child;

 color:
	if (color == RB_BLACK)
		__rb_erase_color(child, parent, root);
}
void rb_erase(struct rb_node *node, struct rb_root *root)
{
	struct rb_node *child, *parent;
	int color;

	if (!node->rb_left)
		child = node->rb_right;
	else if (!node->rb_right)
		child = node->rb_left;
	else
	{
		struct rb_node *old = node, *left;

		node = node->rb_right;
		while ((left = node->rb_left) != NULL)
			node = left;
		child = node->rb_right;
		parent = rb_parent(node);
		color = rb_color(node);

		if (child)
			rb_set_parent(child, parent);
		if (parent == old) {
			parent->rb_right = child;
			parent = node;
		} else
			parent->rb_left = child;

		node->rb_parent_color = old->rb_parent_color;
		node->rb_right = old->rb_right;
		node->rb_left = old->rb_left;

		if (rb_parent(old))
		{
			if (rb_parent(old)->rb_left == old)
				rb_parent(old)->rb_left = node;
			else
				rb_parent(old)->rb_right = node;
		} else
			root->rb_node = node;

		rb_set_parent(old->rb_left, node);
		if (old->rb_right)
			rb_set_parent(old->rb_right, node);
		goto color;
	}

	parent = rb_parent(node);
	color = rb_color(node);

	if (child)
		rb_set_parent(child, parent);
	if (parent)
	{
		if (parent->rb_left == node)
			parent->rb_left = child;
		else
			parent->rb_right = child;
	}
	else
		root->rb_node = child;

 color:
	if (color == RB_BLACK)
		__rb_erase_color(child, parent, root);
}
Example #10
0
void rb_erase(struct rb_node *node, struct rb_root *root)
{
	struct rb_node *child, *parent;
	int color;
	
	struct mytype *mytype;

	mytype = container_of(node, struct mytype, node);
 		
	if (!node->rb_left)
		child = node->rb_right;
	else if (!node->rb_right)
		child = node->rb_left;
	else
	{
		struct rb_node *old = node, *left;

		node = node->rb_right;
		while ((left = node->rb_left) != NULL)
			node = left;

		if (rb_parent(old)) {
			if (rb_parent(old)->rb_left == old)
				rb_parent(old)->rb_left = node;
			else
				rb_parent(old)->rb_right = node;
		} else
			root->rb_node = node;

		child = node->rb_right;
		parent = rb_parent(node);
		color = rb_color(node);

		if (parent == old) {
			parent = node;
		} else {
			if (child)
				rb_set_parent(child, parent);
			parent->rb_left = child;

			node->rb_right = old->rb_right;
			rb_set_parent(old->rb_right, node);
		}

		node->rb_parent_color = old->rb_parent_color;
		node->rb_left = old->rb_left;
		rb_set_parent(old->rb_left, node);

		goto color;
	}

	parent = rb_parent(node);
	color = rb_color(node);

	if (child)
		rb_set_parent(child, parent);
	if (parent)
	{
		if (parent->rb_left == node)
			parent->rb_left = child;
		else
			parent->rb_right = child;
	}
	else
		root->rb_node = child;

 color:  
 	
	if (color == RB_BLACK)
	{
		pr_debug("delete value = %02d, ", mytype->keyvalue);
		__rb_erase_color(child, parent, root);
		
	}
	else 
	{
		pr_debug("delete value = %02d, 对应情况X。\n", mytype->keyvalue);
	}
}
Example #11
0
static void rbtree_remove(char *node, char **tree)
{
    char *parent = rb_get_parent(node);
    char *left = rbtree_get_left(node);
    char *right = rbtree_get_right(node);
    char *next;
    int color;

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

    if (parent)
        rb_set_child(next, parent, rbtree_get_left(parent) == node);
    else
        *tree = next;

    if (left && right) {
        color = rb_get_color(next);
        rb_set_color(rb_get_color(node), next);

        rb_set_left(left, next);
        rb_set_parent(next, left);

        if (next != right) {
            parent = rb_get_parent(next);
            rb_set_parent(rb_get_parent(node), next);

            node = rbtree_get_right(next);
            rb_set_left(node, parent);

            rb_set_right(right, next);
            rb_set_parent(next, right);
        } else {
            rb_set_parent(parent, next);
            parent = next;
            node = rbtree_get_right(next);
        }
    } else {
        color = rb_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)
        rb_set_parent(parent, node);

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

    do {
        if (node == *tree)
            break;

        if (node == rbtree_get_left(parent)) {
            char *sibling = rbtree_get_right(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_left(parent, tree);
                sibling = rbtree_get_right(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_left(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_right(sibling, tree);
                sibling = rbtree_get_right(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_right(sibling));
            rb_rotate_left(parent, tree);
            node = *tree;
            break;
        } else {
            char *sibling = rbtree_get_left(parent);

            if (rb_is_red(sibling)) {
                rb_set_color(RB_BLACK, sibling);
                rb_set_color(RB_RED, parent);
                rb_rotate_right(parent, tree);
                sibling = rbtree_get_left(parent);
            }
            if ((!rbtree_get_left(sibling)  || rb_is_black(rbtree_get_left(sibling))) &&
                (!rbtree_get_right(sibling) || rb_is_black(rbtree_get_right(sibling)))) {
                rb_set_color(RB_RED, sibling);
                node = parent;
                parent = rb_get_parent(parent);
                continue;
            }
            if (!rbtree_get_left(sibling) || rb_is_black(rbtree_get_left(sibling))) {
                rb_set_color(RB_BLACK, rbtree_get_right(sibling));
                rb_set_color(RB_RED, sibling);
                rb_rotate_left(sibling, tree);
                sibling = rbtree_get_left(parent);
            }
            rb_set_color(rb_get_color(parent), sibling);
            rb_set_color(RB_BLACK, parent);
            rb_set_color(RB_BLACK, rbtree_get_left(sibling));
            rb_rotate_right(parent, tree);
            node = *tree;
            break;
        }
    } while (rb_is_black(node));

    if (node)
        rb_set_color(RB_BLACK, node);
}
Example #12
0
static char *rbtree_insert(char *node, char **tree)
{
    char *key, *parent;
    int is_left;

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

    rb_set_left(NULL, node);
    rb_set_right(NULL, node);
    rb_set_color(RB_RED, node);
    rb_set_parent(parent, node);

    if (parent) {
        rb_set_child(node, parent, is_left);
    } else {
        *tree = node;
    }

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

        if (parent == rbtree_get_left(grandpa)) {
            char *uncle = rbtree_get_right(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_right(parent)) {
                    rb_rotate_left(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_right(grandpa, tree);
            }
        } else {
            char *uncle = rbtree_get_left(grandpa);

            if (uncle && rb_is_red(uncle)) {
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_BLACK, uncle);
                rb_set_color(RB_RED, grandpa);
                node = grandpa;
            } else {
                if (node == rbtree_get_left(parent)) {
                    rb_rotate_right(parent, tree);
                    node = parent;
                    parent = rb_get_parent(node);
                }
                rb_set_color(RB_BLACK, parent);
                rb_set_color(RB_RED, grandpa);
                rb_rotate_left(grandpa, tree);
            }
        }
    }
    rb_set_color(RB_BLACK, *tree);
    return NULL;
}
Example #13
0
void rb_delete(struct rb_node* node, struct rb_root* root)
{
    int color;
    struct rb_node *parent, *child = NULL;

    if (node->left && node->right) {
        struct rb_node* old = node;
        struct rb_node* old_parent = rb_parent(node);

        node = node->right;
        while (node->left)
            node = node->left;

        if (old_parent) {
            if (old == old_parent->left)
                old_parent->left = node;
            else
                old_parent->right = node;
        } else
            root->node = node;

        child = node->right;
        parent = rb_parent(node);
        color = rb_color(node);

        if (parent == old)
            parent = node;
        else {
            if (child)
                rb_set_parent(child, parent);
            parent->left = child;

            node->right = old->right;
            rb_set_parent(old->right, node);
        }

        node->parent_color = old->parent_color;
        node->left = old->left;
        rb_set_parent(old->left, node);

        goto rebalance;
    }

    if (!node->left)
        child = node->right;
    else
        child = node->left;

    parent = rb_parent(node);
    color = rb_color(node);

    if (child)
        rb_set_parent(child, parent);

    if (parent) {
        if (node == parent->left)
            parent->left = child;
        else
            parent->right = child;
    } else
        root->node = child;

rebalance:
    if (color == RB_BLACK)
        rb_delete_rebalance(child, parent, root);
}
Example #14
0
static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
					struct jffs2_inode_info *f,
					struct jffs2_raw_inode *latest_node)
{
	struct jffs2_tmp_dnode_info *tn;
	struct rb_root tn_list;
	struct rb_node *rb, *repl_rb;
	struct jffs2_full_dirent *fd_list;
	struct jffs2_full_dnode *fn, *first_fn = NULL;
	uint32_t crc;
	uint32_t latest_mctime, mctime_ver;
	size_t retlen;
	int ret;

	dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);

	/* Grab all nodes relevant to this ino */
	ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);

	if (ret) {
		JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
		if (f->inocache->state == INO_STATE_READING)
			jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
		return ret;
	}
	f->dents = fd_list;

	rb = rb_first(&tn_list);

	while (rb) {
		cond_resched();
		tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
		fn = tn->fn;
		ret = 1;
		dbg_readinode("consider node ver %u, phys offset "
			"%#08x(%d), range %u-%u.\n", tn->version,
			ref_offset(fn->raw), ref_flags(fn->raw),
			fn->ofs, fn->ofs + fn->size);

		if (fn->size) {
			ret = jffs2_add_older_frag_to_fragtree(c, f, tn);
			/* TODO: the error code isn't checked, check it */
			jffs2_dbg_fragtree_paranoia_check_nolock(f);
			BUG_ON(ret < 0);
			if (!first_fn && ret == 0)
				first_fn = fn;
		} else if (!first_fn) {
			first_fn = fn;
			f->metadata = fn;
			ret = 0; /* Prevent freeing the metadata update node */
		} else
			jffs2_mark_node_obsolete(c, fn->raw);

		BUG_ON(rb->rb_left);
		if (rb_parent(rb) && rb_parent(rb)->rb_left == rb) {
			/* We were then left-hand child of our parent. We need
			 * to move our own right-hand child into our place. */
			repl_rb = rb->rb_right;
			if (repl_rb)
				rb_set_parent(repl_rb, rb_parent(rb));
		} else
			repl_rb = NULL;

		rb = rb_next(rb);

		/* Remove the spent tn from the tree; don't bother rebalancing
		 * but put our right-hand child in our own place. */
		if (rb_parent(&tn->rb)) {
			if (rb_parent(&tn->rb)->rb_left == &tn->rb)
				rb_parent(&tn->rb)->rb_left = repl_rb;
			else if (rb_parent(&tn->rb)->rb_right == &tn->rb)
				rb_parent(&tn->rb)->rb_right = repl_rb;
			else BUG();
		} else if (tn->rb.rb_right)
			rb_set_parent(tn->rb.rb_right, NULL);

		jffs2_free_tmp_dnode_info(tn);
		if (ret) {
			dbg_readinode("delete dnode %u-%u.\n",
				fn->ofs, fn->ofs + fn->size);
			jffs2_free_full_dnode(fn);
		}
	}
	jffs2_dbg_fragtree_paranoia_check_nolock(f);

	BUG_ON(first_fn && ref_obsolete(first_fn->raw));

	fn = first_fn;
	if (unlikely(!first_fn)) {
		/* No data nodes for this inode. */
		if (f->inocache->ino != 1) {
			JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);
			if (!fd_list) {
				if (f->inocache->state == INO_STATE_READING)
					jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
				return -EIO;
			}
			JFFS2_NOTICE("but it has children so we fake some modes for it\n");
		}
		latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
		latest_node->version = cpu_to_je32(0);
		latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
		latest_node->isize = cpu_to_je32(0);
		latest_node->gid = cpu_to_je16(0);
		latest_node->uid = cpu_to_je16(0);
		if (f->inocache->state == INO_STATE_READING)
			jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
		return 0;
	}

	ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
	if (ret || retlen != sizeof(*latest_node)) {
		JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
			ret, retlen, sizeof(*latest_node));
		/* FIXME: If this fails, there seems to be a memory leak. Find it. */
		up(&f->sem);
		jffs2_do_clear_inode(c, f);
		return ret?ret:-EIO;
	}

	crc = crc32(0, latest_node, sizeof(*latest_node)-8);
	if (crc != je32_to_cpu(latest_node->node_crc)) {
		JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
			f->inocache->ino, ref_offset(fn->raw));
		up(&f->sem);
		jffs2_do_clear_inode(c, f);
		return -EIO;
	}

	switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
	case S_IFDIR:
		if (mctime_ver > je32_to_cpu(latest_node->version)) {
			/* The times in the latest_node are actually older than
			   mctime in the latest dirent. Cheat. */
			latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
		}
		break;


	case S_IFREG:
		/* If it was a regular file, truncate it to the latest node's isize */
		jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
		break;

	case S_IFLNK:
		/* Hack to work around broken isize in old symlink code.
		   Remove this when dwmw2 comes to his senses and stops
		   symlinks from being an entirely gratuitous special
		   case. */
		if (!je32_to_cpu(latest_node->isize))
			latest_node->isize = latest_node->dsize;

		if (f->inocache->state != INO_STATE_CHECKING) {
			/* Symlink's inode data is the target path. Read it and
			 * keep in RAM to facilitate quick follow symlink
			 * operation. */
			f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
			if (!f->target) {
				JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
				up(&f->sem);
				jffs2_do_clear_inode(c, f);
				return -ENOMEM;
			}

			ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
						je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);

			if (ret  || retlen != je32_to_cpu(latest_node->csize)) {
				if (retlen != je32_to_cpu(latest_node->csize))
					ret = -EIO;
				kfree(f->target);
				f->target = NULL;
				up(&f->sem);
				jffs2_do_clear_inode(c, f);
				return -ret;
			}

			f->target[je32_to_cpu(latest_node->csize)] = '\0';
			dbg_readinode("symlink's target '%s' cached\n", f->target);
		}

		/* fall through... */

	case S_IFBLK:
	case S_IFCHR:
		/* Certain inode types should have only one data node, and it's
		   kept as the metadata node */
		if (f->metadata) {
			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
			up(&f->sem);
			jffs2_do_clear_inode(c, f);
			return -EIO;
		}
		if (!frag_first(&f->fragtree)) {
			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
			up(&f->sem);
			jffs2_do_clear_inode(c, f);
			return -EIO;
		}
		/* ASSERT: f->fraglist != NULL */
		if (frag_next(frag_first(&f->fragtree))) {
			JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
			up(&f->sem);
			jffs2_do_clear_inode(c, f);
			return -EIO;
		}
		/* OK. We're happy */
		f->metadata = frag_first(&f->fragtree)->node;
		jffs2_free_node_frag(frag_first(&f->fragtree));
		f->fragtree = RB_ROOT;
		break;
	}
	if (f->inocache->state == INO_STATE_READING)
		jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);

	return 0;
}
Example #15
0
/* 
 * 删除结点
 *
 * 参数说明:
 *     tree 红黑树的根结点
 *     node 删除的结点
 */
void rbtree_delete(RBRoot *root, Node *node)
{
    Node *child, *parent;
    int color;

	//                  tree
	//                 /    \
	//                       dnode
	//                      /     \
	//                   left      right
	//                            /     \
	//                        replace    right

    // 被删除节点的"左右孩子都不为空"的情况。
    if ( (node->left!=NULL) && (node->right!=NULL) ) 
    {
        // 被删节点的后继节点。(称为"取代节点")
        // 用它来取代"被删节点"的位置,然后再将"被删节点"去掉。
        Node *replace = node;

        // 获取后继节点
        replace = replace->right;
        while (replace->left != NULL)
            replace = replace->left;

        // "node节点"不是根节点(只有根节点不存在父节点)
        if (rb_parent(node))
        {
            if (rb_parent(node)->left == node)
                rb_parent(node)->left = replace;
            else
                rb_parent(node)->right = replace;
        } 
        else 
            // "node节点"是根节点,更新根节点。
            root->node = replace;

        // child是"取代节点"的右孩子,也是需要"调整的节点"。
        // "取代节点"肯定不存在左孩子!因为它是一个后继节点。
        child = replace->right;
        parent = rb_parent(replace);
        // 保存"取代节点"的颜色
        color = rb_color(replace);

        // "被删除节点"是"它的后继节点的父节点"
        if (parent == node)
        {
            parent = replace;
        } 
        else
        {
            // child不为空
            if (child)
                rb_set_parent(child, parent);
            parent->left = child;

            replace->right = node->right;
            rb_set_parent(node->right, replace);
        }

        replace->parent = node->parent;
        replace->color = node->color;
        replace->left = node->left;
        node->left->parent = replace;

        if (color == BLACK)
            rbtree_delete_fixup(root, child, parent);
        free(node);

        return ;
    }

    if (node->left !=NULL)
        child = node->left;
    else 
        child = node->right;

    parent = node->parent;
    // 保存"取代节点"的颜色
    color = node->color;

    if (child)
        child->parent = parent;

    // "node节点"不是根节点
    if (parent)
    {
        if (parent->left == node)
            parent->left = child;
        else
            parent->right = child;
    }
    else
        root->node = child;

    if (color == BLACK)
        rbtree_delete_fixup(root, child, parent);
    free(node);
}