ReactOS 0.4.16-dev-1272-g2c12489
rbtree.h
Go to the documentation of this file.
1/*
2 * Red-black search tree support
3 *
4 * Copyright 2009 Henri Verbeet
5 * Copyright 2009 Andrew Riedi
6 * Copyright 2016 Jacek Caban for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#ifndef __WINE_WINE_RBTREE_H
24#define __WINE_WINE_RBTREE_H
25
26#define RB_ENTRY_VALUE(element, type, field) \
27 ((type *)((char *)(element) - offsetof(type, field)))
28
30{
32 struct rb_entry *left;
33 struct rb_entry *right;
34 unsigned int flags;
35};
36
37typedef int (*rb_compare_func_t)(const void *key, const struct rb_entry *entry);
38
39struct rb_tree
40{
42 struct rb_entry *root;
43};
44
45typedef void (rb_traverse_func_t)(struct rb_entry *entry, void *context);
46
47#define RB_FLAG_RED 0x1
48
49static inline int rb_is_red(struct rb_entry *entry)
50{
51 return entry && (entry->flags & RB_FLAG_RED);
52}
53
54static inline void rb_rotate_left(struct rb_tree *tree, struct rb_entry *e)
55{
56 struct rb_entry *right = e->right;
57
58 if (!e->parent)
59 tree->root = right;
60 else if (e->parent->left == e)
61 e->parent->left = right;
62 else
63 e->parent->right = right;
64
65 e->right = right->left;
66 if (e->right) e->right->parent = e;
67 right->left = e;
68 right->parent = e->parent;
69 e->parent = right;
70}
71
72static inline void rb_rotate_right(struct rb_tree *tree, struct rb_entry *e)
73{
74 struct rb_entry *left = e->left;
75
76 if (!e->parent)
77 tree->root = left;
78 else if (e->parent->left == e)
79 e->parent->left = left;
80 else
81 e->parent->right = left;
82
83 e->left = left->right;
84 if (e->left) e->left->parent = e;
85 left->right = e;
86 left->parent = e->parent;
87 e->parent = left;
88}
89
90static inline void rb_flip_color(struct rb_entry *entry)
91{
92 entry->flags ^= RB_FLAG_RED;
93 entry->left->flags ^= RB_FLAG_RED;
94 entry->right->flags ^= RB_FLAG_RED;
95}
96
97static inline struct rb_entry *rb_head(struct rb_entry *iter)
98{
99 if (!iter) return NULL;
100 while (iter->left) iter = iter->left;
101 return iter;
102}
103
104static inline struct rb_entry *rb_tail(struct rb_entry *iter)
105{
106 if (!iter) return NULL;
107 while (iter->right) iter = iter->right;
108 return iter;
109}
110
111static inline struct rb_entry *rb_next(struct rb_entry *iter)
112{
113 if (iter->right) return rb_head(iter->right);
114 while (iter->parent && iter->parent->right == iter) iter = iter->parent;
115 return iter->parent;
116}
117
118static inline struct rb_entry *rb_prev(struct rb_entry *iter)
119{
120 if (iter->left) return rb_tail(iter->left);
121 while (iter->parent && iter->parent->left == iter) iter = iter->parent;
122 return iter->parent;
123}
124
125static inline struct rb_entry *rb_postorder_head(struct rb_entry *iter)
126{
127 if (!iter) return NULL;
128
129 for (;;) {
130 while (iter->left) iter = iter->left;
131 if (!iter->right) return iter;
132 iter = iter->right;
133 }
134}
135
136static inline struct rb_entry *rb_postorder_next(struct rb_entry *iter)
137{
138 if (!iter->parent) return NULL;
139 if (iter == iter->parent->right || !iter->parent->right) return iter->parent;
140 return rb_postorder_head(iter->parent->right);
141}
142
143/* iterate through the tree */
144#define RB_FOR_EACH(cursor, tree) \
145 for ((cursor) = rb_head((tree)->root); (cursor); (cursor) = rb_next(cursor))
146
147/* iterate through the tree using a tree entry */
148#define RB_FOR_EACH_ENTRY(elem, tree, type, field) \
149 for ((elem) = RB_ENTRY_VALUE(rb_head((tree)->root), type, field); \
150 (elem) != RB_ENTRY_VALUE(0, type, field); \
151 (elem) = RB_ENTRY_VALUE(rb_next(&elem->field), type, field))
152
153/* iterate through the tree using using postorder, making it safe to free the entry */
154#define RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \
155 for ((cursor) = rb_postorder_head((tree)->root); \
156 (cursor) && (((cursor2) = rb_postorder_next(cursor)) || 1); \
157 (cursor) = (cursor2))
158
159/* iterate through the tree using a tree entry and postorder, making it safe to free the entry */
160#define RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \
161 for ((elem) = RB_ENTRY_VALUE(rb_postorder_head((tree)->root), type, field); \
162 (elem) != RB_ENTRY_VALUE(0, type, field) \
163 && (((elem2) = RB_ENTRY_VALUE(rb_postorder_next(&(elem)->field), type, field)) || 1); \
164 (elem) = (elem2))
165
166
167static inline void rb_postorder(struct rb_tree *tree, rb_traverse_func_t *callback, void *context)
168{
169 struct rb_entry *iter, *next;
171}
172
173static inline void rb_init(struct rb_tree *tree, rb_compare_func_t compare)
174{
175 tree->compare = compare;
176 tree->root = NULL;
177}
178
180{
181 struct rb_entry *iter;
182 RB_FOR_EACH(iter, tree) callback(iter, context);
183}
184
185static inline void rb_destroy(struct rb_tree *tree, rb_traverse_func_t *callback, void *context)
186{
187 /* Note that we use postorder here because the callback will likely free the entry. */
189 tree->root = NULL;
190}
191
192static inline struct rb_entry *rb_get(const struct rb_tree *tree, const void *key)
193{
194 struct rb_entry *entry = tree->root;
195 while (entry)
196 {
197 int c = tree->compare(key, entry);
198 if (!c) return entry;
199 entry = c < 0 ? entry->left : entry->right;
200 }
201 return NULL;
202}
203
204static inline int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
205{
206 struct rb_entry **iter = &tree->root, *parent = tree->root;
207
208 while (*iter)
209 {
210 int c;
211
212 parent = *iter;
213 c = tree->compare(key, parent);
214 if (!c) return -1;
215 else if (c < 0) iter = &parent->left;
216 else iter = &parent->right;
217 }
218
219 entry->flags = RB_FLAG_RED;
220 entry->parent = parent;
221 entry->left = NULL;
222 entry->right = NULL;
223 *iter = entry;
224
225 while (rb_is_red(entry->parent))
226 {
227 if (entry->parent == entry->parent->parent->left)
228 {
229 if (rb_is_red(entry->parent->parent->right))
230 {
231 rb_flip_color(entry->parent->parent);
232 entry = entry->parent->parent;
233 }
234 else
235 {
236 if (entry == entry->parent->right)
237 {
238 entry = entry->parent;
240 }
241 entry->parent->flags &= ~RB_FLAG_RED;
242 entry->parent->parent->flags |= RB_FLAG_RED;
243 rb_rotate_right(tree, entry->parent->parent);
244 }
245 }
246 else
247 {
248 if (rb_is_red(entry->parent->parent->left))
249 {
250 rb_flip_color(entry->parent->parent);
251 entry = entry->parent->parent;
252 }
253 else
254 {
255 if (entry == entry->parent->left)
256 {
257 entry = entry->parent;
259 }
260 entry->parent->flags &= ~RB_FLAG_RED;
261 entry->parent->parent->flags |= RB_FLAG_RED;
262 rb_rotate_left(tree, entry->parent->parent);
263 }
264 }
265 }
266
267 tree->root->flags &= ~RB_FLAG_RED;
268
269 return 0;
270}
271
272static inline void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
273{
274 struct rb_entry *iter, *child, *parent, *w;
275 int need_fixup;
276
277 if (entry->right && entry->left)
278 for(iter = entry->right; iter->left; iter = iter->left);
279 else
280 iter = entry;
281
282 child = iter->left ? iter->left : iter->right;
283
284 if (!iter->parent)
285 tree->root = child;
286 else if (iter == iter->parent->left)
287 iter->parent->left = child;
288 else
289 iter->parent->right = child;
290
291 if (child) child->parent = iter->parent;
292 parent = iter->parent;
293
294 need_fixup = !rb_is_red(iter);
295
296 if (entry != iter)
297 {
298 *iter = *entry;
299 if (!iter->parent)
300 tree->root = iter;
301 else if (entry == iter->parent->left)
302 iter->parent->left = iter;
303 else
304 iter->parent->right = iter;
305
306 if (iter->right) iter->right->parent = iter;
307 if (iter->left) iter->left->parent = iter;
308 if (parent == entry) parent = iter;
309 }
310
311 if (need_fixup)
312 {
313 while (parent && !rb_is_red(child))
314 {
315 if (child == parent->left)
316 {
317 w = parent->right;
318 if (rb_is_red(w))
319 {
320 w->flags &= ~RB_FLAG_RED;
321 parent->flags |= RB_FLAG_RED;
323 w = parent->right;
324 }
325 if (rb_is_red(w->left) || rb_is_red(w->right))
326 {
327 if (!rb_is_red(w->right))
328 {
329 w->left->flags &= ~RB_FLAG_RED;
330 w->flags |= RB_FLAG_RED;
332 w = parent->right;
333 }
334 w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED);
335 parent->flags &= ~RB_FLAG_RED;
336 if (w->right)
337 w->right->flags &= ~RB_FLAG_RED;
339 child = NULL;
340 break;
341 }
342 }
343 else
344 {
345 w = parent->left;
346 if (rb_is_red(w))
347 {
348 w->flags &= ~RB_FLAG_RED;
349 parent->flags |= RB_FLAG_RED;
351 w = parent->left;
352 }
353 if (rb_is_red(w->left) || rb_is_red(w->right))
354 {
355 if (!rb_is_red(w->left))
356 {
357 w->right->flags &= ~RB_FLAG_RED;
358 w->flags |= RB_FLAG_RED;
360 w = parent->left;
361 }
362 w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED);
363 parent->flags &= ~RB_FLAG_RED;
364 if (w->left)
365 w->left->flags &= ~RB_FLAG_RED;
367 child = NULL;
368 break;
369 }
370 }
371 w->flags |= RB_FLAG_RED;
372 child = parent;
373 parent = child->parent;
374 }
375 if (child) child->flags &= ~RB_FLAG_RED;
376 }
377
378 if (tree->root) tree->root->flags &= ~RB_FLAG_RED;
379}
380
381static inline void rb_remove_key(struct rb_tree *tree, const void *key)
382{
383 struct rb_entry *entry = rb_get(tree, key);
384 if (entry) rb_remove(tree, entry);
385}
386
387static inline void rb_replace(struct rb_tree *tree, struct rb_entry *dst, struct rb_entry *src)
388{
389 if (!(src->parent = dst->parent))
390 tree->root = src;
391 else if (dst->parent->left == dst)
392 dst->parent->left = src;
393 else
394 dst->parent->right = src;
395
396 if ((src->left = dst->left))
397 src->left->parent = src;
398 if ((src->right = dst->right))
399 src->right->parent = src;
400 src->flags = dst->flags;
401}
402
403/* old names for backwards compatibility */
404#define wine_rb_entry rb_entry
405#define wine_rb_tree rb_tree
406#define wine_rb_init rb_init
407#define wine_rb_for_each_entry rb_for_each_entry
408#define wine_rb_destroy rb_destroy
409#define wine_rb_get rb_get
410#define wine_rb_put rb_put
411#define wine_rb_remove rb_remove
412#define wine_rb_remove_key rb_remove_key
413#define wine_rb_replace rb_replace
414#define WINE_RB_ENTRY_VALUE RB_ENTRY_VALUE
415#define WINE_RB_FOR_EACH_ENTRY RB_FOR_EACH_ENTRY
416#define WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR RB_FOR_EACH_ENTRY_DESTRUCTOR
417#ifdef __REACTOS__
418#define wine_rb_clear rb_destroy
419#endif
420
421#endif /* __WINE_WINE_RBTREE_H */
#define compare
#define NULL
Definition: types.h:112
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
r parent
Definition: btrfs.c:3010
#define rb_is_red(r)
Definition: rbtree.h:115
struct rb_node * rb_next(struct rb_node *)
Definition: rbtree.c:320
struct rb_node * rb_prev(struct rb_node *)
Definition: rbtree.c:346
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLenum GLenum dst
Definition: glext.h:6340
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
#define c
Definition: ke_i.h:80
static IPrintDialogCallback callback
Definition: printdlg.c:326
static HWND child
Definition: cursoricon.c:298
static unsigned __int64 next
Definition: rand_nt.c:6
int(* rb_compare_func_t)(const void *key, const struct rb_entry *entry)
Definition: rbtree.h:37
static struct rb_entry * rb_postorder_next(struct rb_entry *iter)
Definition: rbtree.h:136
#define RB_FOR_EACH(cursor, tree)
Definition: rbtree.h:144
static void rb_postorder(struct rb_tree *tree, rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:167
static void rb_destroy(struct rb_tree *tree, rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:185
static void rb_rotate_right(struct rb_tree *tree, struct rb_entry *e)
Definition: rbtree.h:72
static void rb_for_each_entry(struct rb_tree *tree, rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:179
static void rb_rotate_left(struct rb_tree *tree, struct rb_entry *e)
Definition: rbtree.h:54
static struct rb_entry * rb_head(struct rb_entry *iter)
Definition: rbtree.h:97
static struct rb_entry * rb_tail(struct rb_entry *iter)
Definition: rbtree.h:104
static int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
Definition: rbtree.h:204
static struct rb_entry * rb_get(const struct rb_tree *tree, const void *key)
Definition: rbtree.h:192
static void rb_flip_color(struct rb_entry *entry)
Definition: rbtree.h:90
#define RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree)
Definition: rbtree.h:154
void() rb_traverse_func_t(struct rb_entry *entry, void *context)
Definition: rbtree.h:45
static void rb_remove_key(struct rb_tree *tree, const void *key)
Definition: rbtree.h:381
static void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
Definition: rbtree.h:272
static struct rb_entry * rb_postorder_head(struct rb_entry *iter)
Definition: rbtree.h:125
static void rb_init(struct rb_tree *tree, rb_compare_func_t compare)
Definition: rbtree.h:173
#define RB_FLAG_RED
Definition: rbtree.h:47
static void rb_replace(struct rb_tree *tree, struct rb_entry *dst, struct rb_entry *src)
Definition: rbtree.h:387
struct _root * root
Definition: btrfs_drv.h:433
Definition: bug.cpp:8
Definition: http.c:7252
Definition: copy.c:22
Definition: rbtree.h:30
struct rb_entry * right
Definition: rbtree.h:33
struct rb_entry * parent
Definition: rbtree.h:31
unsigned int flags
Definition: rbtree.h:34
struct rb_entry * left
Definition: rbtree.h:32
Definition: rbtree.h:40
rb_compare_func_t compare
Definition: rbtree.h:41
struct rb_entry * root
Definition: rbtree.h:42