test(tree): validation function to use in testing
							parent
							
								
									89d1c9cdca
								
							
						
					
					
						commit
						3fb027715c
					
				|  | @ -1,4 +1,4 @@ | |||
| #include "vieter_tree.h" | ||||
| #include "vieter_tree_internal.h" | ||||
| #include "vieter_tree_node.h" | ||||
| 
 | ||||
| struct vieter_tree { | ||||
|  | @ -98,3 +98,23 @@ void vieter_tree_free(vieter_tree *tree) { | |||
| end: | ||||
|   free(tree); | ||||
| } | ||||
| 
 | ||||
| int vieter_tree_validate(vieter_tree *tree) { | ||||
|   if (tree->size == 0) { | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // DFS to get expected black nodes
 | ||||
|   uint64_t expected_black_nodes = 0; | ||||
|   vieter_tree_node *node = tree->root; | ||||
| 
 | ||||
|   while (node != NULL) { | ||||
|     if (vieter_tree_node_get(node, vieter_node_black)) { | ||||
|       expected_black_nodes++; | ||||
|     } | ||||
| 
 | ||||
|     node = node->left; | ||||
|   } | ||||
| 
 | ||||
|   return vieter_tree_node_validate(tree->root, 0, expected_black_nodes); | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,43 @@ | |||
| #include "vieter_tree_balancing.h" | ||||
| 
 | ||||
| int vieter_tree_node_validate(vieter_tree_node *node, | ||||
|                               uint64_t passed_black_nodes, | ||||
|                               uint64_t expected_black_nodes) { | ||||
|   if (vieter_tree_node_get(node, vieter_node_black)) { | ||||
|     passed_black_nodes++; | ||||
|   } else { | ||||
|     // A red node should have black child nodes
 | ||||
|     if ((node->left != NULL && | ||||
|          !vieter_tree_node_get(node->left, vieter_node_black)) || | ||||
|         (node->right != NULL && | ||||
|          !vieter_tree_node_get(node->right, vieter_node_black))) { | ||||
|       return 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // All paths to a NULL child should have the same amount of black nodes
 | ||||
|   if ((node->left == NULL || node->right == NULL) && | ||||
|       passed_black_nodes != expected_black_nodes) { | ||||
|     return 1; | ||||
|   } | ||||
| 
 | ||||
|   if (node->left != NULL) { | ||||
|     if (vieter_tree_node_validate(node->left, passed_black_nodes, | ||||
|                                   expected_black_nodes) != 0) { | ||||
|       return 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (node->right != NULL) { | ||||
|     if (vieter_tree_node_validate(node->right, passed_black_nodes, | ||||
|                                   expected_black_nodes) != 0) { | ||||
|       return 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| vieter_tree_node *vieter_tree_node_balance(vieter_tree_node *node) { | ||||
|   vieter_tree_node *parent = node->parent; | ||||
|   vieter_tree_node *grand_parent = parent->parent; | ||||
|  |  | |||
|  | @ -0,0 +1,8 @@ | |||
| #include "vieter_tree.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * Inspect whether the tree is still a valid red-black-tree. | ||||
|  * | ||||
|  * @return 0 if correct, 1 if not. | ||||
|  */ | ||||
| int vieter_tree_validate(vieter_tree *tree); | ||||
|  | @ -40,4 +40,6 @@ bool vieter_tree_node_get(vieter_tree_node *node, vieter_node_flag flag); | |||
| void vieter_tree_node_add_child(vieter_tree_node *parent, uint64_t key, | ||||
|                                 vieter_tree_node *child); | ||||
| 
 | ||||
| int vieter_tree_node_validate(vieter_tree_node *node, uint64_t passed_black_nodes, uint64_t expected_black_nodes); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| #include "acutest.h" | ||||
| #include "vieter_tree.h" | ||||
| #include "vieter_tree_internal.h" | ||||
| 
 | ||||
| #define TEST_SIZE(tree, size) \ | ||||
|     TEST_CHECK(vieter_tree_size(tree) == size); \ | ||||
|  | @ -18,6 +18,7 @@ void test_insert() { | |||
|     for (uint64_t i = 0; i < 250; i++) { | ||||
|         TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_ok); | ||||
|         TEST_SIZE(tree, i + 1); | ||||
|         TEST_CHECK(vieter_tree_validate(tree) == 0); | ||||
|     } | ||||
| 
 | ||||
|     void *out; | ||||
|  | @ -36,13 +37,15 @@ void test_remove() { | |||
| 
 | ||||
|     for (uint64_t i = 0; i < 250; i++) { | ||||
|         TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_ok); | ||||
|         TEST_CHECK(vieter_tree_validate(tree) == 0); | ||||
|     } | ||||
| 
 | ||||
|     void *out; | ||||
| 
 | ||||
|     for (uint64_t i = 0; i < 250; i++) { | ||||
|     for (uint64_t i = 0; i < 25; i++) { | ||||
|         TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok); | ||||
|         TEST_CHECK(vieter_tree_remove(&out, tree, i) == vieter_tree_ok); | ||||
|         TEST_CHECK(vieter_tree_validate(tree) == 0); | ||||
|         TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_not_present); | ||||
|         TEST_SIZE(tree, 250 - i - 1); | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue