From 2497a94013261d6fa9159b9c6e94abe6f2d4fd9e Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 3 Oct 2026 12:03:11 -0400 Subject: process rbtree. add syscall for initrd_file access. --- lib/rbtree.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 lib/rbtree.c (limited to 'lib/rbtree.c') diff --git a/lib/rbtree.c b/lib/rbtree.c new file mode 100644 index 0000000..dc9caf1 --- /dev/null +++ b/lib/rbtree.c @@ -0,0 +1,84 @@ +#include "rbtree.h" + +static inline int +s_direction(const struct rbtree_node *node) +{ + return node == node->parent->children[0] ? 0 : 1; +} + +static struct rbtree_node* +s_rotate(struct rbtree_node *sub, int dir) +{ + int opp = 1 - dir; + struct rbtree_node *sub_parent = sub->parent; + struct rbtree_node *new_root = sub_parent->children[opp]; + struct rbtree_node *new_child = new_root->children[dir]; + + sub_parent->children[opp] = new_child; + if(new_child) new_child->parent = sub; + + new_root->children[dir] = sub; + new_root->parent = sub_parent; + sub->parent = new_root; + + if(sub_parent) + sub_parent->children[s_direction(sub)] = new_root; + return new_root; +} + +void +rbtree_insert(struct rbtree_node *root, struct rbtree_node *node) +{ + struct rbtree_node *parent = root; + int direction; + while(1) { + direction = parent->get_key(parent) < node->get_key(node); + if(parent->children[direction] == 0) break; + parent = parent->children[direction]; + } + + node->color = 1; + parent->children[direction] = node; + node->parent = parent; + + //Rebalance the tree + do { + //Tree is already balanced, return + if(parent->color == 0) return; + struct rbtree_node *gparent = parent->parent; + + //Parent is the root node, set parent to black. + if(!gparent) { + parent->color = 0; + return; + } + + direction = s_direction(parent); + struct rbtree_node *uncle = gparent->children[1-direction]; + if(!uncle || uncle->color == 0) { + //If the uncle node DNE or is black, the tree has to be rotated. + if(node == parent->children[1-direction]) { + //Rotate parent node so that node is the new parent. + s_rotate(parent, direction); + node = parent; + parent = gparent->children[direction]; + } + + //Rotate the parent node so that the gparent is the new parent. + s_rotate(gparent, 1-direction); + parent->color = 0; + gparent->color = 1; + return; + } + + //Both the parent and uncle are red. Push up the red and iterate up. + parent->color = 0; + uncle->color = 0; + gparent->color = 1; + node = gparent; + } while((parent = node->parent)); + + //Tree is balanced now. +} + + -- cgit v1.2.3