Blame view

lib/rbtree.c 10.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  /*
    Red Black Trees
    (C) 1999  Andrea Arcangeli <andrea@suse.de>
    (C) 2002  David Woodhouse <dwmw2@infradead.org>
    
    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
  */
  
  #include <linux/rbtree.h>
  #include <linux/module.h>
  
  static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
  {
  	struct rb_node *right = node->rb_right;
55a981027   David Woodhouse   [RBTREE] Merge co...
29
  	struct rb_node *parent = rb_parent(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  
  	if ((node->rb_right = right->rb_left))
55a981027   David Woodhouse   [RBTREE] Merge co...
32
  		rb_set_parent(right->rb_left, node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  	right->rb_left = node;
55a981027   David Woodhouse   [RBTREE] Merge co...
34
35
36
  	rb_set_parent(right, parent);
  
  	if (parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  	{
55a981027   David Woodhouse   [RBTREE] Merge co...
38
39
  		if (node == parent->rb_left)
  			parent->rb_left = right;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
  		else
55a981027   David Woodhouse   [RBTREE] Merge co...
41
  			parent->rb_right = right;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
44
  	}
  	else
  		root->rb_node = right;
55a981027   David Woodhouse   [RBTREE] Merge co...
45
  	rb_set_parent(node, right);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
  }
  
  static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
  {
  	struct rb_node *left = node->rb_left;
55a981027   David Woodhouse   [RBTREE] Merge co...
51
  	struct rb_node *parent = rb_parent(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
  
  	if ((node->rb_left = left->rb_right))
55a981027   David Woodhouse   [RBTREE] Merge co...
54
  		rb_set_parent(left->rb_right, node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
  	left->rb_right = node;
55a981027   David Woodhouse   [RBTREE] Merge co...
56
57
58
  	rb_set_parent(left, parent);
  
  	if (parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  	{
55a981027   David Woodhouse   [RBTREE] Merge co...
60
61
  		if (node == parent->rb_right)
  			parent->rb_right = left;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  		else
55a981027   David Woodhouse   [RBTREE] Merge co...
63
  			parent->rb_left = left;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
  	}
  	else
  		root->rb_node = left;
55a981027   David Woodhouse   [RBTREE] Merge co...
67
  	rb_set_parent(node, left);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
72
  }
  
  void rb_insert_color(struct rb_node *node, struct rb_root *root)
  {
  	struct rb_node *parent, *gparent;
55a981027   David Woodhouse   [RBTREE] Merge co...
73
  	while ((parent = rb_parent(node)) && rb_is_red(parent))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  	{
55a981027   David Woodhouse   [RBTREE] Merge co...
75
  		gparent = rb_parent(parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
  
  		if (parent == gparent->rb_left)
  		{
  			{
  				register struct rb_node *uncle = gparent->rb_right;
55a981027   David Woodhouse   [RBTREE] Merge co...
81
  				if (uncle && rb_is_red(uncle))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  				{
55a981027   David Woodhouse   [RBTREE] Merge co...
83
84
85
  					rb_set_black(uncle);
  					rb_set_black(parent);
  					rb_set_red(gparent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
92
93
94
95
96
97
98
  					node = gparent;
  					continue;
  				}
  			}
  
  			if (parent->rb_right == node)
  			{
  				register struct rb_node *tmp;
  				__rb_rotate_left(parent, root);
  				tmp = parent;
  				parent = node;
  				node = tmp;
  			}
55a981027   David Woodhouse   [RBTREE] Merge co...
99
100
  			rb_set_black(parent);
  			rb_set_red(gparent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
  			__rb_rotate_right(gparent, root);
  		} else {
  			{
  				register struct rb_node *uncle = gparent->rb_left;
55a981027   David Woodhouse   [RBTREE] Merge co...
105
  				if (uncle && rb_is_red(uncle))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  				{
55a981027   David Woodhouse   [RBTREE] Merge co...
107
108
109
  					rb_set_black(uncle);
  					rb_set_black(parent);
  					rb_set_red(gparent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
114
115
116
117
118
119
120
121
122
  					node = gparent;
  					continue;
  				}
  			}
  
  			if (parent->rb_left == node)
  			{
  				register struct rb_node *tmp;
  				__rb_rotate_right(parent, root);
  				tmp = parent;
  				parent = node;
  				node = tmp;
  			}
55a981027   David Woodhouse   [RBTREE] Merge co...
123
124
  			rb_set_black(parent);
  			rb_set_red(gparent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
  			__rb_rotate_left(gparent, root);
  		}
  	}
55a981027   David Woodhouse   [RBTREE] Merge co...
128
  	rb_set_black(root->rb_node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
  }
  EXPORT_SYMBOL(rb_insert_color);
  
  static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
  			     struct rb_root *root)
  {
  	struct rb_node *other;
55a981027   David Woodhouse   [RBTREE] Merge co...
136
  	while ((!node || rb_is_black(node)) && node != root->rb_node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
  	{
  		if (parent->rb_left == node)
  		{
  			other = parent->rb_right;
55a981027   David Woodhouse   [RBTREE] Merge co...
141
  			if (rb_is_red(other))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
143
144
  				rb_set_black(other);
  				rb_set_red(parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
  				__rb_rotate_left(parent, root);
  				other = parent->rb_right;
  			}
55a981027   David Woodhouse   [RBTREE] Merge co...
148
149
  			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
  			    (!other->rb_right || rb_is_black(other->rb_right)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
151
  				rb_set_red(other);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  				node = parent;
55a981027   David Woodhouse   [RBTREE] Merge co...
153
  				parent = rb_parent(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
  			}
  			else
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
157
  				if (!other->rb_right || rb_is_black(other->rb_right))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  				{
55a63998b   Wolfram Strepp   lib/rbtree.c: opt...
159
  					rb_set_black(other->rb_left);
55a981027   David Woodhouse   [RBTREE] Merge co...
160
  					rb_set_red(other);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
  					__rb_rotate_right(other, root);
  					other = parent->rb_right;
  				}
2f3243aeb   David Woodhouse   [RBTREE] Switch r...
164
  				rb_set_color(other, rb_color(parent));
55a981027   David Woodhouse   [RBTREE] Merge co...
165
  				rb_set_black(parent);
55a63998b   Wolfram Strepp   lib/rbtree.c: opt...
166
  				rb_set_black(other->rb_right);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
171
172
173
174
  				__rb_rotate_left(parent, root);
  				node = root->rb_node;
  				break;
  			}
  		}
  		else
  		{
  			other = parent->rb_left;
55a981027   David Woodhouse   [RBTREE] Merge co...
175
  			if (rb_is_red(other))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
177
178
  				rb_set_black(other);
  				rb_set_red(parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
  				__rb_rotate_right(parent, root);
  				other = parent->rb_left;
  			}
55a981027   David Woodhouse   [RBTREE] Merge co...
182
183
  			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
  			    (!other->rb_right || rb_is_black(other->rb_right)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
185
  				rb_set_red(other);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  				node = parent;
55a981027   David Woodhouse   [RBTREE] Merge co...
187
  				parent = rb_parent(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
  			}
  			else
  			{
55a981027   David Woodhouse   [RBTREE] Merge co...
191
  				if (!other->rb_left || rb_is_black(other->rb_left))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  				{
55a63998b   Wolfram Strepp   lib/rbtree.c: opt...
193
  					rb_set_black(other->rb_right);
55a981027   David Woodhouse   [RBTREE] Merge co...
194
  					rb_set_red(other);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
197
  					__rb_rotate_left(other, root);
  					other = parent->rb_left;
  				}
2f3243aeb   David Woodhouse   [RBTREE] Switch r...
198
  				rb_set_color(other, rb_color(parent));
55a981027   David Woodhouse   [RBTREE] Merge co...
199
  				rb_set_black(parent);
55a63998b   Wolfram Strepp   lib/rbtree.c: opt...
200
  				rb_set_black(other->rb_left);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
207
  				__rb_rotate_right(parent, root);
  				node = root->rb_node;
  				break;
  			}
  		}
  	}
  	if (node)
55a981027   David Woodhouse   [RBTREE] Merge co...
208
  		rb_set_black(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  }
  
  void rb_erase(struct rb_node *node, struct rb_root *root)
  {
  	struct rb_node *child, *parent;
  	int color;
  
  	if (!node->rb_left)
  		child = node->rb_right;
  	else if (!node->rb_right)
  		child = node->rb_left;
  	else
  	{
  		struct rb_node *old = node, *left;
  
  		node = node->rb_right;
  		while ((left = node->rb_left) != NULL)
  			node = left;
16c047add   Wolfram Strepp   rb_tree: reorgani...
227
228
229
230
231
232
233
234
  
  		if (rb_parent(old)) {
  			if (rb_parent(old)->rb_left == old)
  				rb_parent(old)->rb_left = node;
  			else
  				rb_parent(old)->rb_right = node;
  		} else
  			root->rb_node = node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  		child = node->rb_right;
55a981027   David Woodhouse   [RBTREE] Merge co...
236
  		parent = rb_parent(node);
2f3243aeb   David Woodhouse   [RBTREE] Switch r...
237
  		color = rb_color(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238

55a981027   David Woodhouse   [RBTREE] Merge co...
239
  		if (parent == old) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  			parent = node;
4c6011781   Wolfram Strepp   rb_tree: make cle...
241
242
243
  		} else {
  			if (child)
  				rb_set_parent(child, parent);
1975e5937   David Woodhouse   [RBTREE] Remove d...
244
  			parent->rb_left = child;
4b324126e   Wolfram Strepp   rb_tree: remove r...
245
246
247
  
  			node->rb_right = old->rb_right;
  			rb_set_parent(old->rb_right, node);
4c6011781   Wolfram Strepp   rb_tree: make cle...
248
  		}
1975e5937   David Woodhouse   [RBTREE] Remove d...
249

2f3243aeb   David Woodhouse   [RBTREE] Switch r...
250
  		node->rb_parent_color = old->rb_parent_color;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  		node->rb_left = old->rb_left;
55a981027   David Woodhouse   [RBTREE] Merge co...
252
  		rb_set_parent(old->rb_left, node);
4b324126e   Wolfram Strepp   rb_tree: remove r...
253

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
  		goto color;
  	}
55a981027   David Woodhouse   [RBTREE] Merge co...
256
  	parent = rb_parent(node);
2f3243aeb   David Woodhouse   [RBTREE] Switch r...
257
  	color = rb_color(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
259
  
  	if (child)
55a981027   David Woodhouse   [RBTREE] Merge co...
260
  		rb_set_parent(child, parent);
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
261
262
  	if (parent)
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
266
  		if (parent->rb_left == node)
  			parent->rb_left = child;
  		else
  			parent->rb_right = child;
17d9ddc72   Pallipadi, Venkatesh   rbtree: Add suppo...
267
  	}
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
268
269
  	else
  		root->rb_node = child;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
272
273
274
275
  
   color:
  	if (color == RB_BLACK)
  		__rb_erase_color(child, parent, root);
  }
  EXPORT_SYMBOL(rb_erase);
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
  {
  	struct rb_node *parent;
  
  up:
  	func(node, data);
  	parent = rb_parent(node);
  	if (!parent)
  		return;
  
  	if (node == parent->rb_left && parent->rb_right)
  		func(parent->rb_right, data);
  	else if (parent->rb_left)
  		func(parent->rb_left, data);
  
  	node = parent;
  	goto up;
  }
  
  /*
   * after inserting @node into the tree, update the tree to account for
   * both the new entry and any damage done by rebalance
   */
  void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
  {
  	if (node->rb_left)
  		node = node->rb_left;
  	else if (node->rb_right)
  		node = node->rb_right;
  
  	rb_augment_path(node, func, data);
  }
0b6bb66d1   Andreas Gruenbacher   Export the augmen...
308
  EXPORT_SYMBOL(rb_augment_insert);
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  
  /*
   * before removing the node, find the deepest node on the rebalance path
   * that will still be there after @node gets removed
   */
  struct rb_node *rb_augment_erase_begin(struct rb_node *node)
  {
  	struct rb_node *deepest;
  
  	if (!node->rb_right && !node->rb_left)
  		deepest = rb_parent(node);
  	else if (!node->rb_right)
  		deepest = node->rb_left;
  	else if (!node->rb_left)
  		deepest = node->rb_right;
  	else {
  		deepest = rb_next(node);
  		if (deepest->rb_right)
  			deepest = deepest->rb_right;
  		else if (rb_parent(deepest) != node)
  			deepest = rb_parent(deepest);
  	}
  
  	return deepest;
  }
0b6bb66d1   Andreas Gruenbacher   Export the augmen...
334
  EXPORT_SYMBOL(rb_augment_erase_begin);
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
335
336
337
338
339
340
341
342
343
344
  
  /*
   * after removal, update the tree to account for the removed entry
   * and any rebalance damage.
   */
  void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
  {
  	if (node)
  		rb_augment_path(node, func, data);
  }
0b6bb66d1   Andreas Gruenbacher   Export the augmen...
345
  EXPORT_SYMBOL(rb_augment_erase_end);
b945d6b25   Peter Zijlstra   rbtree: Undo augm...
346

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
349
  /*
   * This function returns the first node (in sort order) of the tree.
   */
f4b477c47   Artem Bityutskiy   rbtree: add const...
350
  struct rb_node *rb_first(const struct rb_root *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
354
355
356
357
358
359
360
361
  {
  	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...
362
  struct rb_node *rb_last(const struct rb_root *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
364
365
366
367
368
369
370
371
372
373
  {
  	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...
374
  struct rb_node *rb_next(const struct rb_node *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
  {
55a981027   David Woodhouse   [RBTREE] Merge co...
376
  	struct rb_node *parent;
10fd48f23   Jens Axboe   [PATCH] rbtree: f...
377
378
  	if (rb_parent(node) == node)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
382
383
384
  	/* If we have a right-hand child, go down and then left as far
  	   as we can. */
  	if (node->rb_right) {
  		node = node->rb_right; 
  		while (node->rb_left)
  			node=node->rb_left;
f4b477c47   Artem Bityutskiy   rbtree: add const...
385
  		return (struct rb_node *)node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
387
388
389
390
391
392
393
  	}
  
  	/* 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...
394
395
  	while ((parent = rb_parent(node)) && node == parent->rb_right)
  		node = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396

55a981027   David Woodhouse   [RBTREE] Merge co...
397
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  }
  EXPORT_SYMBOL(rb_next);
f4b477c47   Artem Bityutskiy   rbtree: add const...
400
  struct rb_node *rb_prev(const struct rb_node *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  {
55a981027   David Woodhouse   [RBTREE] Merge co...
402
  	struct rb_node *parent;
10fd48f23   Jens Axboe   [PATCH] rbtree: f...
403
404
  	if (rb_parent(node) == node)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
406
407
408
409
410
  	/* If we have a left-hand child, go down and then right as far
  	   as we can. */
  	if (node->rb_left) {
  		node = node->rb_left; 
  		while (node->rb_right)
  			node=node->rb_right;
f4b477c47   Artem Bityutskiy   rbtree: add const...
411
  		return (struct rb_node *)node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
  	}
  
  	/* 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...
416
417
  	while ((parent = rb_parent(node)) && node == parent->rb_left)
  		node = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418

55a981027   David Woodhouse   [RBTREE] Merge co...
419
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
422
423
424
425
  }
  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...
426
  	struct rb_node *parent = rb_parent(victim);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
430
431
432
433
434
435
436
437
  
  	/* Set the surrounding nodes to point to the replacement */
  	if (parent) {
  		if (victim == parent->rb_left)
  			parent->rb_left = new;
  		else
  			parent->rb_right = new;
  	} else {
  		root->rb_node = new;
  	}
  	if (victim->rb_left)
55a981027   David Woodhouse   [RBTREE] Merge co...
438
  		rb_set_parent(victim->rb_left, new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  	if (victim->rb_right)
55a981027   David Woodhouse   [RBTREE] Merge co...
440
  		rb_set_parent(victim->rb_right, new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
445
  
  	/* Copy the pointers/colour from the victim to the replacement */
  	*new = *victim;
  }
  EXPORT_SYMBOL(rb_replace_node);