Blame view

lib/rbtree.c 18.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
    Red Black Trees
    (C) 1999  Andrea Arcangeli <andrea@suse.de>
    (C) 2002  David Woodhouse <dwmw2@infradead.org>
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
5
    (C) 2012  Michel Lespinasse <walken@google.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
  
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
  
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  
    linux/lib/rbtree.c
  */
9c079add0   Michel Lespinasse   rbtree: move augm...
22
  #include <linux/rbtree_augmented.h>
8bc3bcc93   Paul Gortmaker   lib: reduce the u...
23
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24

5bc9188aa   Michel Lespinasse   rbtree: low level...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  /*
   * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
   *
   *  1) A node is either red or black
   *  2) The root is black
   *  3) All leaves (NULL) are black
   *  4) Both children of every red node are black
   *  5) Every simple path from root to leaves contains the same number
   *     of black nodes.
   *
   *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
   *  consecutive red nodes in a path and every red node is therefore followed by
   *  a black. So if B is the number of black nodes on every simple path (as per
   *  5), then the longest possible path due to 4 is 2B.
   *
   *  We shall indicate color with case, where black nodes are uppercase and red
6280d2356   Michel Lespinasse   rbtree: low level...
41
42
   *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
   *  parentheses and have some accompanying text comment.
5bc9188aa   Michel Lespinasse   rbtree: low level...
43
   */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  /*
   * Notes on lockless lookups:
   *
   * All stores to the tree structure (rb_left and rb_right) must be done using
   * WRITE_ONCE(). And we must not inadvertently cause (temporary) loops in the
   * tree structure as seen in program order.
   *
   * These two requirements will allow lockless iteration of the tree -- not
   * correct iteration mind you, tree rotations are not atomic so a lookup might
   * miss entire subtrees.
   *
   * But they do guarantee that any such traversal will only see valid elements
   * and that it will indeed complete -- does not get stuck in a loop.
   *
   * It also guarantees that if the lookup returns an element it is the 'correct'
   * one. But not returning an element does _NOT_ mean it's not present.
   *
   * NOTE:
   *
   * Stores to __rb_parent_color are not important for simple lookups so those
   * are left undone as of now. Nor did I check for loops involving parent
   * pointers.
   */
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
67
68
69
70
  static inline void rb_set_black(struct rb_node *rb)
  {
  	rb->__rb_parent_color |= RB_BLACK;
  }
5bc9188aa   Michel Lespinasse   rbtree: low level...
71
72
73
74
  static inline struct rb_node *rb_red_parent(struct rb_node *red)
  {
  	return (struct rb_node *)red->__rb_parent_color;
  }
5bc9188aa   Michel Lespinasse   rbtree: low level...
75
76
77
78
79
80
81
82
83
84
85
86
  /*
   * Helper function for rotations:
   * - old's parent and color get assigned to new
   * - old gets assigned new as a parent and 'color' as a color.
   */
  static inline void
  __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
  			struct rb_root *root, int color)
  {
  	struct rb_node *parent = rb_parent(old);
  	new->__rb_parent_color = old->__rb_parent_color;
  	rb_set_parent_color(old, new, color);
7abc704ae   Michel Lespinasse   rbtree: add __rb_...
87
  	__rb_change_child(old, new, parent, root);
5bc9188aa   Michel Lespinasse   rbtree: low level...
88
  }
