Bitdefender Hypervisor Memory Introspection
rbtree.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "introcrt.h"
6 
7 #define RB_NODE_IS_BLACK(Node) (ncBlack == (Node)->Color)
8 #define RB_NODE_IS_RED(Node) (ncRed == (Node)->Color)
9 
10 
11 static void
13  _Inout_ RBTREE *Tree,
14  _Inout_ RBNODE *Node
15  )
16 {
17  // Algorithm:
18  // ==========
19  // LEFT-ROTATE(T, x)
20  // 1 y = x.right // set y
21  // 2 x.right = y.left // turn y's left subtree into x's right subtree
22  // 3 if y.left != T.nil
23  // 4 y.left.p = x
24  // 5 y.p = x.p // link x's parent to y
25  // 6 if x.p == T.nil
26  // 7 T.root = y
27  // 8 elseif x == x.p.left
28  // 9 x.p.left = y
29  // 10 else x.p.right = y
30  // 11 y.left = x // put x on y's left
31  // 12 x.p = y
32 
33  RBNODE *x = Node;
34  RBNODE *y = x->Right; // #1
35  x->Right = y->Left; // #2
36 
37  if (&Tree->Nil != y->Left) // #3
38  {
39  y->Left->Parent = x; // #4
40  }
41 
42  y->Parent = x->Parent; // #5
43 
44  if (&Tree->Nil == x->Parent) // #6
45  {
46  Tree->Root = y; // #7
47  }
48  else if (x == x->Parent->Left) // #8
49  {
50  x->Parent->Left = y; // #9
51  }
52  else
53  {
54  x->Parent->Right = y; // #10
55  }
56 
57  y->Left = x; // #11
58  x->Parent = y; // #12
59 }
60 
61 
62 static void
64  _Inout_ RBTREE *Tree,
65  _Inout_ RBNODE *Node
66  )
67 {
68  // Algorithm:
69  // ==========
70  // RIGHT-ROTATE(T, x)
71  // 1 y = x.left // set y
72  // 2 x.left = y.right// turn y's right subtree into x's left subtree
73  // 3 if y.right != T.nil
74  // 4 y.right.p = x
75  // 5 y.p = x.p // link x's parent to y
76  // 6 if x.p == T.nil
77  // 7 T.root = y
78  // 8 elseif x == x.p.right
79  // 9 x.p.right = y
80  // 10 else x.p.left = y
81  // 11 y.right = x // put x on y's right
82  // 12 x.p = y
83 
84  RBNODE *x = Node;
85  RBNODE *y = x->Left; // #1
86  x->Left = y->Right; // #2
87 
88  if (&Tree->Nil != y->Right) // #3
89  {
90  y->Right->Parent = x; // #4
91  }
92 
93  y->Parent = x->Parent; // #5
94 
95  if (&Tree->Nil == x->Parent) // #6
96  {
97  Tree->Root = y; // #7
98  }
99  else if (x == x->Parent->Right) // #8
100  {
101  x->Parent->Right = y; // #9
102  }
103  else
104  {
105  x->Parent->Left = y; // #10
106  }
107 
108  y->Right = x; // #11
109  x->Parent = y; // #12
110 }
111 
112 
113 static void
115  _Inout_ RBTREE *Tree,
116  _In_ RBNODE *Node
117  )
118 {
119  // Algorithm:
120  // ==========
121  // RB-DELETE-FIXUP (T, x)
122  // 1 while x != T.root and x.color == BLACK
123  // 2 if x == x.p.left
124  // 3 w = x.p.right
125  // 4 if w.color == RED
126  // 5 w.color = BLACK // case 1
127  // 6 x.p.color = RED // case 1
128  // 7 LEFT-ROTATE(T, x.p) // case 1
129  // 8 w = x.p.right // case 1
130  // 9 if w.left.color == BLACK and w.right.color == BLACK
131  // 10 w.color = RED // case 2
132  // 11 x = x.p // case 2
133  // 12 else if w.right.color == BLACK
134  // 13 w.left.color = BLACK // case 3
135  // 14 w.color = RED // case 3
136  // 15 RIGHT-ROTATE(T, w) // case 3
137  // 16 w = x.p.right // case 3
138  // 17 w.color = x.p.color // case 4
139  // 18 x.p.color = BLACK // case 4
140  // 19 w.right.color = BLACK // case 4
141  // 20 LEFT-ROTATE(T, x.p) // case 4
142  // 21 x = T.root // case 4
143  // 22 else
144  // 23 w = x.p.left
145  // 24 if w.color == RED
146  // 25 w.color = BLACK // case 1
147  // 26 x.p.color = RED // case 1
148  // 27 RIGHT-ROTATE(T, x.p) // case 1
149  // 28 w = x.p.left // case 1
150  // 29 if w.right.color == BLACK and w.left.color == BLACK
151  // 30 w.color = RED // case 2
152  // 31 x = x.p // case 2
153  // 32 else if w.left.color == BLACK
154  // 33 w.right.color = BLACK // case 3
155  // 34 w.color = RED // case 3
156  // 35 LEFT-ROTATE(T, w) // case 3
157  // 36 w = x.p.left // case 3
158  // 37 w.color = x.p.color // case 4
159  // 38 x.p.color = BLACK // case 4
160  // 39 w.left.color = BLACK // case 4
161  // 40 RIGHT-ROTATE(T, x.p) // case 4
162  // 41 x = T.root // case 4
163  // 42 x.color = BLACK
164 
165  RBNODE *x = Node;
166  RBNODE *w = &Tree->Nil;
167 
168  while (x != Tree->Root && x->Color == ncBlack) // #1
169  {
170  if (x == x->Parent->Left) // #2
171  {
172  w = x->Parent->Right; // #3
173 
174  if (RB_NODE_IS_RED(w)) // #4
175  {
176  w->Color = ncBlack; // #5
177  x->Parent->Color = ncRed; // #6
178  RbpLeftRotate(Tree, x->Parent); // #7
179  w = x->Parent->Right; // #8
180  }
181 
182  if (RB_NODE_IS_BLACK(w->Left) && RB_NODE_IS_BLACK(w->Right))// #9
183  {
184  w->Color = ncRed; // #10
185  x = x->Parent; // #11
186  }
187  else
188  {
189  if (RB_NODE_IS_BLACK(w->Right)) // #12
190  {
191  w->Left->Color = ncBlack; // #13
192  w->Color = ncRed; // #14
193  RbpRightRotate(Tree, w); // #15
194  w = x->Parent->Right; // #16
195  }
196 
197  w->Color = x->Parent->Color; // #17
198  x->Parent->Color = ncBlack; // #18
199  w->Right->Color = ncBlack; // #19
200  RbpLeftRotate(Tree, x->Parent); // #20
201  x = Tree->Root; // #21
202  }
203  }
204  else // #22
205  {
206  w = x->Parent->Left; // #3
207 
208  if (RB_NODE_IS_RED(w)) // #4
209  {
210  w->Color = ncBlack; // #5
211  x->Parent->Color = ncRed; // #6
212  RbpRightRotate(Tree, x->Parent); // #7
213  w = x->Parent->Left; // #8
214  }
215 
216  if (RB_NODE_IS_BLACK(w->Right) && RB_NODE_IS_BLACK(w->Left))// #9
217  {
218  w->Color = ncRed; // #10
219  x = x->Parent; // #11
220  }
221  else
222  {
223  if (RB_NODE_IS_BLACK(w->Left)) // #12
224  {
225  w->Right->Color = ncBlack; // #13
226  w->Color = ncRed; // #14
227  RbpLeftRotate(Tree, w); // #15
228  w = x->Parent->Left; // #16
229  }
230 
231  w->Color = x->Parent->Color; // #17
232  x->Parent->Color = ncBlack; // #18
233  w->Left->Color = ncBlack; // #19
234  RbpRightRotate(Tree, x->Parent); // #20
235  x = Tree->Root; // #21
236  }
237  }
238  }
239 
240  x->Color = ncBlack;
241 }
242 
243 
244 static void
246  _Inout_ RBTREE *Tree,
247  _Inout_ RBNODE *Node
248  )
249 {
250  // Algorithm:
251  // ==========
252  // RB-INSERT-FIXUP(T, z)
253  // 1 while z.p:color == RED
254  // 2 if z.p == z.p.p.left
255  // 3 y = z.p.p.right
256  // 4 if y.color == RED
257  // 5 z.p.color = BLACK // case 1
258  // 6 y.color = BLACK // case 1
259  // 7 z.p.p.color = RED // case 1
260  // 8 z = z.p.p // case 1
261  // 9 else if z == z.p.right
262  // 10 z = z.p // case 2
263  // 11 LEFT-ROTATE(T, z) // case 2
264  // 12 z.p.color = BLACK // case 3
265  // 13 z.p.p.color = RED // case 3
266  // 14 RIGHT-ROTATE(T, z.p.p) // case 3
267  // 15 else
268  // 16 y = z.p.p.left
269  // 17 if y.color == RED
270  // 18 z.p.color = BLACK // case 4
271  // 19 y.color = BLACK // case 4
272  // 20 z.p.p.color = RED // case 4
273  // 21 z = z.p.p // case 4
274  // 22 else if z == z.p.left
275  // 23 z = z.p // case 5
276  // 24 RIGHT-ROTATE(T, z) // case 5
277  // 25 z.p.color = BLACK // case 6
278  // 26 z.p.p.color = RED // case 6
279  // 27 LEFT-ROTATE(T, z.p.p) // case 6
280  // 28 T.root.color = BLACK
281 
282  RBNODE *z = Node;
283  RBNODE *y = &Tree->Nil;
284 
285  while (RB_NODE_IS_RED(z->Parent)) // #1
286  {
287  if (z->Parent == z->Parent->Parent->Left) // #2
288  {
289  y = z->Parent->Parent->Right; // #3
290 
291  if (RB_NODE_IS_RED(y)) // #4
292  {
293  z->Parent->Color = ncBlack; // #5
294  y->Color = ncBlack; // #6
295  z->Parent->Parent->Color = ncRed; // #7
296  z = z->Parent->Parent; // #8
297  }
298  else
299  {
300  if (z == z->Parent->Right) // #9
301  {
302  z = z->Parent; // #10
303  RbpLeftRotate(Tree, z); // #11
304  }
305  z->Parent->Color = ncBlack; // #12
306  z->Parent->Parent->Color = ncRed; // #13
307  RbpRightRotate(Tree, z->Parent->Parent); // #14
308  }
309  }
310  else // #15
311  {
312  y = z->Parent->Parent->Left; // #16
313 
314  if (RB_NODE_IS_RED(y)) // #17
315  {
316  z->Parent->Color = ncBlack; // #18
317  y->Color = ncBlack; // #19
318  z->Parent->Parent->Color = ncRed; // #20
319  z = z->Parent->Parent; // #21
320  }
321  else
322  {
323  if (z == z->Parent->Left) // #22
324  {
325  z = z->Parent; // #23
326  RbpRightRotate(Tree, z); // #24
327  }
328  z->Parent->Color = ncBlack; // #25
329  z->Parent->Parent->Color = ncRed; // #26
330  RbpLeftRotate(Tree, z->Parent->Parent); // #27
331  }
332  }
333  }
334 
335  Tree->Root->Color = ncBlack; // #28
336 }
337 
338 
339 static void
341  _Inout_ RBTREE *Tree,
342  _In_ RBNODE *Node1,
343  _In_ RBNODE *Node2
344  )
345 {
346  // Algorithm:
347  // ===========
348  // RB-TRANSPLANT(T, u, v)
349  // 1 if u.p == T.nil
350  // 2 T.root = v
351  // 3 elseif u == u.p.left
352  // 4 u.p.left = v
353  // 5 else u.p.right = v
354  // 6 v.p = u.p
355 
356  if (Node1->Parent == &Tree->Nil)
357  {
358  Tree->Root = Node2;
359  }
360  else
361  {
362  if (Node1 == Node1->Parent->Left)
363  {
364  Node1->Parent->Left = Node2;
365  }
366  else
367  {
368  Node1->Parent->Right = Node2;
369  }
370  }
371 
372  Node2->Parent = Node1->Parent;
373 }
374 
375 
376 void
378  _Inout_ RBTREE *Tree
379  )
380 {
381  memzero(Tree, sizeof(*Tree));
382 }
383 
384 
385 INTSTATUS
387  _Inout_ RBTREE *Tree,
388  _In_ PFUNC_RbTreeNodeFree NodeFree,
389  _In_ PFUNC_RbTreeNodeCompare NodeCompare
390  )
391 {
392  if (NULL == Tree)
393  {
395  }
396 
397  if (NULL == NodeFree)
398  {
400  }
401 
402  if (NULL == NodeCompare)
403  {
405  }
406 
407  Tree->Root = &Tree->Nil;
408  Tree->Nil.Left = Tree->Nil.Right = Tree->Nil.Parent = &Tree->Nil;
409  Tree->Nil.Color = ncBlack;
410  Tree->NodeFree = NodeFree;
411  Tree->NodeCompare = NodeCompare;
412  Tree->NodeCount = 0;
413 
414  return INT_STATUS_SUCCESS;
415 }
416 
417 
418 void
420  _Inout_ RBTREE *Tree
421  )
422 {
423  RBNODE *stack[RBTREE_MAXIMUM_LEVEL + 1];
424  int level = 0;
425 
426  stack[0] = Tree->Root;
427  while (Tree->NodeCount > 1)
428  {
429  // if left node is not Nil
430  if (&Tree->Nil != stack[level]->Left)
431  {
432  // traversing the left node first
433  level++;
434  stack[level] = stack[level - 1]->Left;
435  continue;
436  }
437 
438  // if right node is not nil
439  if (&Tree->Nil != stack[level]->Right)
440  {
441  // traversing the right node
442  level++;
443  stack[level] = stack[level - 1]->Right;
444  continue;
445  }
446 
447  // if we are here, the node has no children
448  // so we can delete the node deleting node
449 
450  // we can address level-1, because when nodecount is greater than 1
451  // we always have a root
452  if (stack[level - 1]->Left == stack[level])
453  {
454  // case 1: left child
455  stack[level - 1]->Left = &Tree->Nil;
456  }
457  else
458  {
459  // case 2: right child
460  stack[level - 1]->Right = &Tree->Nil;
461  }
462 
463  Tree->NodeFree(stack[level]);
464  Tree->NodeCount -= 1;
465  level--;
466  }
467 
468  if (Tree->Root != &Tree->Nil)
469  {
470  Tree->NodeFree(Tree->Root);
471  Tree->NodeCount = 0;
472  Tree->Root = &Tree->Nil;
473  }
474 }
475 
476 
477 RBNODE *
479  _In_ RBTREE *Tree,
480  _In_ RBNODE *NodeToSearch,
481  _Outptr_ RBNODE **Parent
482  )
483 {
484  RBNODE *node = Tree->Root;
485  *Parent = &Tree->Nil;
486 
487  while (&Tree->Nil != node)
488  {
489  int cmp = Tree->NodeCompare(node, NodeToSearch);
490 
491  if (0 == cmp) // we found the node
492  {
493  break;
494  }
495 
496  *Parent = node; // setting the parent of the node properly
497  if (0 > cmp) // the node is lesser
498  {
499  node = node->Right;
500  continue;
501  }
502 
503  // the node is greater
504  node = node->Left;
505  }
506 
507  if (node == &Tree->Nil)
508  {
509  node = NULL;
510  }
511 
512  return node;
513 }
514 
515 
516 INTSTATUS
518  _In_ RBTREE *Tree,
519  _In_ RBNODE *NodeToSearch,
520  _Outptr_ RBNODE **NodeFound
521  )
522 {
523  RBNODE *parent;
524 
525  if (NULL == Tree)
526  {
528  }
529 
530  if (NULL == NodeToSearch)
531  {
533  }
534 
535  if (NULL == NodeFound)
536  {
538  }
539 
540  *NodeFound = RbSearch(Tree, NodeToSearch, &parent);
541 
542  if (NULL == *NodeFound)
543  {
545  }
546 
547  return INT_STATUS_SUCCESS;
548 }
549 
550 
551 INTSTATUS
553  _In_ RBTREE *Tree,
555  _In_ void *Key,
556  _Out_ RBNODE **NodeFound
557  )
558 {
559  RBNODE *node;
560 
561  if (NULL == Tree)
562  {
564  }
565 
566  if (NULL == NodeFound)
567  {
569  }
570 
571  node = Tree->Root;
572 
573  while (&Tree->Nil != node)
574  {
575  int cmp = CompareFunc(node, Key);
576 
577  if (0 == cmp) // we found the node
578  {
579  break;
580  }
581 
582  if (0 > cmp) // the node is lesser
583  {
584  node = node->Right;
585  continue;
586  }
587 
588  // the node is greater
589  node = node->Left;
590  }
591 
592  if (node == &Tree->Nil)
593  {
594  node = NULL;
595  *NodeFound = NULL;
597  }
598 
599  *NodeFound = node;
600 
601  return INT_STATUS_SUCCESS;
602 }
603 
604 
605 INTSTATUS
607  _Inout_ RBTREE *Tree,
608  _Inout_ RBNODE *Node
609  )
610 {
611  // Algorithm:
612  // ==========
613  // RB-INSERT (T, z)
614  // 1 y = T.nil
615  // 2 x = T.root
616  // 3 while x != T.nil
617  // 4 y = x
618  // 5 if z.key < x.key
619  // 6 x = x.left
620  // 7 else x = x:right
621  // 8 z.p = y
622  // 9 if y == T.nil
623  // 10 T.root = z
624  // 11 else if z.key < y.key
625  // 12 y.left = z
626  // 13 else y.right = z
627  // 14 z.left = T.nil
628  // 15 z.right = T.nil
629  // 16 z.color = RED
630  // 17 RB-INSERT-FIXUP(T, z)
631 
632  RBNODE *auxNode;
633  RBNODE *parentNode;
634  int cmp;
635 
636  if (NULL == Tree)
637  {
639  }
640 
641  if (NULL == Node || &Tree->Nil == Node)
642  {
644  }
645 
646  // searching in the tree
647  // steps #1 -> #7
648  // y <- parentNode
649  auxNode = RbSearch(Tree, Node, &parentNode);
650 
652  if (NULL != auxNode)
653  {
654  // special case: cannot insert an element with the same key
656  }
657 
658  Tree->NodeCount++;
659 
660  Node->Parent = parentNode; // #8
661  if (&Tree->Nil == parentNode) // #9
662  {
663  // the tree was empty
664  Tree->Root = Node; // #10
665  }
666  else
667  {
668  cmp = Tree->NodeCompare(Node, parentNode);
669  if (cmp < 0) // #11
670  {
671  parentNode->Left = Node; // #12
672  }
673  else
674  {
675  parentNode->Right = Node; // #13
676  }
677  }
678 
679  Node->Left = &Tree->Nil; // #14
680  Node->Right = &Tree->Nil; // #15
681  Node->Color = ncRed; // #16
682 
683  RbpInsertFixup(Tree, Node);
684 
685  return INT_STATUS_SUCCESS;
686 }
687 
688 
689 RBNODE *
691  _In_ RBTREE *Tree,
692  _In_ RBNODE *Node
693  )
694 {
695  while (Node != NULL)
696  {
697  if (&Tree->Nil == Node->Left)
698  {
699  break;
700  }
701 
702  Node = Node->Left;
703  }
704 
705  return Node;
706 }
707 
708 
709 void
711  _Inout_ RBTREE *Tree,
712  _In_ RBNODE *Node
713  )
714 {
715  //RB-DELETE(T, z)
716  //1 y = z
717  //2 y-original-color = y.color
718  //3 if z.left == T.nil
719  //4 x = z.right
720  //5 RB-TRANSPLANT(T, z, z.right)
721  //6 elseif z.right == T.nil
722  //7 x = z.left
723  //8 RB-TRANSPLANT(T, z, z.left)
724  //9 else y = TREE-MINIMUM(z.right)
725  //10 y-original-color = y.color
726  //11 x = y.right
727  //12 if y.p == z
728  //13 x.p = y
729  //14 else RB-TRANSPLANT(T, y, y.right)
730  //15 y.right = z.right
731  //16 y.right.p = y
732  //17 RB-TRANSPLANT(T, z, y)
733  //18 y.left = z.left
734  //19 y.left.p = y
735  //20 y.color = z.color
736  //21 if y-original-color == BLACK
737  //22 RB-DELETE-FIXUP(T, x)
738 
739  RBNODE *z = Node;
740  RBNODE *y = z; // #1
741  RBNODE *x = &Tree->Nil;
742  RbNodeColor yOrigColor = y->Color; // #2
743 
744  if (&Tree->Nil == z->Left)
745  {
746  x = z->Right;
747  RbpTransplant(Tree, z, z->Right);
748  }
749  else
750  {
751  if (&Tree->Nil == z->Right)
752  {
753  x = z->Left;
754  RbpTransplant(Tree, z, z->Left);
755  }
756  else
757  {
758  y = RbTreeMinimum(Tree, z->Right);
759  yOrigColor = y->Color;
760  x = y->Right;
761 
762  if (y->Parent == z)
763  {
764  x->Parent = y;
765  }
766  else
767  {
768  RbpTransplant(Tree, y, y->Right);
769  y->Right = z->Right;
770  y->Right->Parent = y;
771  }
772 
773  RbpTransplant(Tree, z, y);
774 
775  y->Left = z->Left;
776  y->Left->Parent = y;
777  y->Color = z->Color;
778  }
779  }
780 
781  if (yOrigColor == ncBlack)
782  {
783  RbpDeleteFixup(Tree, x);
784  }
785 
786  Node->Parent = NULL;
787  Node->Left = NULL;
788  Node->Right = NULL;
789  Node->Color = ncBlack;
790 
791  Tree->NodeCount--;
792 }
793 
794 
795 //
796 // We need to disable this warning on gcc/clang since the build will fail with -Werror
797 //
798 #if defined(INT_COMPILER_GNUC) || (defined(INT_UNIX) && defined(INT_COMPILER_CLANG))
799 _Pragma("GCC diagnostic push");
800 _Pragma("GCC diagnostic ignored \"-Wstrict-overflow\"")
801 #endif
802 
803 
804 
805 INTSTATUS
807  _In_ RBTREE *Tree,
809  _In_opt_ void *WalkContext
810  )
811 {
812  //
813  // On the stack we will stock the current state of the node;
814  // Possible values:
815  // 0 - no nodes were visited
816  // 1 - left node was visited - the current node should be visited
817  // 2 - the current node was visited, we should go for the right node
818  // 3 - all nodes were visited
819  //
820  size_t stack[RBTREE_MAXIMUM_LEVEL + 1];
821  ssize_t level = 0;
822  RBNODE *node = NULL;
823  BOOLEAN res = FALSE;
824 
825  node = Tree->Root;
826  stack[level] = 0;
827 
828  if (Tree->Root == &Tree->Nil)
829  {
830  // the tree is empty
831  return INT_STATUS_SUCCESS;
832  }
833 
834  while (level >= 0)
835  {
836  if (level == RBTREE_MAXIMUM_LEVEL)
837  {
839  }
840 
841  switch (stack[level])
842  {
843  case 0:
844  stack[level] = 1; // we set that this node
845 
846  if (node->Left != &Tree->Nil)
847  {
848  // otherwise we should go for the next node in the left side
849  level += 1;
850  node = node->Left; // visiting the left node
851  stack[level] = 0; // setting it's state as 0 - no left side was visited
852  }
853 
854  break;
855 
856  case 1:
857  // the left node was visited
858  stack[level] = 2;
859  res = Callback(node, WalkContext); // calling the given function
860 
861  if (!res)
862  {
863  // on FALSE we should stop the walking process
864  return INT_STATUS_FOUND;
865  }
866 
867  break;
868 
869  case 2:
870  // current node was visited, we should visit the left side node
871  stack[level] = 3;
872 
873  if (node->Right != &Tree->Nil)
874  {
875  level += 1;
876  node = node->Right;
877  stack[level] = 0;
878  }
879 
880  break;
881 
882  case 3:
883  // the left node was visited, we should go one level up
884  level -= 1;
885  node = node->Parent;
886  break;
887  }
888  }
889 
890  return INT_STATUS_SUCCESS;
891 }
892 
893 #if defined(INT_COMPILER_GNUC) || (defined(INT_UNIX) && defined(INT_COMPILER_CLANG))
894 _Pragma("GCC diagnostic pop");
895 #endif
void RbUninit(RBTREE *Tree)
Definition: rbtree.c:419
#define _In_opt_
Definition: intro_sal.h:16
RbNodeColor Color
Definition: rbtree.h:39
_Bool BOOLEAN
Definition: intro_types.h:58
#define _Out_
Definition: intro_sal.h:22
INTSTATUS RbInit(RBTREE *Tree, PFUNC_RbTreeNodeFree NodeFree, PFUNC_RbTreeNodeCompare NodeCompare)
Definition: rbtree.c:386
#define INT_STATUS_FOUND
Definition: introstatus.h:329
struct _RBNODE * Right
Definition: rbtree.h:37
FUNC_RbTreeNodeCompare * PFUNC_RbTreeNodeCompare
Definition: rbtree.h:60
struct _RBNODE * Parent
Definition: rbtree.h:38
#define _In_
Definition: intro_sal.h:21
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
#define INT_STATUS_DATA_NOT_FOUND
Definition: introstatus.h:174
static void RbpDeleteFixup(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:114
#define RB_NODE_IS_RED(Node)
Definition: rbtree.c:8
#define RBTREE_MAXIMUM_LEVEL
Definition: rbtree.h:16
Definition: rbtree.h:24
Definition: rbtree.h:34
void RbDeleteNode(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:710
void RbPreinit(RBTREE *Tree)
Definition: rbtree.c:377
INTSTATUS RbInsertNode(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:606
#define _Outptr_
Definition: intro_sal.h:19
int INTSTATUS
The status data type.
Definition: introstatus.h:24
#define INT_STATUS_BUFFER_OVERFLOW
Definition: introstatus.h:200
#define _Inout_
Definition: intro_sal.h:20
INTSTATUS RbWalkInorderTree(RBTREE *Tree, PFUNC_RbTreeWalkCallback Callback, void *WalkContext)
Definition: rbtree.c:806
struct _RBNODE * Left
Definition: rbtree.h:36
#define RB_NODE_IS_BLACK(Node)
Definition: rbtree.c:7
#define memzero(a, s)
Definition: introcrt.h:35
RBNODE * RbSearch(RBTREE *Tree, RBNODE *NodeToSearch, RBNODE **Parent)
Definition: rbtree.c:478
#define INT_STATUS_KEY_ALREADY_EXISTS
Definition: introstatus.h:239
static void RbpTransplant(RBTREE *Tree, RBNODE *Node1, RBNODE *Node2)
Definition: rbtree.c:340
INTSTATUS RbLookupNode(RBTREE *Tree, RBNODE *NodeToSearch, RBNODE **NodeFound)
Definition: rbtree.c:517
Definition: rbtree.h:23
FUNC_RbTreeWalkCallback * PFUNC_RbTreeWalkCallback
Definition: rbtree.h:79
Definition: rbtree.h:84
static void RbpInsertFixup(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:245
static void RbpRightRotate(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:63
INTSTATUS RbLookupNodeCustomCompare(RBTREE *Tree, PFUNC_RbTreeNodeCustomCompare CompareFunc, void *Key, RBNODE **NodeFound)
Definition: rbtree.c:552
FUNC_RbTreeNodeFree * PFUNC_RbTreeNodeFree
Definition: rbtree.h:48
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
enum _RbNodeColor RbNodeColor
RBNODE * RbTreeMinimum(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:690
static void RbpLeftRotate(RBTREE *Tree, RBNODE *Node)
Definition: rbtree.c:12
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
#define FALSE
Definition: intro_types.h:34
FUNC_RbTreeNodeCustomCompare * PFUNC_RbTreeNodeCustomCompare
Definition: rbtree.h:71
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68