xref: /rk3399_rockchip-uboot/include/linux/rbtree.h (revision 42817eb85de1d7dec399c75dbd133ea6b5351a72)
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