2 * Red-black search tree support
4 * Copyright 2009 Henri Verbeet
5 * Copyright 2009 Andrew Riedi
6 * Copyright 2016 Jacek Caban for CodeWeavers
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.
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.
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
23 #ifndef __WINE_WINE_RBTREE_H
24 #define __WINE_WINE_RBTREE_H
26 #define WINE_RB_ENTRY_VALUE(element, type, field) \
27 ((type *)((char *)(element) - offsetof(type, field)))
31 struct wine_rb_entry
*parent
;
32 struct wine_rb_entry
*left
;
33 struct wine_rb_entry
*right
;
37 typedef int (*wine_rb_compare_func_t
)(const void *key
, const struct wine_rb_entry
*entry
);
41 wine_rb_compare_func_t compare
;
42 struct wine_rb_entry
*root
;
45 typedef void (wine_rb_traverse_func_t
)(struct wine_rb_entry
*entry
, void *context
);
47 #define WINE_RB_FLAG_RED 0x1
49 static inline int wine_rb_is_red(struct wine_rb_entry
*entry
)
51 return entry
&& (entry
->flags
& WINE_RB_FLAG_RED
);
54 static inline void wine_rb_rotate_left(struct wine_rb_tree
*tree
, struct wine_rb_entry
*e
)
56 struct wine_rb_entry
*right
= e
->right
;
60 else if (e
->parent
->left
== e
)
61 e
->parent
->left
= right
;
63 e
->parent
->right
= right
;
65 e
->right
= right
->left
;
66 if (e
->right
) e
->right
->parent
= e
;
68 right
->parent
= e
->parent
;
72 static inline void wine_rb_rotate_right(struct wine_rb_tree
*tree
, struct wine_rb_entry
*e
)
74 struct wine_rb_entry
*left
= e
->left
;
78 else if (e
->parent
->left
== e
)
79 e
->parent
->left
= left
;
81 e
->parent
->right
= left
;
83 e
->left
= left
->right
;
84 if (e
->left
) e
->left
->parent
= e
;
86 left
->parent
= e
->parent
;
90 static inline void wine_rb_flip_color(struct wine_rb_entry
*entry
)
92 entry
->flags
^= WINE_RB_FLAG_RED
;
93 entry
->left
->flags
^= WINE_RB_FLAG_RED
;
94 entry
->right
->flags
^= WINE_RB_FLAG_RED
;
97 static inline struct wine_rb_entry
*wine_rb_head(struct wine_rb_entry
*iter
)
99 if (!iter
) return NULL
;
100 while (iter
->left
) iter
= iter
->left
;
104 static inline struct wine_rb_entry
*wine_rb_tail(struct wine_rb_entry
*iter
)
106 if (!iter
) return NULL
;
107 while (iter
->right
) iter
= iter
->right
;
111 static inline struct wine_rb_entry
*wine_rb_next(struct wine_rb_entry
*iter
)
113 if (iter
->right
) return wine_rb_head(iter
->right
);
114 while (iter
->parent
&& iter
->parent
->right
== iter
) iter
= iter
->parent
;
118 static inline struct wine_rb_entry
*wine_rb_prev(struct wine_rb_entry
*iter
)
120 if (iter
->left
) return wine_rb_tail(iter
->left
);
121 while (iter
->parent
&& iter
->parent
->left
== iter
) iter
= iter
->parent
;
125 static inline struct wine_rb_entry
*wine_rb_postorder_head(struct wine_rb_entry
*iter
)
127 if (!iter
) return NULL
;
130 while (iter
->left
) iter
= iter
->left
;
131 if (!iter
->right
) return iter
;
136 static inline struct wine_rb_entry
*wine_rb_postorder_next(struct wine_rb_entry
*iter
)
138 if (!iter
->parent
) return NULL
;
139 if (iter
== iter
->parent
->right
|| !iter
->parent
->right
) return iter
->parent
;
140 return wine_rb_postorder_head(iter
->parent
->right
);
143 /* iterate through the tree */
144 #define WINE_RB_FOR_EACH(cursor, tree) \
145 for ((cursor) = wine_rb_head((tree)->root); (cursor); (cursor) = wine_rb_next(cursor))
147 /* iterate through the tree using a tree entry */
148 #define WINE_RB_FOR_EACH_ENTRY(elem, tree, type, field) \
149 for ((elem) = WINE_RB_ENTRY_VALUE(wine_rb_head((tree)->root), type, field); \
150 (elem) != WINE_RB_ENTRY_VALUE(0, type, field); \
151 (elem) = WINE_RB_ENTRY_VALUE(wine_rb_next(&elem->field), type, field))
153 /* iterate through the tree using using postorder, making it safe to free the entry */
154 #define WINE_RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \
155 for ((cursor) = wine_rb_postorder_head((tree)->root); \
156 (cursor) && (((cursor2) = wine_rb_postorder_next(cursor)) || 1); \
157 (cursor) = (cursor2))
159 /* iterate through the tree using a tree entry and postorder, making it safe to free the entry */
160 #define WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \
161 for ((elem) = WINE_RB_ENTRY_VALUE(wine_rb_postorder_head((tree)->root), type, field); \
162 (elem) != WINE_RB_ENTRY_VALUE(0, type, field) \
163 && (((elem2) = WINE_RB_ENTRY_VALUE(wine_rb_postorder_next(&(elem)->field), type, field)) || 1); \
167 static inline void wine_rb_postorder(struct wine_rb_tree
*tree
, wine_rb_traverse_func_t
*callback
, void *context
)
169 struct wine_rb_entry
*iter
, *next
;
170 WINE_RB_FOR_EACH_DESTRUCTOR(iter
, next
, tree
) callback(iter
, context
);
173 static inline void wine_rb_init(struct wine_rb_tree
*tree
, wine_rb_compare_func_t compare
)
175 tree
->compare
= compare
;
179 static inline void wine_rb_for_each_entry(struct wine_rb_tree
*tree
, wine_rb_traverse_func_t
*callback
, void *context
)
181 struct wine_rb_entry
*iter
;
182 WINE_RB_FOR_EACH(iter
, tree
) callback(iter
, context
);
185 static inline void wine_rb_clear(struct wine_rb_tree
*tree
, wine_rb_traverse_func_t
*callback
, void *context
)
187 /* Note that we use postorder here because the callback will likely free the entry. */
188 if (callback
) wine_rb_postorder(tree
, callback
, context
);
192 static inline void wine_rb_destroy(struct wine_rb_tree
*tree
, wine_rb_traverse_func_t
*callback
, void *context
)
194 wine_rb_clear(tree
, callback
, context
);
197 static inline struct wine_rb_entry
*wine_rb_get(const struct wine_rb_tree
*tree
, const void *key
)
199 struct wine_rb_entry
*entry
= tree
->root
;
202 int c
= tree
->compare(key
, entry
);
203 if (!c
) return entry
;
204 entry
= c
< 0 ? entry
->left
: entry
->right
;
209 static inline int wine_rb_put(struct wine_rb_tree
*tree
, const void *key
, struct wine_rb_entry
*entry
)
211 struct wine_rb_entry
**iter
= &tree
->root
, *parent
= tree
->root
;
218 c
= tree
->compare(key
, parent
);
220 else if (c
< 0) iter
= &parent
->left
;
221 else iter
= &parent
->right
;
224 entry
->flags
= WINE_RB_FLAG_RED
;
225 entry
->parent
= parent
;
230 while (wine_rb_is_red(entry
->parent
))
232 if (entry
->parent
== entry
->parent
->parent
->left
)
234 if (wine_rb_is_red(entry
->parent
->parent
->right
))
236 wine_rb_flip_color(entry
->parent
->parent
);
237 entry
= entry
->parent
->parent
;
241 if (entry
== entry
->parent
->right
)
243 entry
= entry
->parent
;
244 wine_rb_rotate_left(tree
, entry
);
246 entry
->parent
->flags
&= ~WINE_RB_FLAG_RED
;
247 entry
->parent
->parent
->flags
|= WINE_RB_FLAG_RED
;
248 wine_rb_rotate_right(tree
, entry
->parent
->parent
);
253 if (wine_rb_is_red(entry
->parent
->parent
->left
))
255 wine_rb_flip_color(entry
->parent
->parent
);
256 entry
= entry
->parent
->parent
;
260 if (entry
== entry
->parent
->left
)
262 entry
= entry
->parent
;
263 wine_rb_rotate_right(tree
, entry
);
265 entry
->parent
->flags
&= ~WINE_RB_FLAG_RED
;
266 entry
->parent
->parent
->flags
|= WINE_RB_FLAG_RED
;
267 wine_rb_rotate_left(tree
, entry
->parent
->parent
);
272 tree
->root
->flags
&= ~WINE_RB_FLAG_RED
;
277 static inline void wine_rb_remove(struct wine_rb_tree
*tree
, struct wine_rb_entry
*entry
)
279 struct wine_rb_entry
*iter
, *child
, *parent
, *w
;
282 if (entry
->right
&& entry
->left
)
283 for(iter
= entry
->right
; iter
->left
; iter
= iter
->left
);
287 child
= iter
->left
? iter
->left
: iter
->right
;
291 else if (iter
== iter
->parent
->left
)
292 iter
->parent
->left
= child
;
294 iter
->parent
->right
= child
;
296 if (child
) child
->parent
= iter
->parent
;
297 parent
= iter
->parent
;
299 need_fixup
= !wine_rb_is_red(iter
);
306 else if (entry
== iter
->parent
->left
)
307 iter
->parent
->left
= iter
;
309 iter
->parent
->right
= iter
;
311 if (iter
->right
) iter
->right
->parent
= iter
;
312 if (iter
->left
) iter
->left
->parent
= iter
;
313 if (parent
== entry
) parent
= iter
;
318 while (parent
&& !wine_rb_is_red(child
))
320 if (child
== parent
->left
)
323 if (wine_rb_is_red(w
))
325 w
->flags
&= ~WINE_RB_FLAG_RED
;
326 parent
->flags
|= WINE_RB_FLAG_RED
;
327 wine_rb_rotate_left(tree
, parent
);
330 if (wine_rb_is_red(w
->left
) || wine_rb_is_red(w
->right
))
332 if (!wine_rb_is_red(w
->right
))
334 w
->left
->flags
&= ~WINE_RB_FLAG_RED
;
335 w
->flags
|= WINE_RB_FLAG_RED
;
336 wine_rb_rotate_right(tree
, w
);
339 w
->flags
= (w
->flags
& ~WINE_RB_FLAG_RED
) | (parent
->flags
& WINE_RB_FLAG_RED
);
340 parent
->flags
&= ~WINE_RB_FLAG_RED
;
342 w
->right
->flags
&= ~WINE_RB_FLAG_RED
;
343 wine_rb_rotate_left(tree
, parent
);
351 if (wine_rb_is_red(w
))
353 w
->flags
&= ~WINE_RB_FLAG_RED
;
354 parent
->flags
|= WINE_RB_FLAG_RED
;
355 wine_rb_rotate_right(tree
, parent
);
358 if (wine_rb_is_red(w
->left
) || wine_rb_is_red(w
->right
))
360 if (!wine_rb_is_red(w
->left
))
362 w
->right
->flags
&= ~WINE_RB_FLAG_RED
;
363 w
->flags
|= WINE_RB_FLAG_RED
;
364 wine_rb_rotate_left(tree
, w
);
367 w
->flags
= (w
->flags
& ~WINE_RB_FLAG_RED
) | (parent
->flags
& WINE_RB_FLAG_RED
);
368 parent
->flags
&= ~WINE_RB_FLAG_RED
;
370 w
->left
->flags
&= ~WINE_RB_FLAG_RED
;
371 wine_rb_rotate_right(tree
, parent
);
376 w
->flags
|= WINE_RB_FLAG_RED
;
378 parent
= child
->parent
;
380 if (child
) child
->flags
&= ~WINE_RB_FLAG_RED
;
383 if (tree
->root
) tree
->root
->flags
&= ~WINE_RB_FLAG_RED
;
386 static inline void wine_rb_remove_key(struct wine_rb_tree
*tree
, const void *key
)
388 struct wine_rb_entry
*entry
= wine_rb_get(tree
, key
);
389 if (entry
) wine_rb_remove(tree
, entry
);
392 #endif /* __WINE_WINE_RBTREE_H */