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 #define __UBOOT__ 21*9dd228b5SHeiko Schocher #ifndef __UBOOT__ 22*9dd228b5SHeiko Schocher #include <linux/kernel.h> 23*9dd228b5SHeiko Schocher #endif 247ba890bfSKyungmin Park #include <linux/stddef.h> 257ba890bfSKyungmin Park 26*9dd228b5SHeiko Schocher struct rb_node { 27*9dd228b5SHeiko Schocher unsigned long __rb_parent_color; 287ba890bfSKyungmin Park struct rb_node *rb_right; 297ba890bfSKyungmin Park struct rb_node *rb_left; 307ba890bfSKyungmin Park } __attribute__((aligned(sizeof(long)))); 317ba890bfSKyungmin Park /* The alignment might seem pointless, but allegedly CRIS needs it */ 327ba890bfSKyungmin Park 33*9dd228b5SHeiko Schocher struct rb_root { 347ba890bfSKyungmin Park struct rb_node *rb_node; 357ba890bfSKyungmin Park }; 367ba890bfSKyungmin Park 377ba890bfSKyungmin Park 38*9dd228b5SHeiko Schocher #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) 397ba890bfSKyungmin Park 407ba890bfSKyungmin Park #define RB_ROOT (struct rb_root) { NULL, } 417ba890bfSKyungmin Park #define rb_entry(ptr, type, member) container_of(ptr, type, member) 427ba890bfSKyungmin Park 437ba890bfSKyungmin Park #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) 44*9dd228b5SHeiko Schocher 45*9dd228b5SHeiko Schocher /* 'empty' nodes are nodes that are known not to be inserted in an rbree */ 46*9dd228b5SHeiko Schocher #define RB_EMPTY_NODE(node) \ 47*9dd228b5SHeiko Schocher ((node)->__rb_parent_color == (unsigned long)(node)) 48*9dd228b5SHeiko Schocher #define RB_CLEAR_NODE(node) \ 49*9dd228b5SHeiko Schocher ((node)->__rb_parent_color = (unsigned long)(node)) 50*9dd228b5SHeiko Schocher 517ba890bfSKyungmin Park 527ba890bfSKyungmin Park extern void rb_insert_color(struct rb_node *, struct rb_root *); 537ba890bfSKyungmin Park extern void rb_erase(struct rb_node *, struct rb_root *); 547ba890bfSKyungmin Park 55*9dd228b5SHeiko Schocher 567ba890bfSKyungmin Park /* Find logical next and previous nodes in a tree */ 57*9dd228b5SHeiko Schocher extern struct rb_node *rb_next(const struct rb_node *); 58*9dd228b5SHeiko Schocher extern struct rb_node *rb_prev(const struct rb_node *); 59*9dd228b5SHeiko Schocher extern struct rb_node *rb_first(const struct rb_root *); 60*9dd228b5SHeiko Schocher extern struct rb_node *rb_last(const struct rb_root *); 61*9dd228b5SHeiko Schocher 62*9dd228b5SHeiko Schocher /* Postorder iteration - always visit the parent after its children */ 63*9dd228b5SHeiko Schocher extern struct rb_node *rb_first_postorder(const struct rb_root *); 64*9dd228b5SHeiko Schocher extern struct rb_node *rb_next_postorder(const struct rb_node *); 657ba890bfSKyungmin Park 667ba890bfSKyungmin Park /* Fast replacement of a single node without remove/rebalance/add/rebalance */ 677ba890bfSKyungmin Park extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 687ba890bfSKyungmin Park struct rb_root *root); 697ba890bfSKyungmin Park 707ba890bfSKyungmin Park static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, 717ba890bfSKyungmin Park struct rb_node ** rb_link) 727ba890bfSKyungmin Park { 73*9dd228b5SHeiko Schocher node->__rb_parent_color = (unsigned long)parent; 747ba890bfSKyungmin Park node->rb_left = node->rb_right = NULL; 757ba890bfSKyungmin Park 767ba890bfSKyungmin Park *rb_link = node; 777ba890bfSKyungmin Park } 787ba890bfSKyungmin Park 79*9dd228b5SHeiko Schocher #define rb_entry_safe(ptr, type, member) \ 80*9dd228b5SHeiko Schocher ({ typeof(ptr) ____ptr = (ptr); \ 81*9dd228b5SHeiko Schocher ____ptr ? rb_entry(____ptr, type, member) : NULL; \ 82*9dd228b5SHeiko Schocher }) 83*9dd228b5SHeiko Schocher 84*9dd228b5SHeiko Schocher /** 85*9dd228b5SHeiko Schocher * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of 86*9dd228b5SHeiko Schocher * given type safe against removal of rb_node entry 87*9dd228b5SHeiko Schocher * 88*9dd228b5SHeiko Schocher * @pos: the 'type *' to use as a loop cursor. 89*9dd228b5SHeiko Schocher * @n: another 'type *' to use as temporary storage 90*9dd228b5SHeiko Schocher * @root: 'rb_root *' of the rbtree. 91*9dd228b5SHeiko Schocher * @field: the name of the rb_node field within 'type'. 92*9dd228b5SHeiko Schocher */ 93*9dd228b5SHeiko Schocher #define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \ 94*9dd228b5SHeiko Schocher for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \ 95*9dd228b5SHeiko Schocher pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \ 96*9dd228b5SHeiko Schocher typeof(*pos), field); 1; }); \ 97*9dd228b5SHeiko Schocher pos = n) 98*9dd228b5SHeiko Schocher 997ba890bfSKyungmin Park #endif /* _LINUX_RBTREE_H */ 100