aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rbtree.c
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2012-10-08 19:31:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 03:22:35 -0400
commit59633abf34e2f44b8e772a2c12a92132aa7c2220 (patch)
tree3a260a6100ae2c3e2dbade989c3692234081f1c7 /lib/rbtree.c
parent7ce6ff9e5de99e7b72019c7de82fb438fe1dc5a0 (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/rbtree.c')
-rw-r--r--lib/rbtree.c21
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