diff options
| author | Michel Lespinasse <walken@google.com> | 2012-10-08 19:31:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:35 -0400 |
| commit | 59633abf34e2f44b8e772a2c12a92132aa7c2220 (patch) | |
| tree | 3a260a6100ae2c3e2dbade989c3692234081f1c7 /lib | |
| parent | 7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0 (diff) | |
rbtree: optimize fetching of sibling node
When looking to fetch a node's sibling, we went through a sequence of:
- check if node is the parent's left child
- if it is, then fetch the parent's right child
This can be replaced with:
- fetch the parent's right child as an assumed sibling
- check that node is NOT the fetched child
This avoids fetching the parent's left child when node is actually
that child. Saves a bit on code size, though it doesn't seem to make
a large difference in speed.
Signed-off-by: Michel Lespinasse <walken@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Rik van Riel <riel@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Daniel Santos <daniel.santos@pobox.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/rbtree.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/lib/rbtree.c b/lib/rbtree.c index 08926709b4f9..61cdd0e3e538 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
| @@ -107,8 +107,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 107 | 107 | ||
| 108 | gparent = rb_red_parent(parent); | 108 | gparent = rb_red_parent(parent); |
| 109 | 109 | ||
| 110 | if (parent == gparent->rb_left) { | 110 | tmp = gparent->rb_right; |
| 111 | tmp = gparent->rb_right; | 111 | if (parent != tmp) { /* parent == gparent->rb_left */ |
| 112 | if (tmp && rb_is_red(tmp)) { | 112 | if (tmp && rb_is_red(tmp)) { |
| 113 | /* | 113 | /* |
| 114 | * Case 1 - color flips | 114 | * Case 1 - color flips |
| @@ -131,7 +131,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 131 | continue; | 131 | continue; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (parent->rb_right == node) { | 134 | tmp = parent->rb_right; |
| 135 | if (node == tmp) { | ||
| 135 | /* | 136 | /* |
| 136 | * Case 2 - left rotate at parent | 137 | * Case 2 - left rotate at parent |
| 137 | * | 138 | * |
| @@ -151,6 +152,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 151 | RB_BLACK); | 152 | RB_BLACK); |
| 152 | rb_set_parent_color(parent, node, RB_RED); | 153 | rb_set_parent_color(parent, node, RB_RED); |
| 153 | parent = node; | 154 | parent = node; |
| 155 | tmp = node->rb_right; | ||
| 154 | } | 156 | } |
| 155 | 157 | ||
| 156 | /* | 158 | /* |
| @@ -162,7 +164,7 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 162 | * / \ | 164 | * / \ |
| 163 | * n U | 165 | * n U |
| 164 | */ | 166 | */ |
| 165 | gparent->rb_left = tmp = parent->rb_right; | 167 | gparent->rb_left = tmp; /* == parent->rb_right */ |
| 166 | parent->rb_right = gparent; | 168 | parent->rb_right = gparent; |
| 167 | if (tmp) | 169 | if (tmp) |
| 168 | rb_set_parent_color(tmp, gparent, RB_BLACK); | 170 | rb_set_parent_color(tmp, gparent, RB_BLACK); |
| @@ -180,7 +182,8 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 180 | continue; | 182 | continue; |
| 181 | } | 183 | } |
| 182 | 184 | ||
| 183 | if (parent->rb_left == node) { | 185 | tmp = parent->rb_left; |
| 186 | if (node == tmp) { | ||
| 184 | /* Case 2 - right rotate at parent */ | 187 | /* Case 2 - right rotate at parent */ |
| 185 | parent->rb_left = tmp = node->rb_right; | 188 | parent->rb_left = tmp = node->rb_right; |
| 186 | node->rb_right = parent; | 189 | node->rb_right = parent; |
| @@ -189,10 +192,11 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root) | |||
| 189 | RB_BLACK); | 192 | RB_BLACK); |
| 190 | rb_set_parent_color(parent, node, RB_RED); | 193 | rb_set_parent_color(parent, node, RB_RED); |
| 191 | parent = node; | 194 | parent = node; |
| 195 | tmp = node->rb_left; | ||
| 192 | } | 196 | } |
| 193 | 197 | ||
| 194 | /* Case 3 - left rotate at gparent */ | 198 | /* Case 3 - left rotate at gparent */ |
| 195 | gparent->rb_right = tmp = parent->rb_left; | 199 | gparent->rb_right = tmp; /* == parent->rb_left */ |
| 196 | parent->rb_left = gparent; | 200 | parent->rb_left = gparent; |
| 197 | if (tmp) | 201 | if (tmp) |
| 198 | rb_set_parent_color(tmp, gparent, RB_BLACK); | 202 | rb_set_parent_color(tmp, gparent, RB_BLACK); |
| @@ -223,8 +227,9 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, | |||
| 223 | break; | 227 | break; |
| 224 | } else if (!parent) { | 228 | } else if (!parent) { |
| 225 | break; | 229 | break; |
| 226 | } else if (parent->rb_left == node) { | 230 | } |
| 227 | sibling = parent->rb_right; | 231 | sibling = parent->rb_right; |
| 232 | if (node != sibling) { /* node == parent->rb_left */ | ||
| 228 | if (rb_is_red(sibling)) { | 233 | if (rb_is_red(sibling)) { |
| 229 | /* | 234 | /* |
| 230 | * Case 1 - left rotate at parent | 235 | * Case 1 - left rotate at parent |
