1
/* Stolen from Linux 2.6.34 */
2
3
/*
4
  Red Black Trees
5
  (C) 1999  Andrea Arcangeli <andrea@suse.de>
6
  
7
  This program is free software; you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation; either version 2 of the License, or
10
  (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU General Public License for more details.
16
17
  You should have received a copy of the GNU General Public License
18
  along with this program; if not, see <http://www.gnu.org/licenses/>.
19
20
  linux/include/linux/rbtree.h
21
22
  To use rbtrees you'll have to implement your own insert and search cores.
23
  This will avoid us to use callbacks and to drop drammatically performances.
24
  I know it's not the cleaner way,  but in C (not in C++) to get
25
  performances and genericity...
26
27
  Some example of insert and search follows here. The search is a plain
28
  normal search over an ordered tree. The insert instead must be implemented
29
  int two steps: as first thing the code must insert the element in
30
  order as a red leaf in the tree, then the support library function
31
  rb_insert_color() must be called. Such function will do the
32
  not trivial work to rebalance the rbtree if necessary.
33
34
-----------------------------------------------------------------------
35
static inline struct page * rb_search_page_cache(struct inode * inode,
36
						 unsigned long offset)
37
{
38
	struct rb_node * n = inode->i_rb_page_cache.rb_node;
39
	struct page * page;
40
41
	while (n)
42
	{
43
		page = rb_entry(n, struct page, rb_page_cache);
44
45
		if (offset < page->offset)
46
			n = n->rb_left;
47
		else if (offset > page->offset)
48
			n = n->rb_right;
49
		else
50
			return page;
51
	}
52
	return NULL;
53
}
54
55
static inline struct page * __rb_insert_page_cache(struct inode * inode,
56
						   unsigned long offset,
57
						   struct rb_node * node)
58
{
59
	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
60
	struct rb_node * parent = NULL;
61
	struct page * page;
62
63
	while (*p)
64
	{
65
		parent = *p;
66
		page = rb_entry(parent, struct page, rb_page_cache);
67
68
		if (offset < page->offset)
69
			p = &(*p)->rb_left;
70
		else if (offset > page->offset)
71
			p = &(*p)->rb_right;
72
		else
73
			return page;
74
	}
75
76
	rb_link_node(node, parent, p);
77
78
	return NULL;
79
}
80
81
static inline struct page * rb_insert_page_cache(struct inode * inode,
82
						 unsigned long offset,
83
						 struct rb_node * node)
84
{
85
	struct page * ret;
86
	if ((ret = __rb_insert_page_cache(inode, offset, node)))
87
		goto out;
88
	rb_insert_color(node, &inode->i_rb_page_cache);
89
 out:
90
	return ret;
91
}
92
-----------------------------------------------------------------------
93
*/
94
95
#ifndef	_LINUX_RBTREE_H
96
#define	_LINUX_RBTREE_H
97
98
#include "compiler.h" /* container_of */
99
#include <stddef.h>
100
101
struct rb_node
102
{
103
	unsigned long  rb_parent_color;
104
#define	RB_RED		0
105
#define	RB_BLACK	1
106
	struct rb_node *rb_right;
107
	struct rb_node *rb_left;
108
} __attribute__((aligned(sizeof(long))));
109
    /* The alignment might seem pointless, but allegedly CRIS needs it */
110
111
struct rb_root
112
{
113
	struct rb_node *rb_node;
114
};
115
116
117
#define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
118
#define rb_color(r)   ((r)->rb_parent_color & 1)
119
#define rb_is_red(r)   (!rb_color(r))
120
#define rb_is_black(r) rb_color(r)
121
#define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
122
#define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
123
124
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
125
{
126
	rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
127
}
128
static inline void rb_set_color(struct rb_node *rb, int color)
129
{
130
	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
131
}
132
133
#define RB_ROOT	(struct rb_root) { NULL, }
134
#define	rb_entry(ptr, type, member) container_of(ptr, type, member)
135
136
#define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
137
#define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
138
#define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
139
140
void rb_insert_color(struct rb_node *, struct rb_root *);
141
void rb_erase(struct rb_node *, struct rb_root *);
142
143
/* Find logical next and previous nodes in a tree */
144
struct rb_node *rb_next(const struct rb_node *);
145
struct rb_node *rb_prev(const struct rb_node *);
146
struct rb_node *rb_first(const struct rb_root *);
147
struct rb_node *rb_last(const struct rb_root *);
148
149
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
150
void rb_replace_node(struct rb_node *victim, struct rb_node *new, 
151
			struct rb_root *root);
152
153
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
154
				struct rb_node ** rb_link)
155
{
156
	node->rb_parent_color = (unsigned long )parent;
157
	node->rb_left = node->rb_right = NULL;
158
159
	*rb_link = node;
160
}
161
162
163
/* Cmus extensions */
164
165
static inline void rb_root_init(struct rb_root *root)
166
{
167
	root->rb_node = NULL;
168
}
169
170
static inline int rb_root_empty(struct rb_root *root)
171
{
172
	return RB_EMPTY_ROOT(root);
173
}
174
175
/**
176
 * rb_for_each        -       iterate over a rbtree
177
 * @pos:        the &struct rb_node to use as a loop counter.
178
 * @root:       the root for your rbtree.
179
 */
180
#define rb_for_each(pos, root) \
181
	for (pos = rb_first(root); pos; pos = rb_next(pos))
182
183
/**
184
 * rb_for_each_prev   -       iterate over a rbtree backwards
185
 * @pos:        the &struct rb_node to use as a loop counter.
186
 * @root:       the root for your rbtree.
187
 */
188
#define rb_for_each_prev(pos, root) \
189
	for (pos = rb_last(root); pos; pos = rb_prev(pos))
190
191
/**
192
 * rb_for_each_safe   -       iterate over a rbtree safe against removal of rbtree node
193
 * @pos:        the &struct rb_node to use as a loop counter.
194
 * @n:          another &struct rb_node to use as temporary storage
195
 * @root:       the root for your rbtree.
196
 */
197
#define rb_for_each_safe(pos, n, root) \
198
	for (pos = rb_first(root), n = pos ? rb_next(pos) : NULL; pos; \
199
		pos = n, n = pos ? rb_next(pos) : NULL)
200
201
/**
202
 * rb_for_each_entry        -       iterate over a rbtree of given type
203
 * @pos:        the &struct rb_node to use as a loop counter.
204
 * @t:          the type * to use as a loop counter.
205
 * @root:       the root for your rbtree.
206
 * @member:	the name of the rb_node-struct within the struct.
207
 */
208
#define rb_for_each_entry(t, pos, root, member) \
209
	for (pos = rb_first(root), t = pos ? rb_entry(pos, __typeof__(*t), member) : NULL; \
210
		pos; pos = rb_next(pos), t = pos ? rb_entry(pos, __typeof__(*t), member) : NULL)
211
212
/**
213
 * rb_for_each_entry_reverse        -       iterate backwards over a rbtree of given type
214
 * @pos:        the &struct rb_node to use as a loop counter.
215
 * @t:          the type * to use as a loop counter.
216
 * @root:       the root for your rbtree.
217
 * @member:	the name of the rb_node-struct within the struct.
218
 */
219
#define rb_for_each_entry_reverse(t, pos, root, member) \
220
	for (pos = rb_last(root), t = pos ? rb_entry(pos, __typeof__(*t), member) : NULL; \
221
		pos; pos = rb_prev(pos), t = pos ? rb_entry(pos, __typeof__(*t), member) : NULL)
222
223
#endif	/* _LINUX_RBTREE_H */