]>
git.proxmox.com Git - mirror_frr.git/blob - lib/openbsd-tree.h
1 // SPDX-License-Identifier: ISC AND BSD-2-Clause
2 /* $OpenBSD: tree.h,v 1.14 2015/05/25 03:07:49 deraadt Exp $ */
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
15 * This file defines data structures for different types of trees:
16 * splay trees and red-black trees.
18 * A splay tree is a self-organizing data structure. Every operation
19 * on the tree causes a splay to happen. The splay moves the requested
20 * node to the root of the tree and partly rebalances it.
22 * This has the benefit that request locality causes faster lookups as
23 * the requested nodes move to the top of the tree. On the other hand,
24 * every lookup causes memory writes.
26 * The Balance Theorem bounds the total access time for m operations
27 * and n inserts on an initially empty tree as O((m + n)lg n). The
28 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
30 * A red-black tree is a binary search tree with the node color as an
31 * extra attribute. It fulfills a set of conditions:
32 * - every search path from the root to a leaf consists of the
33 * same number of black nodes,
34 * - each red node (except for the root) has a black parent,
35 * - each leaf node is black.
37 * Every operation on a red-black tree is bounded as O(lg n).
38 * The maximum height of a red-black tree is 2lg (n+1).
41 #define SPLAY_HEAD(name, type) \
43 struct type *sph_root; /* root of the tree */ \
46 #define SPLAY_INITIALIZER(root) \
51 #define SPLAY_INIT(root) \
53 (root)->sph_root = NULL; \
56 #define SPLAY_ENTRY(type) \
58 struct type *spe_left; /* left element */ \
59 struct type *spe_right; /* right element */ \
62 #define SPLAY_LEFT(elm, field) (elm)->field.spe_left
63 #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
64 #define SPLAY_ROOT(head) (head)->sph_root
65 #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
67 /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
68 #define SPLAY_ROTATE_RIGHT(head, tmp, field) \
70 SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
71 SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
72 (head)->sph_root = tmp; \
75 #define SPLAY_ROTATE_LEFT(head, tmp, field) \
77 SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
78 SPLAY_LEFT(tmp, field) = (head)->sph_root; \
79 (head)->sph_root = tmp; \
82 #define SPLAY_LINKLEFT(head, tmp, field) \
84 SPLAY_LEFT(tmp, field) = (head)->sph_root; \
85 tmp = (head)->sph_root; \
86 (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
89 #define SPLAY_LINKRIGHT(head, tmp, field) \
91 SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
92 tmp = (head)->sph_root; \
93 (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
96 #define SPLAY_ASSEMBLE(head, node, left, right, field) \
98 SPLAY_RIGHT(left, field) = \
99 SPLAY_LEFT((head)->sph_root, field); \
100 SPLAY_LEFT(right, field) = \
101 SPLAY_RIGHT((head)->sph_root, field); \
102 SPLAY_LEFT((head)->sph_root, field) = \
103 SPLAY_RIGHT(node, field); \
104 SPLAY_RIGHT((head)->sph_root, field) = \
105 SPLAY_LEFT(node, field); \
108 /* Generates prototypes and inline functions */
110 #define SPLAY_PROTOTYPE(name, type, field, cmp) \
111 void name##_SPLAY(struct name *, struct type *); \
112 void name##_SPLAY_MINMAX(struct name *, int); \
113 struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
114 struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
116 /* Finds the node with the same key as elm */ \
117 static __inline struct type *name##_SPLAY_FIND(struct name *head, \
120 if (SPLAY_EMPTY(head)) \
122 name##_SPLAY(head, elm); \
123 if ((cmp)(elm, (head)->sph_root) == 0) \
124 return (head->sph_root); \
128 static __inline struct type *name##_SPLAY_NEXT(struct name *head, \
131 name##_SPLAY(head, elm); \
132 if (SPLAY_RIGHT(elm, field) != NULL) { \
133 elm = SPLAY_RIGHT(elm, field); \
134 while (SPLAY_LEFT(elm, field) != NULL) { \
135 elm = SPLAY_LEFT(elm, field); \
142 static __inline struct type *name##_SPLAY_MIN_MAX(struct name *head, \
145 name##_SPLAY_MINMAX(head, val); \
146 return (SPLAY_ROOT(head)); \
149 /* Main splay operation.
150 * Moves node close to the key of elm to top
152 #define SPLAY_GENERATE(name, type, field, cmp) \
153 struct type *name##_SPLAY_INSERT(struct name *head, struct type *elm) \
155 if (SPLAY_EMPTY(head)) { \
156 SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = \
160 name##_SPLAY(head, elm); \
161 __comp = (cmp)(elm, (head)->sph_root); \
163 SPLAY_LEFT(elm, field) = \
164 SPLAY_LEFT((head)->sph_root, field); \
165 SPLAY_RIGHT(elm, field) = (head)->sph_root; \
166 SPLAY_LEFT((head)->sph_root, field) = NULL; \
167 } else if (__comp > 0) { \
168 SPLAY_RIGHT(elm, field) = \
169 SPLAY_RIGHT((head)->sph_root, field); \
170 SPLAY_LEFT(elm, field) = (head)->sph_root; \
171 SPLAY_RIGHT((head)->sph_root, field) = NULL; \
173 return ((head)->sph_root); \
175 (head)->sph_root = (elm); \
179 struct type *name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
181 struct type *__tmp; \
182 if (SPLAY_EMPTY(head)) \
184 name##_SPLAY(head, elm); \
185 if ((cmp)(elm, (head)->sph_root) == 0) { \
186 if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
188 SPLAY_RIGHT((head)->sph_root, field); \
190 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
192 SPLAY_LEFT((head)->sph_root, field); \
193 name##_SPLAY(head, elm); \
194 SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
201 void name##_SPLAY(struct name *head, struct type *elm) \
203 struct type __node, *__left, *__right, *__tmp; \
206 SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
208 __left = __right = &__node; \
210 while ((__comp = (cmp)(elm, (head)->sph_root))) { \
212 __tmp = SPLAY_LEFT((head)->sph_root, field); \
215 if ((cmp)(elm, __tmp) < 0) { \
216 SPLAY_ROTATE_RIGHT(head, __tmp, \
218 if (SPLAY_LEFT((head)->sph_root, \
223 SPLAY_LINKLEFT(head, __right, field); \
224 } else if (__comp > 0) { \
225 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
228 if ((cmp)(elm, __tmp) > 0) { \
229 SPLAY_ROTATE_LEFT(head, __tmp, field); \
230 if (SPLAY_RIGHT((head)->sph_root, \
235 SPLAY_LINKRIGHT(head, __left, field); \
238 SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
241 /* Splay with either the minimum or the maximum element \
242 * Used to find minimum or maximum element in tree. \
244 void name##_SPLAY_MINMAX(struct name *head, int __comp) \
246 struct type __node, *__left, *__right, *__tmp; \
248 SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
250 __left = __right = &__node; \
254 __tmp = SPLAY_LEFT((head)->sph_root, field); \
258 SPLAY_ROTATE_RIGHT(head, __tmp, \
260 if (SPLAY_LEFT((head)->sph_root, \
265 SPLAY_LINKLEFT(head, __right, field); \
266 } else if (__comp > 0) { \
267 __tmp = SPLAY_RIGHT((head)->sph_root, field); \
271 SPLAY_ROTATE_LEFT(head, __tmp, field); \
272 if (SPLAY_RIGHT((head)->sph_root, \
277 SPLAY_LINKRIGHT(head, __left, field); \
280 SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
283 #define SPLAY_NEGINF -1
286 #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
287 #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
288 #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
289 #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
290 #define SPLAY_MIN(name, x) \
291 (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
292 #define SPLAY_MAX(name, x) \
293 (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
295 #define SPLAY_FOREACH(x, name, head) \
296 for ((x) = SPLAY_MIN(name, head); (x) != NULL; \
297 (x) = SPLAY_NEXT(name, head, x))
300 * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
307 int (*t_compare
)(const void *, const void *);
308 void (*t_augment
)(void *);
309 unsigned int t_offset
; /* offset of rb_entry in type */
313 struct rb_entry
*rbt_root
;
317 struct rb_entry
*rbt_parent
;
318 struct rb_entry
*rbt_left
;
319 struct rb_entry
*rbt_right
;
320 unsigned int rbt_color
;
323 #define RB_HEAD(_name, _type) \
325 struct rbt_tree rbh_root; \
328 #define RB_ENTRY(_type) struct rb_entry
330 static inline void _rb_init(struct rbt_tree
*rbt
)
332 rbt
->rbt_root
= NULL
;
335 static inline int _rb_empty(const struct rbt_tree
*rbt
)
337 return (rbt
->rbt_root
== NULL
);
340 void *_rb_insert(const struct rb_type
*, struct rbt_tree
*, void *);
341 void *_rb_remove(const struct rb_type
*, struct rbt_tree
*, void *);
342 void *_rb_find(const struct rb_type
*, const struct rbt_tree
*, const void *);
343 void *_rb_nfind(const struct rb_type
*, const struct rbt_tree
*, const void *);
344 void *_rb_root(const struct rb_type
*, const struct rbt_tree
*);
345 void *_rb_min(const struct rb_type
*, const struct rbt_tree
*);
346 void *_rb_max(const struct rb_type
*, const struct rbt_tree
*);
347 void *_rb_next(const struct rb_type
*, void *);
348 void *_rb_prev(const struct rb_type
*, void *);
349 void *_rb_left(const struct rb_type
*, void *);
350 void *_rb_right(const struct rb_type
*, void *);
351 void *_rb_parent(const struct rb_type
*, void *);
352 void _rb_set_left(const struct rb_type
*, void *, void *);
353 void _rb_set_right(const struct rb_type
*, void *, void *);
354 void _rb_set_parent(const struct rb_type
*, void *, void *);
355 void _rb_poison(const struct rb_type
*, void *, unsigned long);
356 int _rb_check(const struct rb_type
*, void *, unsigned long);
358 #define RB_INITIALIZER(_head) { { NULL } }
360 #define RB_PROTOTYPE(_name, _type, _field, _cmp) \
361 extern const struct rb_type *const _name##_RB_TYPE; \
363 __attribute__((__unused__)) static inline void _name##_RB_INIT( \
364 struct _name *head) \
366 _rb_init(&head->rbh_root); \
369 __attribute__((__unused__)) static inline struct _type \
370 *_name##_RB_INSERT(struct _name *head, struct _type *elm) \
372 return (struct _type *)_rb_insert(_name##_RB_TYPE, \
373 &head->rbh_root, elm); \
376 __attribute__((__unused__)) static inline struct _type \
377 *_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
379 return (struct _type *)_rb_remove(_name##_RB_TYPE, \
380 &head->rbh_root, elm); \
383 __attribute__((__unused__)) static inline struct _type \
384 *_name##_RB_FIND(const struct _name *head, \
385 const struct _type *key) \
387 return (struct _type *)_rb_find(_name##_RB_TYPE, \
388 &head->rbh_root, key); \
391 __attribute__((__unused__)) static inline struct _type \
392 *_name##_RB_NFIND(const struct _name *head, \
393 const struct _type *key) \
395 return (struct _type *)_rb_nfind(_name##_RB_TYPE, \
396 &head->rbh_root, key); \
399 __attribute__((__unused__)) static inline struct _type \
400 *_name##_RB_ROOT(const struct _name *head) \
402 return (struct _type *)_rb_root(_name##_RB_TYPE, \
406 __attribute__((__unused__)) static inline int _name##_RB_EMPTY( \
407 const struct _name *head) \
409 return _rb_empty(&head->rbh_root); \
412 __attribute__((__unused__)) static inline struct _type \
413 *_name##_RB_MIN(const struct _name *head) \
415 return (struct _type *)_rb_min(_name##_RB_TYPE, \
419 __attribute__((__unused__)) static inline struct _type \
420 *_name##_RB_MAX(const struct _name *head) \
422 return (struct _type *)_rb_max(_name##_RB_TYPE, \
426 __attribute__((__unused__)) static inline struct _type \
427 *_name##_RB_NEXT(struct _type *elm) \
429 return (struct _type *)_rb_next(_name##_RB_TYPE, elm); \
432 __attribute__((__unused__)) static inline struct _type \
433 *_name##_RB_PREV(struct _type *elm) \
435 return (struct _type *)_rb_prev(_name##_RB_TYPE, elm); \
438 __attribute__((__unused__)) static inline struct _type \
439 *_name##_RB_LEFT(struct _type *elm) \
441 return (struct _type *)_rb_left(_name##_RB_TYPE, elm); \
444 __attribute__((__unused__)) static inline struct _type \
445 *_name##_RB_RIGHT(struct _type *elm) \
447 return (struct _type *)_rb_right(_name##_RB_TYPE, elm); \
450 __attribute__((__unused__)) static inline struct _type \
451 *_name##_RB_PARENT(struct _type *elm) \
453 return (struct _type *)_rb_parent(_name##_RB_TYPE, elm); \
456 __attribute__((__unused__)) static inline void _name##_RB_SET_LEFT( \
457 struct _type *elm, struct _type *left) \
459 _rb_set_left(_name##_RB_TYPE, elm, left); \
462 __attribute__((__unused__)) static inline void _name##_RB_SET_RIGHT( \
463 struct _type *elm, struct _type *right) \
465 _rb_set_right(_name##_RB_TYPE, elm, right); \
468 __attribute__((__unused__)) static inline void _name##_RB_SET_PARENT( \
469 struct _type *elm, struct _type *parent) \
471 _rb_set_parent(_name##_RB_TYPE, elm, parent); \
474 __attribute__((__unused__)) static inline void _name##_RB_POISON( \
475 struct _type *elm, unsigned long poison) \
477 _rb_poison(_name##_RB_TYPE, elm, poison); \
480 __attribute__((__unused__)) static inline int _name##_RB_CHECK( \
481 struct _type *elm, unsigned long poison) \
483 return _rb_check(_name##_RB_TYPE, elm, poison); \
486 #define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
487 static int _name##_RB_COMPARE(const void *lptr, const void *rptr) \
489 const struct _type *l = lptr, *r = rptr; \
492 static const struct rb_type _name##_RB_INFO = { \
493 _name##_RB_COMPARE, _aug, offsetof(struct _type, _field), \
495 const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO;
497 #define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
498 static void _name##_RB_AUGMENT(void *ptr) \
500 struct _type *p = ptr; \
503 RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
505 #define RB_GENERATE(_name, _type, _field, _cmp) \
506 RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
508 #define RB_INIT(_name, _head) _name##_RB_INIT(_head)
509 #define RB_INSERT(_name, _head, _elm) _name##_RB_INSERT(_head, _elm)
510 #define RB_REMOVE(_name, _head, _elm) _name##_RB_REMOVE(_head, _elm)
511 #define RB_FIND(_name, _head, _key) _name##_RB_FIND(_head, _key)
512 #define RB_NFIND(_name, _head, _key) _name##_RB_NFIND(_head, _key)
513 #define RB_ROOT(_name, _head) _name##_RB_ROOT(_head)
514 #define RB_EMPTY(_name, _head) _name##_RB_EMPTY(_head)
515 #define RB_MIN(_name, _head) _name##_RB_MIN(_head)
516 #define RB_MAX(_name, _head) _name##_RB_MAX(_head)
517 #define RB_NEXT(_name, _elm) _name##_RB_NEXT(_elm)
518 #define RB_PREV(_name, _elm) _name##_RB_PREV(_elm)
519 #define RB_LEFT(_name, _elm) _name##_RB_LEFT(_elm)
520 #define RB_RIGHT(_name, _elm) _name##_RB_RIGHT(_elm)
521 #define RB_PARENT(_name, _elm) _name##_RB_PARENT(_elm)
522 #define RB_SET_LEFT(_name, _elm, _l) _name##_RB_SET_LEFT(_elm, _l)
523 #define RB_SET_RIGHT(_name, _elm, _r) _name##_RB_SET_RIGHT(_elm, _r)
524 #define RB_SET_PARENT(_name, _elm, _p) _name##_RB_SET_PARENT(_elm, _p)
525 #define RB_POISON(_name, _elm, _p) _name##_RB_POISON(_elm, _p)
526 #define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p)
528 #define RB_FOREACH(_e, _name, _head) \
529 for ((_e) = RB_MIN(_name, (_head)); (_e) != NULL; \
530 (_e) = RB_NEXT(_name, (_e)))
532 #define RB_FOREACH_SAFE(_e, _name, _head, _n) \
533 for ((_e) = RB_MIN(_name, (_head)); \
534 (_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); (_e) = (_n))
536 #define RB_FOREACH_REVERSE(_e, _name, _head) \
537 for ((_e) = RB_MAX(_name, (_head)); (_e) != NULL; \
538 (_e) = RB_PREV(_name, (_e)))
540 #define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
541 for ((_e) = RB_MAX(_name, (_head)); \
542 (_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); (_e) = (_n))
548 #endif /* _SYS_TREE_H_ */