feat(tree): bit flag so children know which child they are
							parent
							
								
									193fc4b454
								
							
						
					
					
						commit
						e5130a6383
					
				|  | @ -16,7 +16,7 @@ vieter_tree_error vieter_tree_insert(vieter_tree *tree, uint64_t key, | |||
|     tree->root = vieter_tree_node_init(); | ||||
|     tree->root->key = key; | ||||
|     tree->root->data = data; | ||||
|     vieter_tree_node_set(tree->root, vieter_tree_node_black); | ||||
|     vieter_tree_node_set(tree->root, vieter_tree_node_black, true); | ||||
|     tree->size = 1; | ||||
| 
 | ||||
|     return vieter_tree_ok; | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "vieter_tree_balancing.h" | ||||
| #include <string.h> | ||||
| 
 | ||||
| bool vieter_tree_node_validate(vieter_tree_node *node, | ||||
|                                uint64_t passed_black_nodes, | ||||
|  | @ -38,48 +39,48 @@ vieter_tree_node *vieter_tree_node_balance(vieter_tree_node *node) { | |||
|   uint64_t key_root = root->key; | ||||
|   void *data_root = root->data; | ||||
| 
 | ||||
|   if (node->key < parent->key && parent->key < grand_parent->key) { | ||||
|   if (vieter_tree_node_get(node, vieter_tree_node_right)) { | ||||
|     left = parent; | ||||
|     right = node; | ||||
| 
 | ||||
|     if (vieter_tree_node_get(parent, vieter_tree_node_right)) { | ||||
|       root->key = parent->key; | ||||
|       root->data = parent->data; | ||||
| 
 | ||||
|       parent->key = key_root; | ||||
|       parent->data = data_root; | ||||
| 
 | ||||
|     left = node; | ||||
|     right = parent; | ||||
| 
 | ||||
|     children[0] = node->children[0]; | ||||
|     children[1] = node->children[1]; | ||||
|     children[2] = parent->children[1]; | ||||
|     children[3] = grand_parent->children[1]; | ||||
|   } else if (node->key < parent->key && parent->key > grand_parent->key) { | ||||
|     root->key = node->key; | ||||
|     root->data = node->data; | ||||
| 
 | ||||
|     node->key = key_root; | ||||
|     node->data = data_root; | ||||
| 
 | ||||
|     left = node; | ||||
|     right = parent; | ||||
| 
 | ||||
|       children[0] = grand_parent->children[0]; | ||||
|     children[1] = node->children[0]; | ||||
|     children[2] = node->children[1]; | ||||
|     children[3] = parent->children[1]; | ||||
|   } else if (node->key > parent->key && parent->key < grand_parent->key) { | ||||
|       children[1] = parent->children[0]; | ||||
|       children[2] = node->children[0]; | ||||
|       children[3] = node->children[1]; | ||||
|     } else { | ||||
|       root->key = node->key; | ||||
|       root->data = node->data; | ||||
| 
 | ||||
|       node->key = key_root; | ||||
|       node->data = data_root; | ||||
| 
 | ||||
|     left = parent; | ||||
|     right = node; | ||||
| 
 | ||||
|       children[0] = parent->children[0]; | ||||
|       children[1] = node->children[0]; | ||||
|       children[2] = node->children[1]; | ||||
|       children[3] = grand_parent->children[1]; | ||||
|     } | ||||
|   } else { | ||||
|     left = node; | ||||
|     right = parent; | ||||
| 
 | ||||
|     if (vieter_tree_node_get(parent, vieter_tree_node_right)) { | ||||
|       root->key = node->key; | ||||
|       root->data = node->data; | ||||
| 
 | ||||
|       node->key = key_root; | ||||
|       node->data = data_root; | ||||
| 
 | ||||
|       children[0] = grand_parent->children[0]; | ||||
|       children[1] = node->children[0]; | ||||
|       children[2] = node->children[1]; | ||||
|       children[3] = parent->children[1]; | ||||
|     } else { | ||||
|       root->key = parent->key; | ||||
|       root->data = parent->data; | ||||
|  | @ -87,36 +88,47 @@ vieter_tree_node *vieter_tree_node_balance(vieter_tree_node *node) { | |||
|       parent->key = key_root; | ||||
|       parent->data = data_root; | ||||
| 
 | ||||
|     left = parent; | ||||
|     right = node; | ||||
| 
 | ||||
|     children[0] = grand_parent->children[0]; | ||||
|     children[1] = parent->children[0]; | ||||
|     children[2] = node->children[0]; | ||||
|     children[3] = node->children[1]; | ||||
|       children[0] = node->children[0]; | ||||
|       children[1] = node->children[1]; | ||||
|       children[2] = parent->children[1]; | ||||
|       children[3] = grand_parent->children[1]; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   vieter_tree_node_set(left, vieter_tree_node_black); | ||||
|   vieter_tree_node_set(right, vieter_tree_node_black); | ||||
|   vieter_tree_node_unset(root, vieter_tree_node_black); | ||||
|   vieter_tree_node_set( | ||||
|       root, vieter_tree_node_right, | ||||
|       vieter_tree_node_get(grand_parent, vieter_tree_node_right)); | ||||
| 
 | ||||
|   left->children[0] = children[0]; | ||||
|   left->children[1] = children[1]; | ||||
|   vieter_tree_node_set(left, vieter_tree_node_black, true); | ||||
|   vieter_tree_node_set(left, vieter_tree_node_right, false); | ||||
|   vieter_tree_node_set(right, vieter_tree_node_black, true); | ||||
|   vieter_tree_node_set(left, vieter_tree_node_right, true); | ||||
| 
 | ||||
|   if (children[0] != NULL) | ||||
|   vieter_tree_node_set(root, vieter_tree_node_black, false); | ||||
| 
 | ||||
|   memcpy(&left->children, children, 2 * sizeof(vieter_tree_node *)); | ||||
| 
 | ||||
|   if (children[0] != NULL) { | ||||
|     children[0]->parent = left; | ||||
|     vieter_tree_node_set(children[0], vieter_tree_node_right, false); | ||||
|   } | ||||
| 
 | ||||
|   if (children[1] != NULL) | ||||
|   if (children[1] != NULL) { | ||||
|     children[1]->parent = left; | ||||
|     vieter_tree_node_set(children[0], vieter_tree_node_right, true); | ||||
|   } | ||||
| 
 | ||||
|   right->children[0] = children[2]; | ||||
|   right->children[1] = children[3]; | ||||
|   memcpy(&right->children, children + 2, 2 * sizeof(vieter_tree_node *)); | ||||
| 
 | ||||
|   if (children[2] != NULL) | ||||
|   if (children[2] != NULL) { | ||||
|     children[2]->parent = right; | ||||
|     vieter_tree_node_set(children[2], vieter_tree_node_right, false); | ||||
|   } | ||||
| 
 | ||||
|   if (children[3] != NULL) | ||||
|   if (children[3] != NULL) { | ||||
|     children[3]->parent = right; | ||||
|     vieter_tree_node_set(children[2], vieter_tree_node_right, true); | ||||
|   } | ||||
| 
 | ||||
|   root->children[0] = left; | ||||
|   root->children[1] = right; | ||||
|  | @ -135,7 +147,7 @@ void vieter_tree_node_balance_after_insert(vieter_tree_node *node) { | |||
| 
 | ||||
|   // The root must always be black
 | ||||
|   if (node->parent == NULL) { | ||||
|     vieter_tree_node_set(node, vieter_tree_node_black); | ||||
|     vieter_tree_node_set(node, vieter_tree_node_black, true); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #include "vieter_tree_node.h" | ||||
| #include "vieter_tree_balancing.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| 
 | ||||
| vieter_tree_node *vieter_tree_node_init() { | ||||
|   return calloc(1, sizeof(vieter_tree_node)); | ||||
| } | ||||
|  | @ -13,10 +15,12 @@ void vieter_tree_node_add_child(vieter_tree_node *parent, uint64_t key, | |||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   parent->children[key > parent->key] = child; | ||||
|   bool side = key > parent->key; | ||||
|   parent->children[side] = child; | ||||
| 
 | ||||
|   if (child != NULL) { | ||||
|     child->parent = parent; | ||||
|     vieter_tree_node_set(child, vieter_tree_node_right, side); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -24,8 +28,8 @@ void vieter_tree_node_replace_with_child(vieter_tree_node *to_replace, | |||
|                                          vieter_tree_node *replacement) { | ||||
|   to_replace->key = replacement->key; | ||||
|   to_replace->data = replacement->data; | ||||
|   to_replace->children[0] = replacement->children[0]; | ||||
|   to_replace->children[1] = replacement->children[1]; | ||||
|   memcpy(to_replace->children, replacement->children, | ||||
|          2 * sizeof(vieter_tree_node *)); | ||||
| 
 | ||||
|   if (to_replace->children[0] != NULL) | ||||
|     to_replace->children[0]->parent = to_replace; | ||||
|  | @ -140,13 +144,13 @@ vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root, | |||
|   return vieter_tree_ok; | ||||
| } | ||||
| 
 | ||||
| void vieter_tree_node_set(vieter_tree_node *node, vieter_tree_node_flag flag) { | ||||
| void vieter_tree_node_set(vieter_tree_node *node, vieter_tree_node_flag flag, | ||||
|                           bool set) { | ||||
|   if (set) { | ||||
|     node->flags |= flag; | ||||
| } | ||||
| 
 | ||||
| void vieter_tree_node_unset(vieter_tree_node *node, | ||||
|                             vieter_tree_node_flag flag) { | ||||
|   } else { | ||||
|     node->flags &= ~flag; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| bool vieter_tree_node_get(vieter_tree_node *node, vieter_tree_node_flag flag) { | ||||
|  |  | |||
|  | @ -37,8 +37,7 @@ vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root, ui | |||
| 
 | ||||
| void vieter_tree_node_replace_with_child(vieter_tree_node *to_replace, vieter_tree_node *replacement); | ||||
| 
 | ||||
| void vieter_tree_node_set(vieter_tree_node *node, vieter_tree_node_flag flag); | ||||
| void vieter_tree_node_unset(vieter_tree_node *node, vieter_tree_node_flag flag); | ||||
| void vieter_tree_node_set(vieter_tree_node *node, vieter_tree_node_flag flag, bool value); | ||||
| bool vieter_tree_node_get(vieter_tree_node *node, vieter_tree_node_flag flag); | ||||
| 
 | ||||
| void vieter_tree_node_add_child(vieter_tree_node *parent, uint64_t key, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue