Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
rbt.h
Go to the documentation of this file.
1#ifndef __LIBK__TREE__RBT__
2#define __LIBK__TREE__RBT__
3
4#ifndef RBT_TYPE
5struct __rbt_type {
6 unsigned long id; // Unique identifier for the data type
7};
8#define RBT_TYPE struct __rbt_type
9#warning "RBT_TYPE is not defined, using default struct __rbt_type"
10#endif // RBT_TYPE
11
12#ifndef RBT_ID_NAME
13#define RBT_ID_NAME id
14#warning "RBT_ID_NAME is not defined, using default id"
15#endif // RBT_ID_NAME
16
17#define FIELD_ACCESS(data_ptr, field) ((data_ptr)->field)
18
19#include <libk/serial.h>
20#include <str.h>
21#include <type.h>
22
24
25typedef struct rbt_node rbt_node;
33
34static inline void
36 // serial_trace("rbt_rotate_left: rotating left on node with id %d\n",
37 // FIELD_ACCESS(x->data, RBT_ID_NAME));
38 rbt_node* y = x->right;
39 x->right = y->left;
40
41 if (y->left != NIL)
42 y->left->parent = x;
43
44 y->parent = x->parent;
45 if (x->parent == NIL)
46 *root = y;
47 else if (x == x->parent->left)
48 x->parent->left = y;
49 else
50 x->parent->right = y;
51 y->left = x;
52 x->parent = y;
53}
54
55static inline void
57 // serial_trace("rbt_rotate_right: rotating right on node with id %d\n",
58 // FIELD_ACCESS(y->data, RBT_ID_NAME));
59 rbt_node* x = y->left;
60 y->left = x->right;
61
62 if (x->right != NIL) {
63 x->right->parent = y;
64 }
65 x->parent = y->parent;
66 if (y->parent == NIL) {
67 *root = x;
68 } else if (y == y->parent->right) {
69 y->parent->right = x;
70 } else {
71 y->parent->left = x;
72 }
73 x->right = y;
74 y->parent = x;
75}
76
77static inline void rbt_fix_insert(rbt_node** root, rbt_node* y, rbt_node* NIL) {
78 // serial_trace("rbt_fix_insert: fixing insert for node with id %d\n",
79 // FIELD_ACCESS(y->data, RBT_ID_NAME));
80 while (y->parent->color == RBT_RED) {
81 // serial_trace("rbt_fix_insert: y->parent->color is RED\n");
82 if (y->parent == y->parent->parent->left) {
83 // serial_trace("rbt_fix_insert: fixing insert, y->parent is left
84 // child\n");
85 rbt_node* x = y->parent->parent->right;
86 if (x != 0 && x->color == RBT_RED) {
87 // serial_trace("rbt_fix_insert: fixing insert, case 1\n");
88 y->parent->color = RBT_BLACK;
89 x->color = RBT_BLACK;
90 y->parent->parent->color = RBT_RED;
91 y = y->parent->parent;
92 } else {
93 if (y == y->parent->right) {
94 y = y->parent;
96 }
97 y->parent->color = RBT_BLACK;
98 y->parent->parent->color = RBT_RED;
99 rbt_rotate_right(root, y->parent->parent, NIL);
100 }
101 } else {
102 rbt_node* x = y->parent->parent->left;
103 if (x != 0 && x->color == RBT_RED) {
104 y->parent->color = RBT_BLACK;
105 x->color = RBT_BLACK;
106 y->parent->parent->color = RBT_RED;
107 y = y->parent->parent;
108 } else {
109 if (y == y->parent->left) {
110 y = y->parent;
112 }
113 y->parent->color = RBT_BLACK;
114 y->parent->parent->color = RBT_RED;
115 rbt_rotate_left(root, y->parent->parent, NIL);
116 }
117 }
118 }
119 (*root)->color = RBT_BLACK;
120}
121
122static inline int
124 memset(z, 0, sizeof(rbt_node));
125 z->data = data;
126 z->left = z->right = NIL;
127 z->color = RBT_RED;
128
129 // mencari posisi
131 rbt_node* curent = *root;
132 while (curent != NIL) {
133 // serial_trace("}} curent->data->id : %d\n", curent->data->id);
134 parent = curent;
135
137 < FIELD_ACCESS(curent->data, RBT_ID_NAME))
138 curent = curent->left;
139 else
140 curent = curent->right;
141 }
142
143 z->parent = parent;
144 if (parent == NIL) {
145 // serial_trace("}} root is null\n");
146 *root = z;
147 } else if (FIELD_ACCESS(z->data, RBT_ID_NAME)
149 parent->left = z;
150 else
151 parent->right = z;
152
153 if (z->parent == NIL) {
154 z->color = RBT_BLACK;
155 return 1;
156 }
157
158 if (z->parent->parent == NIL) {
159 return 1;
160 }
161 // serial_trace("rbt_fix_insert: fixing insert\n");
162
164 return 1;
165}
166
167static inline rbt_node*
169 if (root == NIL || FIELD_ACCESS(root->data, RBT_ID_NAME) == id)
170 return root;
171
172 if (id < FIELD_ACCESS(root->data, RBT_ID_NAME))
173 return rbt_search_node(root->left, id, NIL);
174
175 return rbt_search_node(root->right, id, NIL);
176}
177
178static inline void rbt_fix_delete(rbt_node** root, rbt_node* x, rbt_node* NIL) {
179 // serial_trace("rbt_fix_delete: fixing delete for node with id %d\n",
180 // FIELD_ACCESS(x->data, RBT_ID_NAME));
181 while (x != *root && x->color == RBT_BLACK) {
182 if (x == x->parent->left) {
183 rbt_node* w = x->parent->right;
184 if (w->color == RBT_RED) {
185 w->color = RBT_BLACK;
186 x->parent->color = RBT_RED;
187 rbt_rotate_left(root, x->parent, NIL);
188 w = x->parent->right;
189 }
190 if (w->left->color == RBT_BLACK
191 && w->right->color == RBT_BLACK) {
192 w->color = RBT_RED;
193 x = x->parent;
194 } else {
195 if (w->right->color == RBT_BLACK) {
196 w->left->color = RBT_BLACK;
197 w->color = RBT_RED;
199 w = x->parent->right;
200 }
201 w->color = x->parent->color;
202 x->parent->color = RBT_BLACK;
203 w->right->color = RBT_BLACK;
204 rbt_rotate_left(root, x->parent, NIL);
205 x = *root;
206 }
207 } else {
208 rbt_node* w = x->parent->left;
209 if (w->color == RBT_RED) {
210 w->color = RBT_BLACK;
211 x->parent->color = RBT_RED;
212 rbt_rotate_right(root, x->parent, NIL);
213 w = x->parent->left;
214 }
215 if (w->right->color == RBT_BLACK
216 && w->left->color == RBT_BLACK) {
217 w->color = RBT_RED;
218 x = x->parent;
219 } else {
220 if (w->left->color == RBT_BLACK) {
221 w->right->color = RBT_BLACK;
222 w->color = RBT_RED;
224 w = x->parent->left;
225 }
226 w->color = x->parent->color;
227 x->parent->color = RBT_BLACK;
228 w->left->color = RBT_BLACK;
229 rbt_rotate_right(root, x->parent, NIL);
230 x = *root;
231 }
232 }
233 }
234 x->color = RBT_BLACK;
235}
236
237static inline void
239 rbt_node* y = z;
240 rbt_node* x;
241 rbt_node_color y_original_color = y->color;
242
243 if (z->left == NIL) {
244 x = z->right;
245 if (z->parent == NIL) {
246 *root = x;
247 } else if (z == z->parent->left) {
248 z->parent->left = z->right;
249 } else {
250 z->parent->right = z->right;
251 }
252 if (z->right != NIL) {
253 z->right->parent = z->parent;
254 }
255 } else if (z->right == NIL) {
256 x = z->left;
257 if (z->parent == NIL) {
258 *root = x;
259 } else if (z == z->parent->left) {
260 z->parent->left = z->left;
261 } else {
262 z->parent->right = z->left;
263 }
264 if (z->left != NIL) {
265 z->left->parent = z->parent;
266 }
267 } else {
268 y = z->right;
269 while (y->left != NIL) {
270 y = y->left;
271 }
272 y_original_color = y->color;
273 x = y->right;
274 if (y->parent == z) {
275 if (x != NIL) {
276 x->parent = y;
277 }
278 } else {
279 if (y->parent != NIL) {
280 y->parent->left = y->right;
281 }
282 if (y->right != NIL) {
283 y->right->parent = y->parent;
284 }
285 y->right = z->right;
286 if (y->right != NIL) {
287 y->right->parent = y;
288 }
289 }
290
291 if (z->parent == NIL) {
292 *root = y;
293 } else if (z == z->parent->left) {
294 z->parent->left = y;
295 } else {
296 z->parent->right = y;
297 }
298 y->parent = z->parent;
299 y->color = z->color;
300 if (y->left != NIL) {
301 y->left->parent = y;
302 }
303 }
304 if (y_original_color == RBT_BLACK) {
305 // serial_trace("rbt_remove_node: fixing delete\n");
307 }
308}
309
310#endif // __LIBK__TREE__RBT__
dentry_ptr parent
Definition dentry.h:7
struct fs_data data
Definition filesystem.h:1
static struct ioforge_device * root
Definition ioforge.c:25
static rbt_node * rbt_search_node(rbt_node *root, uint64_t id, rbt_node *NIL)
Definition rbt.h:168
rbt_node_color
Definition rbt.h:23
@ RBT_RED
Definition rbt.h:23
@ RBT_BLACK
Definition rbt.h:23
#define RBT_ID_NAME
Definition rbt.h:13
#define RBT_TYPE
Definition rbt.h:8
static void rbt_rotate_right(rbt_node **root, rbt_node *y, rbt_node *NIL)
Definition rbt.h:56
static void rbt_remove_node(rbt_node **root, rbt_node *z, rbt_node *NIL)
Definition rbt.h:238
static void rbt_fix_delete(rbt_node **root, rbt_node *x, rbt_node *NIL)
Definition rbt.h:178
#define FIELD_ACCESS(data_ptr, field)
Definition rbt.h:17
static void rbt_fix_insert(rbt_node **root, rbt_node *y, rbt_node *NIL)
Definition rbt.h:77
static void rbt_rotate_left(rbt_node **root, rbt_node *x, rbt_node *NIL)
Definition rbt.h:35
static int rbt_insert_node(rbt_node **root, rbt_node *z, struct __rbt_type *data, rbt_node *NIL)
Definition rbt.h:123
void memset(void *ptr, int value, size_t num)
unsigned long id
Definition rbt.h:6
Definition rbt.h:26
rbt_node * right
Definition rbt.h:29
rbt_node_color color
Definition rbt.h:31
rbt_node * left
Definition rbt.h:28
rbt_node * parent
Definition rbt.h:30
struct __rbt_type * data
Definition rbt.h:27
unsigned long uint64_t
Definition type.h:25
static rbt_node * NIL
Definition vfs.c:37
uint32_t y
Definition virtio-gpu.hpp:1
uint32_t x
Definition virtio-gpu.hpp:0