1
/*
2
* \brief AVL tree
3
* \author Norman Feske
4
* \date 2006-04-12
5
*/
6
7
/*
8
* Copyright (C) 2006-2013 Genode Labs GmbH
9
*
10
* This file is part of the Genode OS framework, which is distributed
11
* under the terms of the GNU General Public License version 2.
12
*/
13
14
#
ifndef _INCLUDE__UTIL__AVL_TREE_H_
15
#
define _INCLUDE__UTIL__AVL_TREE_H_
16
17
#
include <util/misc_math.h>
18
19
namespace
Genode {
20
21
class
Avl_node_base;
22
template
<
typename
>
class
Avl_node;
23
template
<
typename
>
class
Avl_tree;
24
}
25
26
27
class
Genode::
Avl_node_base
28
{
29
protected
:
30
31
/**
32
* Internal policy interface
33
*
34
* The implementation of this interface is provided by the AVL tree.
35
*/
36
struct
Policy
37
{
38
virtual
~
Policy(
)
{
}
39
40
/**
41
* Compare two nodes
42
*
43
* \retval false if n2 is lower than n1
44
* \retval true if n2 is higher than or equal to n1
45
*
46
* This method must be provided by the derived class.
47
* It determines the order of nodes inside the AVL tree.
48
*/
49
virtual
bool
higher(
Avl_node_base *
n1
,
Avl_node_base *
n2
)
const
=
0
;
50
51
/**
52
* Node recomputation hook
53
*
54
* If a node gets rearranged, this method is called.
55
* It can be used to update AVL-tree-position dependent
56
* meta data.
57
*/
58
virtual
void
recompute(
Avl_node_base *
)
{
}
59
}
;
60
61
Avl_node_base *
_child[2]
;
/* left and right subtrees */
62
Avl_node_base *
_parent;
/* parent of subtree */
63
unsigned
char _depth;
/* depth of subtree */
64
65
public
:
66
67
typedef
bool Side
;
68
69
enum
{
LEFT =
false
,
RIGHT =
true
}
;
70
71
private
:
72
73
/**
74
* Determine depth of subtree
75
*/
76
inline
int
_child_depth(
Side
i
)
{
77
return
_child[i]
?
_child[i]
->
_depth : 0
;
}
78
79
/**
80
* Update depth of node
81
*/
82
void
_recompute_depth(
Policy &
policy
)
;
83
84
/**
85
* Determine left-right bias of both subtrees
86
*/
87
inline
Side
_bias(
)
{
88
return
(
_child_depth(
RIGHT)
>
_child_depth(
LEFT)
)
;
}
89
90
/**
91
* Insert subtree into specified side of the node
92
*/
93
void
_adopt(
Avl_node_base *
node
,
Side
i
,
Policy &
policy
)
;
94
95
/**
96
* Rotate subtree
97
*
98
* \param side direction of rotate operation
99
* \param node subtree to rotate
100
*
101
* The local node_* variable names describe node locations for
102
* the left (default) rotation. For example, node_r_l is the
103
* left of the right of node.
104
*/
105
void
_rotate_subtree(
Avl_node_base *
node
,
Side
side
,
Policy &
policy
)
;
106
107
/**
108
* Rebalance subtree
109
*
110
* \param node immediate child that needs balancing
111
*
112
* `this` is parent of the subtree to rebalance
113
*/
114
void
_rebalance_subtree(
Avl_node_base *
node
,
Policy &
policy
)
;
115
116
public
:
117
118
/**
119
* Constructor
120
*/
121
Avl_node_base(
)
;
122
123
/**
124
* Insert new node into subtree
125
*/
126
void
insert(
Avl_node_base *
node
,
Policy &
policy
)
;
127
128
/**
129
* Remove node from tree
130
*/
131
void
remove(
Policy &
policy
)
;
132
}
;
133
134
135
/**
136
* AVL node
137
*
138
* \param NT type of the class derived from `Avl_node`
139
*
140
* Each object to be stored in the AVL tree must be derived from `Avl_node`.
141
* The type of the derived class is to be specified as template argument to
142
* enable `Avl_node` to call virtual methods specific for the derived class.
143
*
144
* The NT class must implement a method called `higher` that takes a pointer to
145
* another NT object as argument and returns a bool value. The bool value is
146
* true if the specified node is higher or equal in the tree order.
147
*/
148
template
<
typename
NT
>
149
struct
Genode::
Avl_node :
Avl_node_base
150
{
151
/**
152
* Return child of specified side, or nullptr if there is no child
153
*
154
* This method can be called by the NT objects to traverse the tree.
155
*/
156
inline
NT *
child(
Side
i
)
const
{
return
static_cast
<
NT *
>
(
_child[i])
;
}
157
158
/**
159
* Default policy
160
*
161
* \noapi
162
*/
163
void
recompute(
)
{
}
164
}
;
165
166
167
/**
168
* Root node of the AVL tree
169
*
170
* The real nodes are always attached at the left branch of this root node.
171
*/
172
template
<
typename
NT
>
173
class
Genode::
Avl_tree :
Avl_node<
NT
>
174
{
175
private
:
176
177
/**
178
* Auto-generated policy class specific for NT
179
*/
180
class
Policy :
public
Avl_node_base::
Policy
181
{
182
bool
higher(
Avl_node_base *
n1
,
Avl_node_base *
n2
)
const
183
{
184
return
static_cast
<
NT *
>
(
n1)
->
higher(
static_cast
<
NT *
>
(
n2)
)
;
185
}
186
187
void
recompute(
Avl_node_base *
node
)
188
{
189
static_cast
<
NT *
>
(
node)
->
recompute(
)
;
190
}
191
192
}
_policy;
193
194
public
:
195
196
/**
197
* Insert node into AVL tree
198
*/
199
void
insert(
Avl_node<
NT
>
*
node
)
{
Avl_node_base::
insert(
node,
_policy)
;
}
200
201
/**
202
* Remove node from AVL tree
203
*/
204
void
remove(
Avl_node<
NT
>
*
node
)
{
node->
remove(
_policy)
;
}
205
206
/**
207
* Request first node of the tree
208
*
209
* \return first node, or nullptr if the tree is empty
210
*/
211
inline
NT *
first(
)
const
{
return
this->
child(
Avl_node<
NT
>
::
LEFT)
;
}
212
}
;
213
214
#
endif /* _INCLUDE__UTIL__AVL_TREE_H_ */