#ifndef _KERNEL_LIBK_RBTREE_H #define _KERNEL_LIBK_RBTREE_H struct rb_node_link { struct rb_node_link* left; struct rb_node_link* right; struct rb_node_link* parent; int color; }; #define RBTREE_RED 0 #define RBTREE_BLACK 1 #define rbtree_parent(x) ((x)->parent) #define rbtree_left(x) ((x)->left) #define rbtree_right(x) ((x)->right) #define rbtree_color(x) ((x)->color) #define rbtree_entry(node, type, member) ((type*)((char*)(node) - offsetof (type, member))) #define rbtree_node_color(x) ((x) ? (x)->color : RBTREE_BLACK) #define rbtree_rotate_left(root_ptr, x_node) \ do { \ struct rb_node_link* __x = (x_node); \ struct rb_node_link* __y = __x->right; \ __x->right = __y->left; \ if (__y->left) \ __y->left->parent = __x; \ __y->parent = __x->parent; \ if (!__x->parent) \ *(root_ptr) = __y; \ else if (__x == __x->parent->left) \ __x->parent->left = __y; \ else \ __x->parent->right = __y; \ __y->left = __x; \ __x->parent = __y; \ } while (0) #define rbtree_rotate_right(root_ptr, y_node) \ do { \ struct rb_node_link* __y = (y_node); \ struct rb_node_link* __x = __y->left; \ __y->left = __x->right; \ if (__x->right) \ __x->right->parent = __y; \ __x->parent = __y->parent; \ if (!__y->parent) \ *(root_ptr) = __x; \ else if (__y == __y->parent->right) \ __y->parent->right = __x; \ else \ __y->parent->left = __x; \ __x->right = __y; \ __y->parent = __x; \ } while (0) #define rbtree_insert_fixup(root_ptr, z_node) \ do { \ struct rb_node_link* __z = (z_node); \ while (__z->parent && __z->parent->color == RBTREE_RED) { \ if (__z->parent == __z->parent->parent->left) { \ struct rb_node_link* __y = __z->parent->parent->right; \ if (rbtree_node_color (__y) == RBTREE_RED) { \ __z->parent->color = RBTREE_BLACK; \ __y->color = RBTREE_BLACK; \ __z->parent->parent->color = RBTREE_RED; \ __z = __z->parent->parent; \ } else { \ if (__z == __z->parent->right) { \ __z = __z->parent; \ rbtree_rotate_left (root_ptr, __z); \ } \ __z->parent->color = RBTREE_BLACK; \ __z->parent->parent->color = RBTREE_RED; \ rbtree_rotate_right (root_ptr, __z->parent->parent); \ } \ } else { \ struct rb_node_link* __y = __z->parent->parent->left; \ if (rbtree_node_color (__y) == RBTREE_RED) { \ __z->parent->color = RBTREE_BLACK; \ __y->color = RBTREE_BLACK; \ __z->parent->parent->color = RBTREE_RED; \ __z = __z->parent->parent; \ } else { \ if (__z == __z->parent->left) { \ __z = __z->parent; \ rbtree_rotate_right (root_ptr, __z); \ } \ __z->parent->color = RBTREE_BLACK; \ __z->parent->parent->color = RBTREE_RED; \ rbtree_rotate_left (root_ptr, __z->parent->parent); \ } \ } \ } \ (*(root_ptr))->color = RBTREE_BLACK; \ } while (0) #define rbtree_insert(type, root_ptr, node, member, keyfield) \ do { \ struct rb_node_link** __link = (root_ptr); \ struct rb_node_link* __parent = NULL; \ struct rb_node_link* __new = (node); \ type* __nobj = rbtree_entry (__new, type, member); \ while (*__link) { \ __parent = *__link; \ type* __xobj = rbtree_entry (*__link, type, member); \ if (__nobj->keyfield < __xobj->keyfield) \ __link = &((*__link)->left); \ else \ __link = &((*__link)->right); \ } \ __new->parent = __parent; \ __new->left = __new->right = NULL; \ __new->color = RBTREE_RED; \ *__link = __new; \ rbtree_insert_fixup (root_ptr, __new); \ } while (0) #define rbtree_find(type, root_ptr, keyval, out, member, keyfield) \ do { \ (out) = NULL; \ struct rb_node_link* __cur = *(root_ptr); \ while (__cur) { \ type* __obj = rbtree_entry (__cur, type, member); \ if ((keyval) == __obj->keyfield) { \ (out) = __cur; \ break; \ } else if ((keyval) < __obj->keyfield) \ __cur = __cur->left; \ else \ __cur = __cur->right; \ } \ } while (0) #define rbtree_min(node, out) \ do { \ (out) = NULL; \ struct rb_node_link* __n = (node); \ while (__n && __n->left) \ __n = __n->left; \ (out) = __n; \ } while (0) #define rbtree_max(node, out) \ do { \ (out) = NULL; \ struct rb_node_link* __n = (node); \ while (__n && __n->right) \ __n = __n->right; \ (out) = __n; \ } while (0) #define rbtree_first(root_ptr, out) rbtree_min (*(root_ptr), out) #define rbtree_last(root_ptr, out) rbtree_max (*(root_ptr), out) #define rbtree_transplant(root_ptr, u_node, v_node) \ do { \ struct rb_node_link* __u = (u_node); \ struct rb_node_link* __v = (v_node); \ if (!__u->parent) \ *(root_ptr) = __v; \ else if (__u == __u->parent->left) \ __u->parent->left = __v; \ else \ __u->parent->right = __v; \ if (__v) \ __v->parent = __u->parent; \ } while (0) #define rbtree_delete_fixup(root_ptr, x_node, xparent_node) \ do { \ struct rb_node_link* __rdf_x = (x_node); \ struct rb_node_link* __rdf_xp = (xparent_node); \ while (__rdf_xp && (__rdf_x == NULL || __rdf_x->color == RBTREE_BLACK)) { \ if (__rdf_x == __rdf_xp->left) { \ struct rb_node_link* __w = __rdf_xp->right; \ if (rbtree_node_color (__w) == RBTREE_RED) { \ __w->color = RBTREE_BLACK; \ __rdf_xp->color = RBTREE_RED; \ rbtree_rotate_left (root_ptr, __rdf_xp); \ __w = __rdf_xp->right; \ } \ if (rbtree_node_color (__w->left) == RBTREE_BLACK && \ rbtree_node_color (__w->right) == RBTREE_BLACK) { \ if (__w) \ __w->color = RBTREE_RED; \ __rdf_x = __rdf_xp; \ __rdf_xp = __rdf_x->parent; \ } else { \ if (rbtree_node_color (__w->right) == RBTREE_BLACK) { \ if (__w->left) \ __w->left->color = RBTREE_BLACK; \ __w->color = RBTREE_RED; \ rbtree_rotate_right (root_ptr, __w); \ __w = __rdf_xp->right; \ } \ __w->color = __rdf_xp->color; \ __rdf_xp->color = RBTREE_BLACK; \ if (__w->right) \ __w->right->color = RBTREE_BLACK; \ rbtree_rotate_left (root_ptr, __rdf_xp); \ __rdf_x = *(root_ptr); \ break; \ } \ } else { \ struct rb_node_link* __w = __rdf_xp->left; \ if (rbtree_node_color (__w) == RBTREE_RED) { \ __w->color = RBTREE_BLACK; \ __rdf_xp->color = RBTREE_RED; \ rbtree_rotate_right (root_ptr, __rdf_xp); \ __w = __rdf_xp->left; \ } \ if (rbtree_node_color (__w->right) == RBTREE_BLACK && \ rbtree_node_color (__w->left) == RBTREE_BLACK) { \ if (__w) \ __w->color = RBTREE_RED; \ __rdf_x = __rdf_xp; \ __rdf_xp = __rdf_x->parent; \ } else { \ if (rbtree_node_color (__w->left) == RBTREE_BLACK) { \ if (__w->right) \ __w->right->color = RBTREE_BLACK; \ __w->color = RBTREE_RED; \ rbtree_rotate_left (root_ptr, __w); \ __w = __rdf_xp->left; \ } \ __w->color = __rdf_xp->color; \ __rdf_xp->color = RBTREE_BLACK; \ if (__w->left) \ __w->left->color = RBTREE_BLACK; \ rbtree_rotate_right (root_ptr, __rdf_xp); \ __rdf_x = *(root_ptr); \ break; \ } \ } \ } \ if (__rdf_x) \ __rdf_x->color = RBTREE_BLACK; \ } while (0) #define rbtree_delete(root_ptr, z_node) \ do { \ struct rb_node_link* __rd_z = (z_node); \ struct rb_node_link* __rd_y = __rd_z; \ struct rb_node_link* __rd_x = NULL; \ struct rb_node_link* __rd_xp = NULL; \ int __rd_y_orig_color = __rd_y->color; \ if (!__rd_z->left) { \ __rd_x = __rd_z->right; \ __rd_xp = __rd_z->parent; \ rbtree_transplant (root_ptr, __rd_z, __rd_z->right); \ } else if (!__rd_z->right) { \ __rd_x = __rd_z->left; \ __rd_xp = __rd_z->parent; \ rbtree_transplant (root_ptr, __rd_z, __rd_z->left); \ } else { \ rbtree_min (__rd_z->right, __rd_y); \ __rd_y_orig_color = __rd_y->color; \ __rd_x = __rd_y->right; \ if (__rd_y->parent == __rd_z) { \ __rd_xp = __rd_y; \ if (__rd_x) \ __rd_x->parent = __rd_y; \ } else { \ __rd_xp = __rd_y->parent; \ rbtree_transplant (root_ptr, __rd_y, __rd_y->right); \ __rd_y->right = __rd_z->right; \ __rd_y->right->parent = __rd_y; \ } \ rbtree_transplant (root_ptr, __rd_z, __rd_y); \ __rd_y->left = __rd_z->left; \ __rd_y->left->parent = __rd_y; \ __rd_y->color = __rd_z->color; \ } \ if (__rd_y_orig_color == RBTREE_BLACK) \ rbtree_delete_fixup (root_ptr, __rd_x, __rd_xp); \ } while (0) #define rbtree_next(node, out) \ do { \ (out) = NULL; \ if (node) { \ if ((node)->right) { \ struct rb_node_link* __n = (node)->right; \ while (__n->left) \ __n = __n->left; \ (out) = __n; \ } else { \ struct rb_node_link* __n = (node); \ struct rb_node_link* __p = (node)->parent; \ while (__p && __n == __p->right) { \ __n = __p; \ __p = __p->parent; \ } \ (out) = __p; \ } \ } \ } while (0) #define rbtree_prev(node, out) \ do { \ (out) = NULL; \ if (node) { \ if ((node)->left) { \ struct rb_node_link* __n = (node)->left; \ while (__n->right) \ __n = __n->right; \ (out) = __n; \ } else { \ struct rb_node_link* __n = (node); \ struct rb_node_link* __p = (node)->parent; \ while (__p && __n == __p->left) { \ __n = __p; \ __p = __p->parent; \ } \ (out) = __p; \ } \ } \ } while (0) #endif // _KERNEL_LIBK_RBTREE_H