Skip to content

Commit

Permalink
rbtree: move some implementation details from rbtree.h to rbtree.c
Browse files Browse the repository at this point in the history
rbtree users must use the documented APIs to manipulate the tree
structure.  Low-level helpers to manipulate node colors and parenthood are
not part of that API, so move them to lib/rbtree.c

[[email protected]: fix jffs2 build issue due to renamed __rb_parent_color field]
Signed-off-by: Michel Lespinasse <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Acked-by: David Woodhouse <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Daniel Santos <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
walken-google authored and torvalds committed Oct 9, 2012
1 parent ea5272f commit bf7ad8e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 31 deletions.
13 changes: 8 additions & 5 deletions fs/jffs2/readinode.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,11 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
}

/* Trivial function to remove the last node in the tree. Which by definition
has no right-hand -- so can be removed just by making its only child (if
any) take its place under its parent. */
has no right-hand child — so can be removed just by making its left-hand
child (if any) take its place under its parent. Since this is only done
when we're consuming the whole tree, there's no need to use rb_erase()
and let it worry about adjusting colours and balancing the tree. That
would just be a waste of time. */
static void eat_last(struct rb_root *root, struct rb_node *node)
{
struct rb_node *parent = rb_parent(node);
Expand All @@ -412,12 +415,12 @@ static void eat_last(struct rb_root *root, struct rb_node *node)
link = &parent->rb_right;

*link = node->rb_left;
/* Colour doesn't matter now. Only the parent pointer. */
if (node->rb_left)
node->rb_left->rb_parent_color = node->rb_parent_color;
node->rb_left->__rb_parent_color = node->__rb_parent_color;
}

/* We put this in reverse order, so we can just use eat_last */
/* We put the version tree in reverse order, so we can use the same eat_last()
function that we use to consume the tmpnode tree (tn_root). */
static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn)
{
struct rb_node **link = &ver_root->rb_node;
Expand Down
34 changes: 9 additions & 25 deletions include/linux/rbtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,46 +32,30 @@
#include <linux/kernel.h>
#include <linux/stddef.h>

struct rb_node
{
unsigned long rb_parent_color;
#define RB_RED 0
#define RB_BLACK 1
struct rb_node {
unsigned long __rb_parent_color;
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */

struct rb_root
{
struct rb_root {
struct rb_node *rb_node;
};


#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
#define rb_color(r) ((r)->rb_parent_color & 1)
#define rb_is_red(r) (!rb_color(r))
#define rb_is_black(r) rb_color(r)
#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)

static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
}
static inline void rb_set_color(struct rb_node *rb, int color)
{
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
}
#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))

#define RB_ROOT (struct rb_root) { NULL, }
#define rb_entry(ptr, type, member) container_of(ptr, type, member)

#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)

/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
#define RB_EMPTY_NODE(node) ((node)->rb_parent_color == (unsigned long)(node))
#define RB_CLEAR_NODE(node) ((node)->rb_parent_color = (unsigned long)(node))
#define RB_EMPTY_NODE(node) \
((node)->__rb_parent_color == (unsigned long)(node))
#define RB_CLEAR_NODE(node) \
((node)->__rb_parent_color = (unsigned long)(node))


extern void rb_insert_color(struct rb_node *, struct rb_root *);
Expand All @@ -98,7 +82,7 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
struct rb_node ** rb_link)
{
node->rb_parent_color = (unsigned long )parent;
node->__rb_parent_color = (unsigned long)parent;
node->rb_left = node->rb_right = NULL;

*rb_link = node;
Expand Down
20 changes: 19 additions & 1 deletion lib/rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@
#include <linux/rbtree.h>
#include <linux/export.h>

#define RB_RED 0
#define RB_BLACK 1

#define rb_color(r) ((r)->__rb_parent_color & 1)
#define rb_is_red(r) (!rb_color(r))
#define rb_is_black(r) rb_color(r)
#define rb_set_red(r) do { (r)->__rb_parent_color &= ~1; } while (0)
#define rb_set_black(r) do { (r)->__rb_parent_color |= 1; } while (0)

static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
}
static inline void rb_set_color(struct rb_node *rb, int color)
{
rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
}

static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
{
struct rb_node *right = node->rb_right;
Expand Down Expand Up @@ -255,7 +273,7 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
rb_set_parent(old->rb_right, node);
}

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

Expand Down

0 comments on commit bf7ad8e

Please sign in to comment.