XenevaOS
Loading...
Searching...
No Matches
rbtree.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 Red Black Trees
4 (C) 1999 Andrea Arcangeli <andrea@suse.de>
5
6
7 linux/include/linux/rbtree.h
8
9 To use rbtrees you'll have to implement your own insert and search cores.
10 This will avoid us to use callbacks and to drop drammatically performances.
11 I know it's not the cleaner way, but in C (not in C++) to get
12 performances and genericity...
13
14 See Documentation/core-api/rbtree.rst for documentation and samples.
15*/
16
17#ifndef _LINUX_RBTREE_H
18#define _LINUX_RBTREE_H
19
20#include <linux/container_of.h>
21#include <linux/rbtree_types.h>
22
23#include <linux/stddef.h>
24#include <linux/rcupdate.h>
25
26#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
27
28#define rb_entry(ptr, type, member) container_of(ptr, type, member)
29
30#define RB_EMPTY_ROOT(root) (READ_ONCE((root)->rb_node) == NULL)
31
32/*
33 * DCL delta -- `uintptr_t` where mainline writes `unsigned long`, at the two
34 * macros here and the two rb_link_node variants below; rbtree_augmented.h
35 * has the same two in rb_set_parent()/rb_set_parent_color(). The field
36 * holds a pointer (see rbtree_types.h for why the width matters).
37 */
38/* 'empty' nodes are nodes that are known not to be inserted in an rbtree */
39#define RB_EMPTY_NODE(node) \
40 ((node)->__rb_parent_color == (uintptr_t)(node))
41#define RB_CLEAR_NODE(node) \
42 ((node)->__rb_parent_color = (uintptr_t)(node))
43
44#define RB_EMPTY_LINKED_NODE(lnode) RB_EMPTY_NODE(&(lnode)->node)
45#define RB_CLEAR_LINKED_NODE(lnode) ({ \
46 RB_CLEAR_NODE(&(lnode)->node); \
47 (lnode)->prev = (lnode)->next = NULL; \
48})
49
50extern void rb_insert_color(struct rb_node *, struct rb_root *);
51extern void rb_erase(struct rb_node *, struct rb_root *);
52extern bool rb_erase_linked(struct rb_node_linked *, struct rb_root_linked *);
53
54/* Find logical next and previous nodes in a tree */
55extern struct rb_node *rb_next(const struct rb_node *);
56extern struct rb_node *rb_prev(const struct rb_node *);
57
58/*
59 * This function returns the first node (in sort order) of the tree.
60 */
61static inline struct rb_node *rb_first(const struct rb_root *root)
62{
63 struct rb_node *n;
64
65 n = root->rb_node;
66 if (!n)
67 return NULL;
68 while (n->rb_left)
69 n = n->rb_left;
70 return n;
71}
72
73/*
74 * This function returns the last node (in sort order) of the tree.
75 */
76static inline struct rb_node *rb_last(const struct rb_root *root)
77{
78 struct rb_node *n;
79
80 n = root->rb_node;
81 if (!n)
82 return NULL;
83 while (n->rb_right)
84 n = n->rb_right;
85 return n;
86}
87
88/* Postorder iteration - always visit the parent after its children */
89extern struct rb_node *rb_first_postorder(const struct rb_root *);
90extern struct rb_node *rb_next_postorder(const struct rb_node *);
91
92/* Fast replacement of a single node without remove/rebalance/add/rebalance */
93extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
94 struct rb_root *root);
95extern void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new,
96 struct rb_root *root);
97
98static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
99 struct rb_node **rb_link)
100{
101 node->__rb_parent_color = (uintptr_t)parent;
102 node->rb_left = node->rb_right = NULL;
103
104 *rb_link = node;
105}
106
107static inline void rb_link_node_rcu(struct rb_node *node, struct rb_node *parent,
108 struct rb_node **rb_link)
109{
110 node->__rb_parent_color = (uintptr_t)parent;
111 node->rb_left = node->rb_right = NULL;
112
113 rcu_assign_pointer(*rb_link, node);
114}
115
116#define rb_entry_safe(ptr, type, member) \
117 ({ typeof(ptr) ____ptr = (ptr); \
118 ____ptr ? rb_entry(____ptr, type, member) : NULL; \
119 })
120
138#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
139 for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
140 pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
141 typeof(*pos), field); 1; }); \
142 pos = n)
143
144/* Same as rb_first(), but O(1) */
145#define rb_first_cached(root) (root)->rb_leftmost
146
147static inline void rb_insert_color_cached(struct rb_node *node,
148 struct rb_root_cached *root,
149 bool leftmost)
150{
151 if (leftmost)
152 root->rb_leftmost = node;
153 rb_insert_color(node, &root->rb_root);
154}
155
156
157static inline struct rb_node *
158rb_erase_cached(struct rb_node *node, struct rb_root_cached *root)
159{
160 struct rb_node *leftmost = NULL;
161
162 if (root->rb_leftmost == node)
163 leftmost = root->rb_leftmost = rb_next(node);
164
165 rb_erase(node, &root->rb_root);
166
167 return leftmost;
168}
169
170static inline void rb_replace_node_cached(struct rb_node *victim,
171 struct rb_node *new,
172 struct rb_root_cached *root)
173{
174 if (root->rb_leftmost == victim)
175 root->rb_leftmost = new;
176 rb_replace_node(victim, new, &root->rb_root);
177}
178
179/*
180 * The below helper functions use 2 operators with 3 different
181 * calling conventions. The operators are related like:
182 *
183 * comp(a->key,b) < 0 := less(a,b)
184 * comp(a->key,b) > 0 := less(b,a)
185 * comp(a->key,b) == 0 := !less(a,b) && !less(b,a)
186 *
187 * If these operators define a partial order on the elements we make no
188 * guarantee on which of the elements matching the key is found. See
189 * rb_find().
190 *
191 * The reason for this is to allow the find() interface without requiring an
192 * on-stack dummy object, which might not be feasible due to object size.
193 */
194
203static __always_inline struct rb_node *
204rb_add_cached(struct rb_node *node, struct rb_root_cached *tree,
205 bool (*less)(struct rb_node *, const struct rb_node *))
206{
207 struct rb_node **link = &tree->rb_root.rb_node;
208 struct rb_node *parent = NULL;
209 bool leftmost = true;
210
211 while (*link) {
212 parent = *link;
213 if (less(node, parent)) {
214 link = &parent->rb_left;
215 } else {
216 link = &parent->rb_right;
217 leftmost = false;
218 }
219 }
220
221 rb_link_node(node, parent, link);
222 rb_insert_color_cached(node, tree, leftmost);
223
224 return leftmost ? node : NULL;
225}
226
227static __always_inline void
228__rb_add(struct rb_node *node, struct rb_root *tree,
229 bool (*less)(struct rb_node *, const struct rb_node *),
230 void (*linkop)(struct rb_node *, struct rb_node *, struct rb_node **))
231{
232 struct rb_node **link = &tree->rb_node;
233 struct rb_node *parent = NULL;
234
235 while (*link) {
236 parent = *link;
237 if (less(node, parent))
238 link = &parent->rb_left;
239 else
240 link = &parent->rb_right;
241 }
242
243 linkop(node, parent, link);
244 rb_link_node(node, parent, link);
245 rb_insert_color(node, tree);
246}
247
248#define __node_2_linked_node(_n) \
249 rb_entry((_n), struct rb_node_linked, node)
250
251static inline void
252rb_link_linked_node(struct rb_node *node, struct rb_node *parent, struct rb_node **link)
253{
254 if (!parent)
255 return;
256
259
260 if (link == &parent->rb_left) {
261 nnew->prev = npar->prev;
262 nnew->next = npar;
263 npar->prev = nnew;
264 if (nnew->prev)
265 nnew->prev->next = nnew;
266 } else {
267 nnew->next = npar->next;
268 nnew->prev = npar;
269 npar->next = nnew;
270 if (nnew->next)
271 nnew->next->prev = nnew;
272 }
273}
274
283static __always_inline bool
284rb_add_linked(struct rb_node_linked *node, struct rb_root_linked *tree,
285 bool (*less)(struct rb_node *, const struct rb_node *))
286{
287 __rb_add(&node->node, &tree->rb_root, less, rb_link_linked_node);
288 if (!node->prev)
289 tree->rb_leftmost = node;
290 return !node->prev;
291}
292
293/* Empty linkop function which is optimized away by the compiler */
294static __always_inline void
295rb_link_noop(struct rb_node *n, struct rb_node *p, struct rb_node **l) { }
296
303static __always_inline void
304rb_add(struct rb_node *node, struct rb_root *tree,
305 bool (*less)(struct rb_node *, const struct rb_node *))
306{
307 __rb_add(node, tree, less, rb_link_noop);
308}
309
319static __always_inline struct rb_node *
320rb_find_add_cached(struct rb_node *node, struct rb_root_cached *tree,
321 int (*cmp)(const struct rb_node *new, const struct rb_node *exist))
322{
323 bool leftmost = true;
324 struct rb_node **link = &tree->rb_root.rb_node;
325 struct rb_node *parent = NULL;
326 int c;
327
328 while (*link) {
329 parent = *link;
330 c = cmp(node, parent);
331
332 if (c < 0) {
333 link = &parent->rb_left;
334 } else if (c > 0) {
335 link = &parent->rb_right;
336 leftmost = false;
337 } else {
338 return parent;
339 }
340 }
341
342 rb_link_node(node, parent, link);
343 rb_insert_color_cached(node, tree, leftmost);
344 return NULL;
345}
346
356static __always_inline struct rb_node *
357rb_find_add(struct rb_node *node, struct rb_root *tree,
358 int (*cmp)(struct rb_node *, const struct rb_node *))
359{
360 struct rb_node **link = &tree->rb_node;
361 struct rb_node *parent = NULL;
362 int c;
363
364 while (*link) {
365 parent = *link;
366 c = cmp(node, parent);
367
368 if (c < 0)
369 link = &parent->rb_left;
370 else if (c > 0)
371 link = &parent->rb_right;
372 else
373 return parent;
374 }
375
376 rb_link_node(node, parent, link);
377 rb_insert_color(node, tree);
378 return NULL;
379}
380
392static __always_inline struct rb_node *
393rb_find_add_rcu(struct rb_node *node, struct rb_root *tree,
394 int (*cmp)(struct rb_node *, const struct rb_node *))
395{
396 struct rb_node **link = &tree->rb_node;
397 struct rb_node *parent = NULL;
398 int c;
399
400 while (*link) {
401 parent = *link;
402 c = cmp(node, parent);
403
404 if (c < 0)
405 link = &parent->rb_left;
406 else if (c > 0)
407 link = &parent->rb_right;
408 else
409 return parent;
410 }
411
412 rb_link_node_rcu(node, parent, link);
413 rb_insert_color(node, tree);
414 return NULL;
415}
416
425static __always_inline struct rb_node *
426rb_find(const void *key, const struct rb_root *tree,
427 int (*cmp)(const void *key, const struct rb_node *))
428{
429 struct rb_node *node = tree->rb_node;
430
431 while (node) {
432 int c = cmp(key, node);
433
434 if (c < 0)
435 node = node->rb_left;
436 else if (c > 0)
437 node = node->rb_right;
438 else
439 return node;
440 }
441
442 return NULL;
443}
444
456static __always_inline struct rb_node *
457rb_find_rcu(const void *key, const struct rb_root *tree,
458 int (*cmp)(const void *key, const struct rb_node *))
459{
460 struct rb_node *node = tree->rb_node;
461
462 while (node) {
463 int c = cmp(key, node);
464
465 if (c < 0)
466 node = rcu_dereference_raw(node->rb_left);
467 else if (c > 0)
468 node = rcu_dereference_raw(node->rb_right);
469 else
470 return node;
471 }
472
473 return NULL;
474}
475
484static __always_inline struct rb_node *
485rb_find_first(const void *key, const struct rb_root *tree,
486 int (*cmp)(const void *key, const struct rb_node *))
487{
488 struct rb_node *node = tree->rb_node;
489 struct rb_node *match = NULL;
490
491 while (node) {
492 int c = cmp(key, node);
493
494 if (c <= 0) {
495 if (!c)
496 match = node;
497 node = node->rb_left;
498 } else if (c > 0) {
499 node = node->rb_right;
500 }
501 }
502
503 return match;
504}
505
514static __always_inline struct rb_node *
515rb_next_match(const void *key, struct rb_node *node,
516 int (*cmp)(const void *key, const struct rb_node *))
517{
518 node = rb_next(node);
519 if (node && cmp(key, node))
520 node = NULL;
521 return node;
522}
523
531#define rb_for_each(node, key, tree, cmp) \
532 for ((node) = rb_find_first((key), (tree), (cmp)); \
533 (node); (node) = rb_next_match((key), (node), (cmp)))
534
535#endif /* _LINUX_RBTREE_H */
unsigned int uintptr_t
Definition stdint.h:94
#define NULL
Definition actypes.h:561
#define __always_inline
Definition compiler_attributes.h:55
struct kobject * parent
Definition kobject.h:91
void int node
Definition kthread.h:31
int const struct list_head const struct list_head struct list_head list_cmp_func_t cmp
Definition list_sort.h:13
void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, struct rb_root *root)
struct rb_node * rb_next_postorder(const struct rb_node *)
struct rb_node * rb_next(const struct rb_node *)
bool rb_erase_linked(struct rb_node_linked *, struct rb_root_linked *)
#define __node_2_linked_node(_n)
Definition rbtree.h:248
struct rb_node * rb_first_postorder(const struct rb_root *)
void rb_insert_color(struct rb_node *, struct rb_root *)
void rb_erase(struct rb_node *, struct rb_root *)
struct rb_node * rb_prev(const struct rb_node *)
void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root)
#define rcu_assign_pointer(p, v)
Definition rcupdate.h:51
#define rcu_dereference_raw(p)
Definition rcupdate.h:42
Definition rbtree_types.h:28
struct rb_node_linked * prev
Definition rbtree_types.h:30
struct rb_node_linked * next
Definition rbtree_types.h:31
Definition rbtree_types.h:21
struct rb_node * rb_left
Definition rbtree_types.h:24
struct rb_node * rb_right
Definition rbtree_types.h:23
Definition rbtree_types.h:48
struct rb_root rb_root
Definition rbtree_types.h:49
Definition rbtree_types.h:57
struct rb_node_linked * rb_leftmost
Definition rbtree_types.h:59
struct rb_root rb_root
Definition rbtree_types.h:58
Definition rbtree_types.h:34
struct rb_node * rb_node
Definition rbtree_types.h:35
TTY * root
Definition tty.cpp:47