14b94af0b   Michel Lespinasse   rbtree: faster au...
89
90
  static __always_inline void
  __rb_insert(struct rb_node *node, struct rb_root *root,
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
91
  	    bool newleft, struct rb_node **leftmost,
14b94af0b   Michel Lespinasse   rbtree: faster au...
92
  	    void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  {
5bc9188aa   Michel Lespinasse   rbtree: low level...
94
  	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
96
97
  	if (newleft)
  		*leftmost = node;
6d58452dc   Michel Lespinasse   rbtree: adjust ro...
98
99
  	while (true) {
  		/*
2aadf7fc7   Davidlohr Bueso   rbtree: optimize ...
100
  		 * Loop invariant: node is red.
6d58452dc   Michel Lespinasse   rbtree: adjust ro...
101
  		 */
2aadf7fc7   Davidlohr Bueso   rbtree: optimize ...
102
103
104
105
106
107
  		if (unlikely(!parent)) {
  			/*
  			 * The inserted node is root. Either this is the
  			 * first node, or we recursed at Case 1 below and
  			 * are no longer violating 4).
  			 */
5bc9188aa   Michel Lespinasse   rbtree: low level...
108
  			rb_set_parent_color(node, NULL, RB_BLACK);
6d58452dc   Michel Lespinasse   rbtree: adjust ro...
109
  			break;
2aadf7fc7   Davidlohr Bueso   rbtree: optimize ...
110
111
112
113
114
115
116
117
118
  		}
  
  		/*
  		 * If there is a black parent, we are done.
  		 * Otherwise, take some corrective action as,
  		 * per 4), we don't want a red root or two
  		 * consecutive red nodes.
  		 */
  		if(rb_is_black(parent))
6d58452dc   Michel Lespinasse   rbtree: adjust ro...
119
  			break;
5bc9188aa   Michel Lespinasse   rbtree: low level...
120
  		gparent = rb_red_parent(parent);
59633abf3   Michel Lespinasse   rbtree: optimize ...
121
122
  		tmp = gparent->rb_right;
  		if (parent != tmp) {	/* parent == gparent->rb_left */
5bc9188aa   Michel Lespinasse   rbtree: low level...
123
124
  			if (tmp && rb_is_red(tmp)) {
  				/*
35dc67d7d   Davidlohr Bueso   rbtree: add some ...
125
  				 * Case 1 - node's uncle is red (color flips).
5bc9188aa   Michel Lespinasse   rbtree: low level...
126
127
128
129
130
  				 *
  				 *       G            g
  				 *      / \          / \
  				 *     p   u  -->   P   U
  				 *    /            /
1b9c53e84   Wei Yang   lib/rbtree.c: fix...
131
  				 *   n            n
5bc9188aa   Michel Lespinasse   rbtree: low level...
132
133
134
135
136
137
138
139
140
141
142
  				 *
  				 * However, since g's parent might be red, and
  				 * 4) does not allow this, we need to recurse
  				 * at g.
  				 */
  				rb_set_parent_color(tmp, gparent, RB_BLACK);
  				rb_set_parent_color(parent, gparent, RB_BLACK);
  				node = gparent;
  				parent = rb_parent(node);
  				rb_set_parent_color(node, parent, RB_RED);
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  			}
59633abf3   Michel Lespinasse   rbtree: optimize ...
144
145
  			tmp = parent->rb_right;
  			if (node == tmp) {
5bc9188aa   Michel Lespinasse   rbtree: low level...
146
  				/*
35dc67d7d   Davidlohr Bueso   rbtree: add some ...
147
148
  				 * Case 2 - node's uncle is black and node is
  				 * the parent's right child (left rotate at parent).
5bc9188aa   Michel Lespinasse   rbtree: low level...
149
150
151
152
153
154
155
156
157
158
  				 *
  				 *      G             G
  				 *     / \           / \
  				 *    p   U  -->    n   U
  				 *     \           /
  				 *      n         p
  				 *
  				 * This still leaves us in violation of 4), the
  				 * continuation into Case 3 will fix that.
  				 */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
159
160
161
  				tmp = node->rb_left;
  				WRITE_ONCE(parent->rb_right, tmp);
  				WRITE_ONCE(node->rb_left, parent);
5bc9188aa   Michel Lespinasse   rbtree: low level...
162
163
164
165
  				if (tmp)
  					rb_set_parent_color(tmp, parent,
  							    RB_BLACK);
  				rb_set_parent_color(parent, node, RB_RED);
14b94af0b   Michel Lespinasse   rbtree: faster au...
166
  				augment_rotate(parent, node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
  				parent = node;
59633abf3   Michel Lespinasse   rbtree: optimize ...
168
  				tmp = node->rb_right;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  			}
5bc9188aa   Michel Lespinasse   rbtree: low level...
170
  			/*
35dc67d7d   Davidlohr Bueso   rbtree: add some ...
171
172
  			 * Case 3 - node's uncle is black and node is
  			 * the parent's left child (right rotate at gparent).
5bc9188aa   Michel Lespinasse   rbtree: low level...
173
174
175
176
177
178
179
  			 *
  			 *        G           P
  			 *       / \         / \
  			 *      p   U  -->  n   g
  			 *     /                 \
  			 *    n                   U
  			 */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
180
181
  			WRITE_ONCE(gparent->rb_left, tmp); /* == parent->rb_right */
  			WRITE_ONCE(parent->rb_right, gparent);
5bc9188aa   Michel Lespinasse   rbtree: low level...
182
183
184
  			if (tmp)
  				rb_set_parent_color(tmp, gparent, RB_BLACK);
  			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
14b94af0b   Michel Lespinasse   rbtree: faster au...
185
  			augment_rotate(gparent, parent);
1f0528653   Michel Lespinasse   rbtree: break out...
186
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
  		} else {
5bc9188aa   Michel Lespinasse   rbtree: low level...
188
189
190
191
192
193
194
195
196
  			tmp = gparent->rb_left;
  			if (tmp && rb_is_red(tmp)) {
  				/* Case 1 - color flips */
  				rb_set_parent_color(tmp, gparent, RB_BLACK);
  				rb_set_parent_color(parent, gparent, RB_BLACK);
  				node = gparent;
  				parent = rb_parent(node);
  				rb_set_parent_color(node, parent, RB_RED);
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
  			}
59633abf3   Michel Lespinasse   rbtree: optimize ...
198
199
  			tmp = parent->rb_left;
  			if (node == tmp) {
5bc9188aa   Michel Lespinasse   rbtree: low level...
200
  				/* Case 2 - right rotate at parent */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
201
202
203
  				tmp = node->rb_right;
  				WRITE_ONCE(parent->rb_left, tmp);
  				WRITE_ONCE(node->rb_right, parent);
5bc9188aa   Michel Lespinasse   rbtree: low level...
204
205
206
207
  				if (tmp)
  					rb_set_parent_color(tmp, parent,
  							    RB_BLACK);
  				rb_set_parent_color(parent, node, RB_RED);
14b94af0b   Michel Lespinasse   rbtree: faster au...
208
  				augment_rotate(parent, node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  				parent = node;
59633abf3   Michel Lespinasse   rbtree: optimize ...
210
  				tmp = node->rb_left;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  			}
5bc9188aa   Michel Lespinasse   rbtree: low level...
212
  			/* Case 3 - left rotate at gparent */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
213
214
  			WRITE_ONCE(gparent->rb_right, tmp); /* == parent->rb_left */
  			WRITE_ONCE(parent->rb_left, gparent);
5bc9188aa   Michel Lespinasse   rbtree: low level...
215
216
217
  			if (tmp)
  				rb_set_parent_color(tmp, gparent, RB_BLACK);
  			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
14b94af0b   Michel Lespinasse   rbtree: faster au...
218
  			augment_rotate(gparent, parent);
1f0528653   Michel Lespinasse   rbtree: break out...
219
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223

3cb7a5634   Michel Lespinasse   lib/rbtree.c: avo...
224
225
226
227
228
229
  /*
   * Inline version for rb_erase() use - we want to be able to inline
   * and eliminate the dummy_rotate callback there
   */
  static __always_inline void
  ____rb_erase_color(struct rb_node *parent, struct rb_root *root,
9c079add0   Michel Lespinasse   rbtree: move augm...
230
  	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  {
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
232
  	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233

d6ff12739   Michel Lespinasse   rbtree: adjust no...
234
235
  	while (true) {
  		/*
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
236
237
238
239
240
  		 * Loop invariants:
  		 * - node is black (or NULL on first iteration)
  		 * - node is not the root (parent is not NULL)
  		 * - All leaf paths going through parent and node have a
  		 *   black node count that is 1 lower than other leaf paths.
d6ff12739   Michel Lespinasse   rbtree: adjust no...
241
  		 */
59633abf3   Michel Lespinasse   rbtree: optimize ...
242
243
  		sibling = parent->rb_right;
  		if (node != sibling) {	/* node == parent->rb_left */
6280d2356   Michel Lespinasse   rbtree: low level...
244
245
246
247
248
249
250
251
252
253
  			if (rb_is_red(sibling)) {
  				/*
  				 * Case 1 - left rotate at parent
  				 *
  				 *     P               S
  				 *    / \             / \
  				 *   N   s    -->    p   Sr
  				 *      / \         / \
  				 *     Sl  Sr      N   Sl
  				 */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
254
255
256
  				tmp1 = sibling->rb_left;
  				WRITE_ONCE(parent->rb_right, tmp1);
  				WRITE_ONCE(sibling->rb_left, parent);
6280d2356   Michel Lespinasse   rbtree: low level...
257
258
259
  				rb_set_parent_color(tmp1, parent, RB_BLACK);
  				__rb_rotate_set_parents(parent, sibling, root,
  							RB_RED);
9c079add0   Michel Lespinasse   rbtree: move augm...
260
  				augment_rotate(parent, sibling);
6280d2356   Michel Lespinasse   rbtree: low level...
261
  				sibling = tmp1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  			}
6280d2356   Michel Lespinasse   rbtree: low level...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  			tmp1 = sibling->rb_right;
  			if (!tmp1 || rb_is_black(tmp1)) {
  				tmp2 = sibling->rb_left;
  				if (!tmp2 || rb_is_black(tmp2)) {
  					/*
  					 * Case 2 - sibling color flip
  					 * (p could be either color here)
  					 *
  					 *    (p)           (p)
  					 *    / \           / \
  					 *   N   S    -->  N   s
  					 *      / \           / \
  					 *     Sl  Sr        Sl  Sr
  					 *
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
277
278
279
280
  					 * This leaves us violating 5) which
  					 * can be fixed by flipping p to black
  					 * if it was red, or by recursing at p.
  					 * p is red when coming from Case 1.
6280d2356   Michel Lespinasse   rbtree: low level...
281
282
283
  					 */
  					rb_set_parent_color(sibling, parent,
  							    RB_RED);
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
284
285
286
287
288
289
290
291
292
  					if (rb_is_red(parent))
  						rb_set_black(parent);
  					else {
  						node = parent;
  						parent = rb_parent(node);
  						if (parent)
  							continue;
  					}
  					break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
  				}
6280d2356   Michel Lespinasse   rbtree: low level...
294
295
296
297
298
299
  				/*
  				 * Case 3 - right rotate at sibling
  				 * (p could be either color here)
  				 *
  				 *   (p)           (p)
  				 *   / \           / \
ce093a045   Jie Chen   lib/rbtree.c: fix...
300
  				 *  N   S    -->  N   sl
6280d2356   Michel Lespinasse   rbtree: low level...
301
  				 *     / \             \
ce093a045   Jie Chen   lib/rbtree.c: fix...
302
  				 *    sl  Sr            S
6280d2356   Michel Lespinasse   rbtree: low level...
303
304
  				 *                       \
  				 *                        Sr
ce093a045   Jie Chen   lib/rbtree.c: fix...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  				 *
  				 * Note: p might be red, and then both
  				 * p and sl are red after rotation(which
  				 * breaks property 4). This is fixed in
  				 * Case 4 (in __rb_rotate_set_parents()
  				 *         which set sl the color of p
  				 *         and set p RB_BLACK)
  				 *
  				 *   (p)            (sl)
  				 *   / \            /  \
  				 *  N   sl   -->   P    S
  				 *       \        /      \
  				 *        S      N        Sr
  				 *         \
  				 *          Sr
6280d2356   Michel Lespinasse   rbtree: low level...
320
  				 */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
321
322
323
324
  				tmp1 = tmp2->rb_right;
  				WRITE_ONCE(sibling->rb_left, tmp1);
  				WRITE_ONCE(tmp2->rb_right, sibling);
  				WRITE_ONCE(parent->rb_right, tmp2);
6280d2356   Michel Lespinasse   rbtree: low level...
325
326
327
  				if (tmp1)
  					rb_set_parent_color(tmp1, sibling,
  							    RB_BLACK);
9c079add0   Michel Lespinasse   rbtree: move augm...
328
  				augment_rotate(sibling, tmp2);
6280d2356   Michel Lespinasse   rbtree: low level...
329
330
  				tmp1 = sibling;
  				sibling = tmp2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
  			}
6280d2356   Michel Lespinasse   rbtree: low level...
332
333
334
335
336
337
338
339
340
341
342
343
  			/*
  			 * Case 4 - left rotate at parent + color flips
  			 * (p and sl could be either color here.
  			 *  After rotation, p becomes black, s acquires
  			 *  p's color, and sl keeps its color)
  			 *
  			 *      (p)             (s)
  			 *      / \             / \
  			 *     N   S     -->   P   Sr
  			 *        / \         / \
  			 *      (sl) sr      N  (sl)
  			 */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
344
345
346
  			tmp2 = sibling->rb_left;
  			WRITE_ONCE(parent->rb_right, tmp2);
  			WRITE_ONCE(sibling->rb_left, parent);
6280d2356   Michel Lespinasse   rbtree: low level...
347
348
349
350
351
  			rb_set_parent_color(tmp1, sibling, RB_BLACK);
  			if (tmp2)
  				rb_set_parent(tmp2, parent);
  			__rb_rotate_set_parents(parent, sibling, root,
  						RB_BLACK);
9c079add0   Michel Lespinasse   rbtree: move augm...
352
  			augment_rotate(parent, sibling);
e125d1471   Michel Lespinasse   rbtree: optimize ...
353
  			break;
d6ff12739   Michel Lespinasse   rbtree: adjust no...
354
  		} else {
6280d2356   Michel Lespinasse   rbtree: low level...
355
356
357
  			sibling = parent->rb_left;
  			if (rb_is_red(sibling)) {
  				/* Case 1 - right rotate at parent */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
358
359
360
  				tmp1 = sibling->rb_right;
  				WRITE_ONCE(parent->rb_left, tmp1);
  				WRITE_ONCE(sibling->rb_right, parent);
6280d2356   Michel Lespinasse   rbtree: low level...
361
362
363
  				rb_set_parent_color(tmp1, parent, RB_BLACK);
  				__rb_rotate_set_parents(parent, sibling, root,
  							RB_RED);
9c079add0   Michel Lespinasse   rbtree: move augm...
364
  				augment_rotate(parent, sibling);
6280d2356   Michel Lespinasse   rbtree: low level...
365
  				sibling = tmp1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  			}
6280d2356   Michel Lespinasse   rbtree: low level...
367
368
369
370
371
372
373
  			tmp1 = sibling->rb_left;
  			if (!tmp1 || rb_is_black(tmp1)) {
  				tmp2 = sibling->rb_right;
  				if (!tmp2 || rb_is_black(tmp2)) {
  					/* Case 2 - sibling color flip */
  					rb_set_parent_color(sibling, parent,
  							    RB_RED);
46b6135a7   Michel Lespinasse   rbtree: handle 1-...
374
375
376
377
378
379
380
381
382
  					if (rb_is_red(parent))
  						rb_set_black(parent);
  					else {
  						node = parent;
  						parent = rb_parent(node);
  						if (parent)
  							continue;
  					}
  					break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  				}
ce093a045   Jie Chen   lib/rbtree.c: fix...
384
  				/* Case 3 - left rotate at sibling */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
385
386
387
388
  				tmp1 = tmp2->rb_left;
  				WRITE_ONCE(sibling->rb_right, tmp1);
  				WRITE_ONCE(tmp2->rb_left, sibling);
  				WRITE_ONCE(parent->rb_left, tmp2);
6280d2356   Michel Lespinasse   rbtree: low level...
389
390
391
  				if (tmp1)
  					rb_set_parent_color(tmp1, sibling,
  							    RB_BLACK);
9c079add0   Michel Lespinasse   rbtree: move augm...
392
  				augment_rotate(sibling, tmp2);
6280d2356   Michel Lespinasse   rbtree: low level...
393
394
  				tmp1 = sibling;
  				sibling = tmp2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  			}
ce093a045   Jie Chen   lib/rbtree.c: fix...
396
  			/* Case 4 - right rotate at parent + color flips */
d72da4a4d   Peter Zijlstra   rbtree: Make lock...
397
398
399
  			tmp2 = sibling->rb_right;
  			WRITE_ONCE(parent->rb_left, tmp2);
  			WRITE_ONCE(sibling->rb_right, parent);
6280d2356   Michel Lespinasse   rbtree: low level...
400
401
402
403
404
  			rb_set_parent_color(tmp1, sibling, RB_BLACK);
  			if (tmp2)
  				rb_set_parent(tmp2, parent);
  			__rb_rotate_set_parents(parent, sibling, root,
  						RB_BLACK);
9c079add0   Michel Lespinasse   rbtree: move augm...
405
  			augment_rotate(parent, sibling);
e125d1471   Michel Lespinasse   rbtree: optimize ...
406
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  }
3cb7a5634   Michel Lespinasse   lib/rbtree.c: avo...
410
411
412
413
414
415
416
  
  /* Non-inline version for rb_erase_augmented() use */
  void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
  	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
  {
  	____rb_erase_color(parent, root, augment_rotate);
  }
9c079add0   Michel Lespinasse   rbtree: move augm...
417
  EXPORT_SYMBOL(__rb_erase_color);
14b94af0b   Michel Lespinasse   rbtree: faster au...
418
419
420
421
422
423
424
425
426
427
428
429
430
  
  /*
   * Non-augmented rbtree manipulation functions.
   *
   * We use dummy augmented callbacks here, and have the compiler optimize them
   * out of the rb_insert_color() and rb_erase() function definitions.
   */
  
  static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {}
  static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {}
  static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {}
  
  static const struct rb_augment_callbacks dummy_callbacks = {
f231aebfc   Kees Cook   rbtree: use desig...
431
432
433
  	.propagate = dummy_propagate,
  	.copy = dummy_copy,
  	.rotate = dummy_rotate
14b94af0b   Michel Lespinasse   rbtree: faster au...
434
435
436
437
  };
  
  void rb_insert_color(struct rb_node *node, struct rb_root *root)
  {
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
438
  	__rb_insert(node, root, false, NULL, dummy_rotate);
14b94af0b   Michel Lespinasse   rbtree: faster au...
439
440
441
442
443
  }
  EXPORT_SYMBOL(rb_insert_color);
  
  void rb_erase(struct rb_node *node, struct rb_root *root)
  {
3cb7a5634   Michel Lespinasse   lib/rbtree.c: avo...
444
  	struct rb_node *rebalance;
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
445
446
  	rebalance = __rb_erase_augmented(node, root,
  					 NULL, &dummy_callbacks);
3cb7a5634   Michel Lespinasse   lib/rbtree.c: avo...
447
448
  	if (rebalance)
  		____rb_erase_color(rebalance, root, dummy_rotate);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
450
  }
  EXPORT_SYMBOL(rb_erase);
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  void rb_insert_color_cached(struct rb_node *node,
  			    struct rb_root_cached *root, bool leftmost)
  {
  	__rb_insert(node, &root->rb_root, leftmost,
  		    &root->rb_leftmost, dummy_rotate);
  }
  EXPORT_SYMBOL(rb_insert_color_cached);
  
  void rb_erase_cached(struct rb_node *node, struct rb_root_cached *root)
  {
  	struct rb_node *rebalance;
  	rebalance = __rb_erase_augmented(node, &root->rb_root,
  					 &root->rb_leftmost, &dummy_callbacks);
  	if (rebalance)
  		____rb_erase_color(rebalance, &root->rb_root, dummy_rotate);
  }
  EXPORT_SYMBOL(rb_erase_cached);
14b94af0b   Michel Lespinasse   rbtree: faster au...
468
469
470
471
472
473
474
475
  /*
   * Augmented rbtree manipulation functions.
   *
   * This instantiates the same __always_inline functions as in the non-augmented
   * case, but this time with user-defined callbacks.
   */
  
  void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
476
  			   bool newleft, struct rb_node **leftmost,
14b94af0b   Michel Lespinasse   rbtree: faster au...
477
478
  	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
  {
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
479
  	__rb_insert(node, root, newleft, leftmost, augment_rotate);
14b94af0b   Michel Lespinasse   rbtree: faster au...
480
481
  }
  EXPORT_SYMBOL(__rb_insert_augmented);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
483
484
  /*
   * This function returns the first node (in sort order) of the tree.
   */
f4b477c47   Artem Bityutskiy   rbtree: add const...
485
  struct rb_node *rb_first(const struct rb_root *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
487
488
489
490
491
492
493
494
495
496
  {
  	struct rb_node	*n;
  
  	n = root->rb_node;
  	if (!n)
  		return NULL;
  	while (n->rb_left)
  		n = n->rb_left;
  	return n;
  }
  EXPORT_SYMBOL(rb_first);
f4b477c47   Artem Bityutskiy   rbtree: add const...
497
  struct rb_node *rb_last(const struct rb_root *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
502
503
504
505
506
507
508
  {
  	struct rb_node	*n;
  
  	n = root->rb_node;
  	if (!n)
  		return NULL;
  	while (n->rb_right)
  		n = n->rb_right;
  	return n;
  }
  EXPORT_SYMBOL(rb_last);
f4b477c47   Artem Bityutskiy   rbtree: add const...
509
  struct rb_node *rb_next(const struct rb_node *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
  {
55a981027   David Woodhouse   [RBTREE] Merge co...
511
  	struct rb_node *parent;
4c199a93a   Michel Lespinasse   rbtree: empty nod...
512
  	if (RB_EMPTY_NODE(node))
10fd48f23   Jens Axboe   [PATCH] rbtree: f...
513
  		return NULL;
7ce6ff9e5   Michel Lespinasse   rbtree: coding st...
514
515
516
517
  	/*
  	 * If we have a right-hand child, go down and then left as far
  	 * as we can.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
  	if (node->rb_right) {
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
519
  		node = node->rb_right;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
  		while (node->rb_left)
  			node=node->rb_left;
f4b477c47   Artem Bityutskiy   rbtree: add const...
522
  		return (struct rb_node *)node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
  	}
7ce6ff9e5   Michel Lespinasse   rbtree: coding st...
524
525
526
527
528
529
530
  	/*
  	 * No right-hand children. Everything down and left is smaller than us,
  	 * so any 'next' node must be in the general direction of our parent.
  	 * Go up the tree; any time the ancestor is a right-hand child of its
  	 * parent, keep going up. First time it's a left-hand child of its
  	 * parent, said parent is our 'next' node.
  	 */
55a981027   David Woodhouse   [RBTREE] Merge co...
531
532
  	while ((parent = rb_parent(node)) && node == parent->rb_right)
  		node = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533

55a981027   David Woodhouse   [RBTREE] Merge co...
534
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
536
  }
  EXPORT_SYMBOL(rb_next);
f4b477c47   Artem Bityutskiy   rbtree: add const...
537
  struct rb_node *rb_prev(const struct rb_node *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
  {
55a981027   David Woodhouse   [RBTREE] Merge co...
539
  	struct rb_node *parent;
4c199a93a   Michel Lespinasse   rbtree: empty nod...
540
  	if (RB_EMPTY_NODE(node))
10fd48f23   Jens Axboe   [PATCH] rbtree: f...
541
  		return NULL;
7ce6ff9e5   Michel Lespinasse   rbtree: coding st...
542
543
544
545
  	/*
  	 * If we have a left-hand child, go down and then right as far
  	 * as we can.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
  	if (node->rb_left) {
cd9e61ed1   Davidlohr Bueso   rbtree: cache lef...
547
  		node = node->rb_left;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
  		while (node->rb_right)
  			node=node->rb_right;
f4b477c47   Artem Bityutskiy   rbtree: add const...
550
  		return (struct rb_node *)node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
  	}
7ce6ff9e5   Michel Lespinasse   rbtree: coding st...
552
553
554
555
  	/*
  	 * No left-hand children. Go up till we find an ancestor which
  	 * is a right-hand child of its parent.
  	 */
55a981027   David Woodhouse   [RBTREE] Merge co...
556
557
  	while ((parent = rb_parent(node)) && node == parent->rb_left)
  		node = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558

55a981027   David Woodhouse   [RBTREE] Merge co...
559
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
561
562
563
564
565
  }
  EXPORT_SYMBOL(rb_prev);
  
  void rb_replace_node(struct rb_node *victim, struct rb_node *new,
  		     struct rb_root *root)
  {
55a981027   David Woodhouse   [RBTREE] Merge co...
566
  	struct rb_node *parent = rb_parent(victim);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567

c1adf2005   David Howells   Introduce rb_repl...
568
569
  	/* Copy the pointers/colour from the victim to the replacement */
  	*new = *victim;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
  	/* Set the surrounding nodes to point to the replacement */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
  	if (victim->rb_left)
55a981027   David Woodhouse   [RBTREE] Merge co...
572
  		rb_set_parent(victim->rb_left, new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
  	if (victim->rb_right)
55a981027   David Woodhouse   [RBTREE] Merge co...
574
  		rb_set_parent(victim->rb_right, new);
c1adf2005   David Howells   Introduce rb_repl...
575
576
577
578
579
580
581
582
  	__rb_change_child(victim, new, parent, root);
  }
  EXPORT_SYMBOL(rb_replace_node);
  
  void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new,
  			 struct rb_root *root)
  {
  	struct rb_node *parent = rb_parent(victim);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
585
  
  	/* Copy the pointers/colour from the victim to the replacement */
  	*new = *victim;
c1adf2005   David Howells   Introduce rb_repl...
586
587
588
589
590
591
592
593
594
595
596
597
  
  	/* Set the surrounding nodes to point to the replacement */
  	if (victim->rb_left)
  		rb_set_parent(victim->rb_left, new);
  	if (victim->rb_right)
  		rb_set_parent(victim->rb_right, new);
  
  	/* Set the parent's pointer to the new node last after an RCU barrier
  	 * so that the pointers onwards are seen to be set correctly when doing
  	 * an RCU walk over the tree.
  	 */
  	__rb_change_child_rcu(victim, new, parent, root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
  }
c1adf2005   David Howells   Introduce rb_repl...
599
  EXPORT_SYMBOL(rb_replace_node_rcu);
9dee5c515   Cody P Schafer   rbtree: add posto...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
  
  static struct rb_node *rb_left_deepest_node(const struct rb_node *node)
  {
  	for (;;) {
  		if (node->rb_left)
  			node = node->rb_left;
  		else if (node->rb_right)
  			node = node->rb_right;
  		else
  			return (struct rb_node *)node;
  	}
  }
  
  struct rb_node *rb_next_postorder(const struct rb_node *node)
  {
  	const struct rb_node *parent;
  	if (!node)
  		return NULL;
  	parent = rb_parent(node);
  
  	/* If we're sitting on node, we've already seen our children */
  	if (parent && node == parent->rb_left && parent->rb_right) {
  		/* If we are the parent's left node, go to the parent's right
  		 * node then all the way down to the left */
  		return rb_left_deepest_node(parent->rb_right);
  	} else
  		/* Otherwise we are the parent's right node, and the parent
  		 * should be next */
  		return (struct rb_node *)parent;
  }
  EXPORT_SYMBOL(rb_next_postorder);
  
  struct rb_node *rb_first_postorder(const struct rb_root *root)
  {
  	if (!root->rb_node)
  		return NULL;
  
  	return rb_left_deepest_node(root->rb_node);
  }
  EXPORT_SYMBOL(rb_first_postorder);