xref: /Universal-ctags/main/rbtree.h (revision e9626ab137cf0cb58e112667ee01430cae6db3e7)
1b8d30947SMasatake YAMATO /*
2b8d30947SMasatake YAMATO  * =============================================================================
3b8d30947SMasatake YAMATO  *
4b8d30947SMasatake YAMATO  *       Filename:  rbtree.h
5b8d30947SMasatake YAMATO  *
6b8d30947SMasatake YAMATO  *    Description:  rbtree(Red-Black tree) implementation adapted from linux
7b8d30947SMasatake YAMATO  *                  kernel thus can be used in userspace c program.
8b8d30947SMasatake YAMATO  *
9b8d30947SMasatake YAMATO  *        Created:  09/02/2012 11:36:11 PM
10b8d30947SMasatake YAMATO  *
11b8d30947SMasatake YAMATO  *         Author:  Fu Haiping (forhappy), haipingf@gmail.com
12b8d30947SMasatake YAMATO  *        Company:  ICT ( Institute Of Computing Technology, CAS )
13b8d30947SMasatake YAMATO  *
14b8d30947SMasatake YAMATO  * =============================================================================
15b8d30947SMasatake YAMATO  */
16b8d30947SMasatake YAMATO 
17b8d30947SMasatake YAMATO /*
18b8d30947SMasatake YAMATO   Red Black Trees
19b8d30947SMasatake YAMATO   (C) 1999  Andrea Arcangeli <andrea@suse.de>
20b8d30947SMasatake YAMATO 
21b8d30947SMasatake YAMATO   This program is free software; you can redistribute it and/or modify
22b8d30947SMasatake YAMATO   it under the terms of the GNU General Public License as published by
23b8d30947SMasatake YAMATO   the Free Software Foundation; either version 2 of the License, or
24b8d30947SMasatake YAMATO   (at your option) any later version.
25b8d30947SMasatake YAMATO 
26b8d30947SMasatake YAMATO   This program is distributed in the hope that it will be useful,
27b8d30947SMasatake YAMATO   but WITHOUT ANY WARRANTY; without even the implied warranty of
28b8d30947SMasatake YAMATO   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29b8d30947SMasatake YAMATO   GNU General Public License for more details.
30b8d30947SMasatake YAMATO 
31b8d30947SMasatake YAMATO   You should have received a copy of the GNU General Public License
32b8d30947SMasatake YAMATO   along with this program; if not, write to the Free Software
33b8d30947SMasatake YAMATO   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34b8d30947SMasatake YAMATO 
35b8d30947SMasatake YAMATO   linux/include/linux/rbtree.h
36b8d30947SMasatake YAMATO 
37b8d30947SMasatake YAMATO   To use rbtrees you'll have to implement your own insert and search cores.
38b8d30947SMasatake YAMATO   This will avoid us to use callbacks and to drop drammatically performances.
39b8d30947SMasatake YAMATO   I know it's not the cleaner way,  but in C (not in C++) to get
40b8d30947SMasatake YAMATO   performances and genericity...
41b8d30947SMasatake YAMATO 
42b8d30947SMasatake YAMATO   Some example of insert and search follows here. The search is a plain
43b8d30947SMasatake YAMATO   normal search over an ordered tree. The insert instead must be implemented
44b8d30947SMasatake YAMATO   in two steps: First, the code must insert the element in order as a red leaf
45b8d30947SMasatake YAMATO   in the tree, and then the support library function rb_insert_color() must
46b8d30947SMasatake YAMATO   be called. Such function will do the not trivial work to rebalance the
47b8d30947SMasatake YAMATO   rbtree, if necessary.
48b8d30947SMasatake YAMATO 
49b8d30947SMasatake YAMATO -----------------------------------------------------------------------
50b8d30947SMasatake YAMATO static inline struct page * rb_search_page_cache(struct inode * inode,
51b8d30947SMasatake YAMATO 						 unsigned long offset)
52b8d30947SMasatake YAMATO {
53b8d30947SMasatake YAMATO 	struct rb_node * n = inode->i_rb_page_cache.rb_node;
54b8d30947SMasatake YAMATO 	struct page * page;
55b8d30947SMasatake YAMATO 
56b8d30947SMasatake YAMATO 	while (n)
57b8d30947SMasatake YAMATO 	{
58b8d30947SMasatake YAMATO 		page = rb_entry(n, struct page, rb_page_cache);
59b8d30947SMasatake YAMATO 
60b8d30947SMasatake YAMATO 		if (offset < page->offset)
61b8d30947SMasatake YAMATO 			n = n->rb_left;
62b8d30947SMasatake YAMATO 		else if (offset > page->offset)
63b8d30947SMasatake YAMATO 			n = n->rb_right;
64b8d30947SMasatake YAMATO 		else
65b8d30947SMasatake YAMATO 			return page;
66b8d30947SMasatake YAMATO 	}
67b8d30947SMasatake YAMATO 	return NULL;
68b8d30947SMasatake YAMATO }
69b8d30947SMasatake YAMATO 
70b8d30947SMasatake YAMATO static inline struct page * __rb_insert_page_cache(struct inode * inode,
71b8d30947SMasatake YAMATO 						   unsigned long offset,
72b8d30947SMasatake YAMATO 						   struct rb_node * node)
73b8d30947SMasatake YAMATO {
74b8d30947SMasatake YAMATO 	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
75b8d30947SMasatake YAMATO 	struct rb_node * parent = NULL;
76b8d30947SMasatake YAMATO 	struct page * page;
77b8d30947SMasatake YAMATO 
78b8d30947SMasatake YAMATO 	while (*p)
79b8d30947SMasatake YAMATO 	{
80b8d30947SMasatake YAMATO 		parent = *p;
81b8d30947SMasatake YAMATO 		page = rb_entry(parent, struct page, rb_page_cache);
82b8d30947SMasatake YAMATO 
83b8d30947SMasatake YAMATO 		if (offset < page->offset)
84b8d30947SMasatake YAMATO 			p = &(*p)->rb_left;
85b8d30947SMasatake YAMATO 		else if (offset > page->offset)
86b8d30947SMasatake YAMATO 			p = &(*p)->rb_right;
87b8d30947SMasatake YAMATO 		else
88b8d30947SMasatake YAMATO 			return page;
89b8d30947SMasatake YAMATO 	}
90b8d30947SMasatake YAMATO 
91b8d30947SMasatake YAMATO 	rb_link_node(node, parent, p);
92b8d30947SMasatake YAMATO 
93b8d30947SMasatake YAMATO 	return NULL;
94b8d30947SMasatake YAMATO }
95b8d30947SMasatake YAMATO 
96b8d30947SMasatake YAMATO static inline struct page * rb_insert_page_cache(struct inode * inode,
97b8d30947SMasatake YAMATO 						 unsigned long offset,
98b8d30947SMasatake YAMATO 						 struct rb_node * node)
99b8d30947SMasatake YAMATO {
100b8d30947SMasatake YAMATO 	struct page * ret;
101b8d30947SMasatake YAMATO 	if ((ret = __rb_insert_page_cache(inode, offset, node)))
102b8d30947SMasatake YAMATO 		goto out;
103b8d30947SMasatake YAMATO 	rb_insert_color(node, &inode->i_rb_page_cache);
104b8d30947SMasatake YAMATO  out:
105b8d30947SMasatake YAMATO 	return ret;
106b8d30947SMasatake YAMATO }
107b8d30947SMasatake YAMATO -----------------------------------------------------------------------
108b8d30947SMasatake YAMATO */
109b8d30947SMasatake YAMATO 
110b85d98b5SMasatake YAMATO #ifndef	CTAGS_MAIN_RBTREE_H
111b85d98b5SMasatake YAMATO #define	CTAGS_MAIN_RBTREE_H
112b85d98b5SMasatake YAMATO 
113b85d98b5SMasatake YAMATO #include "general.h"
114b85d98b5SMasatake YAMATO #include "inline.h"
115b85d98b5SMasatake YAMATO #include "gcc-attr.h"
116*e9626ab1SK.Takata #include <stdint.h>
117b8d30947SMasatake YAMATO 
118b8d30947SMasatake YAMATO #if defined(container_of)
119b8d30947SMasatake YAMATO   #undef container_of
120b85d98b5SMasatake YAMATO #if defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT)
121b8d30947SMasatake YAMATO   #define container_of(ptr, type, member) ({			\
122b8d30947SMasatake YAMATO         const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
123b8d30947SMasatake YAMATO         (type *)( (char *)__mptr - offsetof(type,member) );})
124b8d30947SMasatake YAMATO #else
125b85d98b5SMasatake YAMATO   #define container_of(ptr, type, member) \
126b85d98b5SMasatake YAMATO         ((type *)( (char *)ptr - offsetof(type,member)))
127b85d98b5SMasatake YAMATO #endif	/* defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT) */
128b85d98b5SMasatake YAMATO #else
129b85d98b5SMasatake YAMATO #if defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT)
130b8d30947SMasatake YAMATO   #define container_of(ptr, type, member) ({			\
131b8d30947SMasatake YAMATO         const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
132b8d30947SMasatake YAMATO         (type *)( (char *)__mptr - offsetof(type,member) );})
133b85d98b5SMasatake YAMATO #else
134b85d98b5SMasatake YAMATO   #define container_of(ptr, type, member) \
135b85d98b5SMasatake YAMATO         ((type *)( (char *)ptr - offsetof(type,member)))
136b85d98b5SMasatake YAMATO #endif /* defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT) */
137b85d98b5SMasatake YAMATO #endif /* defined(container_of) */
138b8d30947SMasatake YAMATO 
139b8d30947SMasatake YAMATO #if defined(offsetof)
140b8d30947SMasatake YAMATO   #undef offsetof
141b8d30947SMasatake YAMATO   #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
142b8d30947SMasatake YAMATO #else
143b8d30947SMasatake YAMATO   #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
144b8d30947SMasatake YAMATO #endif
145b8d30947SMasatake YAMATO 
146b8d30947SMasatake YAMATO #undef NULL
147b8d30947SMasatake YAMATO #if defined(__cplusplus)
148b8d30947SMasatake YAMATO   #define NULL 0
149b8d30947SMasatake YAMATO #else
150b8d30947SMasatake YAMATO   #define NULL ((void *)0)
151b8d30947SMasatake YAMATO #endif
152b8d30947SMasatake YAMATO 
153b8d30947SMasatake YAMATO struct rb_node
154b8d30947SMasatake YAMATO {
155*e9626ab1SK.Takata 	uintptr_t  rb_parent_color;
156b8d30947SMasatake YAMATO #define	RB_RED		0
157b8d30947SMasatake YAMATO #define	RB_BLACK	1
158b8d30947SMasatake YAMATO 	struct rb_node *rb_right;
159b8d30947SMasatake YAMATO 	struct rb_node *rb_left;
160b85d98b5SMasatake YAMATO } CTAGA_ATTR_ALIGNED(sizeof(long));
161b8d30947SMasatake YAMATO     /* The alignment might seem pointless, but allegedly CRIS needs it */
162b8d30947SMasatake YAMATO 
163b8d30947SMasatake YAMATO struct rb_root
164b8d30947SMasatake YAMATO {
165b8d30947SMasatake YAMATO 	struct rb_node *rb_node;
166b8d30947SMasatake YAMATO };
167b8d30947SMasatake YAMATO 
168b8d30947SMasatake YAMATO 
169b8d30947SMasatake YAMATO #define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
170b8d30947SMasatake YAMATO #define rb_color(r)   ((r)->rb_parent_color & 1)
171b8d30947SMasatake YAMATO #define rb_is_red(r)   (!rb_color(r))
172b8d30947SMasatake YAMATO #define rb_is_black(r) rb_color(r)
173b8d30947SMasatake YAMATO #define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
174b8d30947SMasatake YAMATO #define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
175b8d30947SMasatake YAMATO 
rb_set_parent(struct rb_node * rb,struct rb_node * p)176b85d98b5SMasatake YAMATO CTAGS_INLINE void rb_set_parent(struct rb_node *rb, struct rb_node *p)
177b8d30947SMasatake YAMATO {
178*e9626ab1SK.Takata 	rb->rb_parent_color = (rb->rb_parent_color & 3) | (uintptr_t)p;
179b8d30947SMasatake YAMATO }
rb_set_color(struct rb_node * rb,int color)180b85d98b5SMasatake YAMATO CTAGS_INLINE void rb_set_color(struct rb_node *rb, int color)
181b8d30947SMasatake YAMATO {
182b8d30947SMasatake YAMATO 	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
183b8d30947SMasatake YAMATO }
184b8d30947SMasatake YAMATO 
185b8d30947SMasatake YAMATO #define RB_ROOT	(struct rb_root) { NULL, }
186b8d30947SMasatake YAMATO #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
187b8d30947SMasatake YAMATO 
188b8d30947SMasatake YAMATO #define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
189b8d30947SMasatake YAMATO #define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
190b8d30947SMasatake YAMATO #define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
191b8d30947SMasatake YAMATO 
rb_init_node(struct rb_node * rb)192b85d98b5SMasatake YAMATO CTAGS_INLINE void rb_init_node(struct rb_node *rb)
193b8d30947SMasatake YAMATO {
194b8d30947SMasatake YAMATO 	rb->rb_parent_color = 0;
195b8d30947SMasatake YAMATO 	rb->rb_right = NULL;
196b8d30947SMasatake YAMATO 	rb->rb_left = NULL;
197b8d30947SMasatake YAMATO 	RB_CLEAR_NODE(rb);
198b8d30947SMasatake YAMATO }
199b8d30947SMasatake YAMATO 
200b8d30947SMasatake YAMATO extern void rb_insert_color(struct rb_node *, struct rb_root *);
201b8d30947SMasatake YAMATO extern void rb_erase(struct rb_node *, struct rb_root *);
202b8d30947SMasatake YAMATO 
203b8d30947SMasatake YAMATO typedef void (*rb_augment_f)(struct rb_node *node, void *data);
204b8d30947SMasatake YAMATO 
205b8d30947SMasatake YAMATO extern void rb_augment_insert(struct rb_node *node,
206b8d30947SMasatake YAMATO 			      rb_augment_f func, void *data);
207b8d30947SMasatake YAMATO extern struct rb_node *rb_augment_erase_begin(struct rb_node *node);
208b8d30947SMasatake YAMATO extern void rb_augment_erase_end(struct rb_node *node,
209b8d30947SMasatake YAMATO 				 rb_augment_f func, void *data);
210b8d30947SMasatake YAMATO 
211b8d30947SMasatake YAMATO /* Find logical next and previous nodes in a tree */
212b8d30947SMasatake YAMATO extern struct rb_node *rb_next(const struct rb_node *);
213b8d30947SMasatake YAMATO extern struct rb_node *rb_prev(const struct rb_node *);
214b8d30947SMasatake YAMATO extern struct rb_node *rb_first(const struct rb_root *);
215b8d30947SMasatake YAMATO extern struct rb_node *rb_last(const struct rb_root *);
216b8d30947SMasatake YAMATO 
217b8d30947SMasatake YAMATO /* Fast replacement of a single node without remove/rebalance/add/rebalance */
218b8d30947SMasatake YAMATO extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
219b8d30947SMasatake YAMATO 			    struct rb_root *root);
220b8d30947SMasatake YAMATO 
rb_link_node(struct rb_node * node,struct rb_node * parent,struct rb_node ** rb_link)221b85d98b5SMasatake YAMATO CTAGS_INLINE void rb_link_node(struct rb_node * node, struct rb_node * parent,
222b8d30947SMasatake YAMATO 				struct rb_node ** rb_link)
223b8d30947SMasatake YAMATO {
224*e9626ab1SK.Takata 	node->rb_parent_color = (uintptr_t)parent;
225b8d30947SMasatake YAMATO 	node->rb_left = node->rb_right = NULL;
226b8d30947SMasatake YAMATO 
227b8d30947SMasatake YAMATO 	*rb_link = node;
228b8d30947SMasatake YAMATO }
229b8d30947SMasatake YAMATO 
230b85d98b5SMasatake YAMATO #endif	/* CTAGS_MAIN_RBTREE_H */
231