17ba890bfSKyungmin Park /*
27ba890bfSKyungmin Park Red Black Trees
37ba890bfSKyungmin Park (C) 1999 Andrea Arcangeli <andrea@suse.de>
47ba890bfSKyungmin Park
51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
67ba890bfSKyungmin Park
77ba890bfSKyungmin Park linux/include/linux/rbtree.h
87ba890bfSKyungmin Park
97ba890bfSKyungmin Park To use rbtrees you'll have to implement your own insert and search cores.
107ba890bfSKyungmin Park This will avoid us to use callbacks and to drop drammatically performances.
117ba890bfSKyungmin Park I know it's not the cleaner way, but in C (not in C++) to get
127ba890bfSKyungmin Park performances and genericity...
137ba890bfSKyungmin Park
14*9dd228b5SHeiko Schocher See Documentation/rbtree.txt for documentation and samples.
157ba890bfSKyungmin Park */
167ba890bfSKyungmin Park
177ba890bfSKyungmin Park #ifndef _LINUX_RBTREE_H
187ba890bfSKyungmin Park #define _LINUX_RBTREE_H
197ba890bfSKyungmin Park
20*9dd228b5SHeiko Schocher #ifndef __UBOOT__
21*9dd228b5SHeiko Schocher #include <linux/kernel.h>
22*9dd228b5SHeiko Schocher #endif
237ba890bfSKyungmin Park #include <linux/stddef.h>
247ba890bfSKyungmin Park
25*9dd228b5SHeiko Schocher struct rb_node {
26*9dd228b5SHeiko Schocher unsigned long __rb_parent_color;
277ba890bfSKyungmin Park struct rb_node *rb_right;
287ba890bfSKyungmin Park struct rb_node *rb_left;
297ba890bfSKyungmin Park } __attribute__((aligned(sizeof(long))));
307ba890bfSKyungmin Park /* The alignment might seem pointless, but allegedly CRIS needs it */
317ba890bfSKyungmin Park
32*9dd228b5SHeiko Schocher struct rb_root {
337ba890bfSKyungmin Park struct rb_node *rb_node;
347ba890bfSKyungmin Park };
357ba890bfSKyungmin Park
367ba890bfSKyungmin Park
37*9dd228b5SHeiko Schocher #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
387ba890bfSKyungmin Park
397ba890bfSKyungmin Park #define RB_ROOT (struct rb_root) { NULL, }
407ba890bfSKyungmin Park #define rb_entry(ptr, type, member) container_of(ptr, type, member)
417ba890bfSKyungmin Park
427ba890bfSKyungmin Park #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
43*9dd228b5SHeiko Schocher
44*9dd228b5SHeiko Schocher /* 'empty' nodes are nodes that are known not to be inserted in an rbree */
45*9dd228b5SHeiko Schocher #define RB_EMPTY_NODE(node) \
46*9dd228b5SHeiko Schocher ((node)->__rb_parent_color == (unsigned long)(node))
47*9dd228b5SHeiko Schocher #define RB_CLEAR_NODE(node) \
48*9dd228b5SHeiko Schocher ((node)->__rb_parent_color = (unsigned long)(node))
49*9dd228b5SHeiko Schocher
507ba890bfSKyungmin Park
517ba890bfSKyungmin Park extern void rb_insert_color(struct rb_node *, struct rb_root *);
527ba890bfSKyungmin Park extern void rb_erase(struct rb_node *, struct rb_root *);
537ba890bfSKyungmin Park
54*9dd228b5SHeiko Schocher
557ba890bfSKyungmin Park /* Find logical next and previous nodes in a tree */
56*9dd228b5SHeiko Schocher extern struct rb_node *rb_next(const struct rb_node *);
57*9dd228b5SHeiko Schocher extern struct rb_node *rb_prev(const struct rb_node *);
58*9dd228b5SHeiko Schocher extern struct rb_node *rb_first(const struct rb_root *);
59*9dd228b5SHeiko Schocher extern struct rb_node *rb_last(const struct rb_root *);
60*9dd228b5SHeiko Schocher
61*9dd228b5SHeiko Schocher /* Postorder iteration - always visit the parent after its children */
62*9dd228b5SHeiko Schocher extern struct rb_node *rb_first_postorder(const struct rb_root *);
63*9dd228b5SHeiko Schocher extern struct rb_node *rb_next_postorder(const struct rb_node *);
647ba890bfSKyungmin Park
657ba890bfSKyungmin Park /* Fast replacement of a single node without remove/rebalance/add/rebalance */
667ba890bfSKyungmin Park extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
677ba890bfSKyungmin Park struct rb_root *root);
687ba890bfSKyungmin Park
rb_link_node(struct rb_node * node,struct rb_node * parent,struct rb_node ** rb_link)697ba890bfSKyungmin Park static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
707ba890bfSKyungmin Park struct rb_node ** rb_link)
717ba890bfSKyungmin Park {
72*9dd228b5SHeiko Schocher node->__rb_parent_color = (unsigned long)parent;
737ba890bfSKyungmin Park node->rb_left = node->rb_right = NULL;
747ba890bfSKyungmin Park
757ba890bfSKyungmin Park *rb_link = node;
767ba890bfSKyungmin Park }
777ba890bfSKyungmin Park
78*9dd228b5SHeiko Schocher #define rb_entry_safe(ptr, type, member) \
79*9dd228b5SHeiko Schocher ({ typeof(ptr) ____ptr = (ptr); \
80*9dd228b5SHeiko Schocher ____ptr ? rb_entry(____ptr, type, member) : NULL; \
81*9dd228b5SHeiko Schocher })
82*9dd228b5SHeiko Schocher
83*9dd228b5SHeiko Schocher /**
84*9dd228b5SHeiko Schocher * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of
85*9dd228b5SHeiko Schocher * given type safe against removal of rb_node entry
86*9dd228b5SHeiko Schocher *
87*9dd228b5SHeiko Schocher * @pos: the 'type *' to use as a loop cursor.
88*9dd228b5SHeiko Schocher * @n: another 'type *' to use as temporary storage
89*9dd228b5SHeiko Schocher * @root: 'rb_root *' of the rbtree.
90*9dd228b5SHeiko Schocher * @field: the name of the rb_node field within 'type'.
91*9dd228b5SHeiko Schocher */
92*9dd228b5SHeiko Schocher #define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
93*9dd228b5SHeiko Schocher for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
94*9dd228b5SHeiko Schocher pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
95*9dd228b5SHeiko Schocher typeof(*pos), field); 1; }); \
96*9dd228b5SHeiko Schocher pos = n)
97*9dd228b5SHeiko Schocher
987ba890bfSKyungmin Park #endif /* _LINUX_RBTREE_H */
99