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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
/*
* Copyright 2015 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
#include <core/os.h>
/*XXX: this is just an unbalanced bst with linux's rbtree interface */
void
rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **ptr)
{
node->parent = parent;
*ptr = node;
}
void
rb_insert_color(struct rb_node *node, struct rb_root *root)
{
}
void
rb_erase(struct rb_node *node, struct rb_root *root)
{
struct rb_node **ptr;
/* determine which parent pointer needs replacing */
if (node->parent) {
if (node == node->parent->rb_left)
ptr = &node->parent->rb_left;
else
ptr = &node->parent->rb_right;
} else {
ptr = &root->rb_node;
}
if (node->rb_left && node->rb_right) {
/* find the largest value to the left of the deleted
* node, this will take its place in the tree
*/
struct rb_node *lr = node->rb_left;
while (lr->rb_right)
lr = lr->rb_right;
/* if this isn't the immediate left of the deleted node,
* search down to find the smallest value and link the
* immediate left of the deleted node there
*/
if (node->rb_left != lr) {
struct rb_node *lrl = lr;
while (lrl->rb_left)
lrl = lrl->rb_left;
lrl->rb_left = node->rb_left;
lrl->rb_left->parent = lrl;
lr->parent->rb_right = NULL;
}
/* link into the deleted node's position */
lr->parent = node->parent;
lr->rb_right = node->rb_right;
lr->rb_right->parent = lr;
*ptr = lr;
} else
if (node->rb_left) {
/* move left node into the deleted node's position */
node->rb_left->parent = node->parent;
*ptr = node->rb_left;
} else
if (node->rb_right) {
/* move right node into the deleted node's position */
node->rb_right->parent = node->parent;
*ptr = node->rb_right;
} else {
*ptr = NULL;
}
}
|