1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
27ba890bfSKyungmin Park /*
37ba890bfSKyungmin Park Red Black Trees
47ba890bfSKyungmin Park (C) 1999 Andrea Arcangeli <andrea@suse.de>
57ba890bfSKyungmin Park
67ba890bfSKyungmin Park linux/include/linux/rbtree.h
77ba890bfSKyungmin Park
87ba890bfSKyungmin Park To use rbtrees you'll have to implement your own insert and search cores.
97ba890bfSKyungmin Park This will avoid us to use callbacks and to drop drammatically performances.
107ba890bfSKyungmin Park I know it's not the cleaner way, but in C (not in C++) to get
117ba890bfSKyungmin Park performances and genericity...
127ba890bfSKyungmin Park
139dd228b5SHeiko Schocher See Documentation/rbtree.txt for documentation and samples.
147ba890bfSKyungmin Park */
157ba890bfSKyungmin Park
167ba890bfSKyungmin Park #ifndef _LINUX_RBTREE_H
177ba890bfSKyungmin Park #define _LINUX_RBTREE_H
187ba890bfSKyungmin Park
199dd228b5SHeiko Schocher #ifndef __UBOOT__
209dd228b5SHeiko Schocher #include <linux/kernel.h>
219dd228b5SHeiko Schocher #endif
227ba890bfSKyungmin Park #include <linux/stddef.h>
237ba890bfSKyungmin Park
249dd228b5SHeiko Schocher struct rb_node {
259dd228b5SHeiko Schocher unsigned long __rb_parent_color;
267ba890bfSKyungmin Park struct rb_node *rb_right;
277ba890bfSKyungmin Park struct rb_node *rb_left;
287ba890bfSKyungmin Park } __attribute__((aligned(sizeof(long))));
297ba890bfSKyungmin Park /* The alignment might seem pointless, but allegedly CRIS needs it */
307ba890bfSKyungmin Park
319dd228b5SHeiko Schocher struct rb_root {
327ba890bfSKyungmin Park struct rb_node *rb_node;
337ba890bfSKyungmin Park };
347ba890bfSKyungmin Park
357ba890bfSKyungmin Park
369dd228b5SHeiko Schocher #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
377ba890bfSKyungmin Park
387ba890bfSKyungmin Park #define RB_ROOT (struct rb_root) { NULL, }
397ba890bfSKyungmin Park #define rb_entry(ptr, type, member) container_of(ptr, type, member)
407ba890bfSKyungmin Park
417ba890bfSKyungmin Park #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
429dd228b5SHeiko Schocher
439dd228b5SHeiko Schocher /* 'empty' nodes are nodes that are known not to be inserted in an rbree */
449dd228b5SHeiko Schocher #define RB_EMPTY_NODE(node) \
459dd228b5SHeiko Schocher ((node)->__rb_parent_color == (unsigned long)(node))
469dd228b5SHeiko Schocher #define RB_CLEAR_NODE(node) \
479dd228b5SHeiko Schocher ((node)->__rb_parent_color = (unsigned long)(node))
489dd228b5SHeiko Schocher
497ba890bfSKyungmin Park
507ba890bfSKyungmin Park extern void rb_insert_color(struct rb_node *, struct rb_root *);
517ba890bfSKyungmin Park extern void rb_erase(struct rb_node *, struct rb_root *);
527ba890bfSKyungmin Park
539dd228b5SHeiko Schocher
547ba890bfSKyungmin Park /* Find logical next and previous nodes in a tree */
559dd228b5SHeiko Schocher extern struct rb_node *rb_next(const struct rb_node *);
569dd228b5SHeiko Schocher extern struct rb_node *rb_prev(const struct rb_node *);
579dd228b5SHeiko Schocher extern struct rb_node *rb_first(const struct rb_root *);
589dd228b5SHeiko Schocher extern struct rb_node *rb_last(const struct rb_root *);
599dd228b5SHeiko Schocher
609dd228b5SHeiko Schocher /* Postorder iteration - always visit the parent after its children */
619dd228b5SHeiko Schocher extern struct rb_node *rb_first_postorder(const struct rb_root *);
629dd228b5SHeiko Schocher extern struct rb_node *rb_next_postorder(const struct rb_node *);
637ba890bfSKyungmin Park
647ba890bfSKyungmin Park /* Fast replacement of a single node without remove/rebalance/add/rebalance */
657ba890bfSKyungmin Park extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
667ba890bfSKyungmin Park struct rb_root *root);
677ba890bfSKyungmin Park
rb_link_node(struct rb_node * node,struct rb_node * parent,struct rb_node ** rb_link)687ba890bfSKyungmin Park static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
697ba890bfSKyungmin Park struct rb_node ** rb_link)
707ba890bfSKyungmin Park {
719dd228b5SHeiko Schocher node->__rb_parent_color = (unsigned long)parent;
727ba890bfSKyungmin Park node->rb_left = node->rb_right = NULL;
737ba890bfSKyungmin Park
747ba890bfSKyungmin Park *rb_link = node;
757ba890bfSKyungmin Park }
767ba890bfSKyungmin Park
779dd228b5SHeiko Schocher #define rb_entry_safe(ptr, type, member) \
789dd228b5SHeiko Schocher ({ typeof(ptr) ____ptr = (ptr); \
799dd228b5SHeiko Schocher ____ptr ? rb_entry(____ptr, type, member) : NULL; \
809dd228b5SHeiko Schocher })
819dd228b5SHeiko Schocher
829dd228b5SHeiko Schocher /**
839dd228b5SHeiko Schocher * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of
849dd228b5SHeiko Schocher * given type safe against removal of rb_node entry
859dd228b5SHeiko Schocher *
869dd228b5SHeiko Schocher * @pos: the 'type *' to use as a loop cursor.
879dd228b5SHeiko Schocher * @n: another 'type *' to use as temporary storage
889dd228b5SHeiko Schocher * @root: 'rb_root *' of the rbtree.
899dd228b5SHeiko Schocher * @field: the name of the rb_node field within 'type'.
909dd228b5SHeiko Schocher */
919dd228b5SHeiko Schocher #define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
929dd228b5SHeiko Schocher for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
939dd228b5SHeiko Schocher pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
949dd228b5SHeiko Schocher typeof(*pos), field); 1; }); \
959dd228b5SHeiko Schocher pos = n)
969dd228b5SHeiko Schocher
977ba890bfSKyungmin Park #endif /* _LINUX_RBTREE_H */
98