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 |