xref: /openbmc/u-boot/include/linux/rbtree.h (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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