17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2017 Jason Ekstrand 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice shall be included in 127ec681f3Smrg * all copies or substantial portions of the Software. 137ec681f3Smrg * 147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177ec681f3Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 187ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 197ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 207ec681f3Smrg * DEALINGS IN THE SOFTWARE. 217ec681f3Smrg */ 227ec681f3Smrg 237ec681f3Smrg#undef NDEBUG 247ec681f3Smrg 257ec681f3Smrg#include "rb_tree.h" 267ec681f3Smrg 277ec681f3Smrg#include <assert.h> 287ec681f3Smrg#include <limits.h> 297ec681f3Smrg 307ec681f3Smrg/* A list of 100 random numbers from 1 to 100. The number 30 is explicitly 317ec681f3Smrg * missing from this list. 327ec681f3Smrg */ 337ec681f3Smrgint test_numbers[] = { 347ec681f3Smrg 26, 12, 35, 15, 48, 11, 39, 23, 40, 18, 357ec681f3Smrg 39, 15, 40, 11, 42, 2, 5, 2, 28, 8, 367ec681f3Smrg 10, 22, 23, 38, 47, 12, 31, 22, 26, 39, 377ec681f3Smrg 9, 42, 32, 18, 36, 8, 32, 29, 9, 3, 387ec681f3Smrg 32, 49, 23, 11, 43, 41, 22, 42, 6, 35, 397ec681f3Smrg 38, 48, 5, 35, 39, 44, 22, 16, 16, 32, 407ec681f3Smrg 31, 50, 48, 5, 50, 8, 2, 32, 27, 34, 417ec681f3Smrg 42, 48, 22, 47, 10, 48, 39, 36, 28, 40, 427ec681f3Smrg 32, 33, 21, 17, 14, 38, 27, 6, 25, 18, 437ec681f3Smrg 32, 38, 19, 22, 20, 47, 50, 41, 29, 50, 447ec681f3Smrg}; 457ec681f3Smrg 467ec681f3Smrg#define NON_EXISTANT_NUMBER 30 477ec681f3Smrg 487ec681f3Smrg#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) 497ec681f3Smrg 507ec681f3Smrgstruct rb_test_node { 517ec681f3Smrg int key; 527ec681f3Smrg struct rb_node node; 537ec681f3Smrg}; 547ec681f3Smrg 557ec681f3Smrgstatic int 567ec681f3Smrgrb_test_node_cmp_void(const struct rb_node *n, const void *v) 577ec681f3Smrg{ 587ec681f3Smrg struct rb_test_node *tn = rb_node_data(struct rb_test_node, n, node); 597ec681f3Smrg return *(int *)v - tn->key; 607ec681f3Smrg} 617ec681f3Smrg 627ec681f3Smrgstatic int 637ec681f3Smrgrb_test_node_cmp(const struct rb_node *a, const struct rb_node *b) 647ec681f3Smrg{ 657ec681f3Smrg struct rb_test_node *ta = rb_node_data(struct rb_test_node, a, node); 667ec681f3Smrg struct rb_test_node *tb = rb_node_data(struct rb_test_node, b, node); 677ec681f3Smrg 687ec681f3Smrg return tb->key - ta->key; 697ec681f3Smrg} 707ec681f3Smrg 717ec681f3Smrgstatic void 727ec681f3Smrgvalidate_tree_order(struct rb_tree *tree, unsigned expected_count) 737ec681f3Smrg{ 747ec681f3Smrg struct rb_test_node *prev = NULL; 757ec681f3Smrg int max_val = -1; 767ec681f3Smrg unsigned count = 0; 777ec681f3Smrg rb_tree_foreach(struct rb_test_node, n, tree, node) { 787ec681f3Smrg /* Everything should be in increasing order */ 797ec681f3Smrg assert(n->key >= max_val); 807ec681f3Smrg if (n->key > max_val) { 817ec681f3Smrg max_val = n->key; 827ec681f3Smrg } else { 837ec681f3Smrg /* Things should be stable, i.e., given equal keys, they should 847ec681f3Smrg * show up in the list in order of insertion. We insert them 857ec681f3Smrg * in the order they are in in the array. 867ec681f3Smrg */ 877ec681f3Smrg assert(prev == NULL || prev < n); 887ec681f3Smrg } 897ec681f3Smrg 907ec681f3Smrg prev = n; 917ec681f3Smrg count++; 927ec681f3Smrg } 937ec681f3Smrg assert(count == expected_count); 947ec681f3Smrg 957ec681f3Smrg prev = NULL; 967ec681f3Smrg max_val = -1; 977ec681f3Smrg count = 0; 987ec681f3Smrg rb_tree_foreach_safe(struct rb_test_node, n, tree, node) { 997ec681f3Smrg /* Everything should be in increasing order */ 1007ec681f3Smrg assert(n->key >= max_val); 1017ec681f3Smrg if (n->key > max_val) { 1027ec681f3Smrg max_val = n->key; 1037ec681f3Smrg } else { 1047ec681f3Smrg /* Things should be stable, i.e., given equal keys, they should 1057ec681f3Smrg * show up in the list in order of insertion. We insert them 1067ec681f3Smrg * in the order they are in in the array. 1077ec681f3Smrg */ 1087ec681f3Smrg assert(prev == NULL || prev < n); 1097ec681f3Smrg } 1107ec681f3Smrg 1117ec681f3Smrg prev = n; 1127ec681f3Smrg count++; 1137ec681f3Smrg } 1147ec681f3Smrg assert(count == expected_count); 1157ec681f3Smrg 1167ec681f3Smrg prev = NULL; 1177ec681f3Smrg int min_val = INT_MAX; 1187ec681f3Smrg count = 0; 1197ec681f3Smrg rb_tree_foreach_rev(struct rb_test_node, n, tree, node) { 1207ec681f3Smrg /* Everything should be in increasing order */ 1217ec681f3Smrg assert(n->key <= min_val); 1227ec681f3Smrg if (n->key < min_val) { 1237ec681f3Smrg min_val = n->key; 1247ec681f3Smrg } else { 1257ec681f3Smrg /* Things should be stable, i.e., given equal keys, they should 1267ec681f3Smrg * show up in the list in order of insertion. We insert them 1277ec681f3Smrg * in the order they are in in the array. 1287ec681f3Smrg */ 1297ec681f3Smrg assert(prev == NULL || prev > n); 1307ec681f3Smrg } 1317ec681f3Smrg 1327ec681f3Smrg prev = n; 1337ec681f3Smrg count++; 1347ec681f3Smrg } 1357ec681f3Smrg assert(count == expected_count); 1367ec681f3Smrg 1377ec681f3Smrg prev = NULL; 1387ec681f3Smrg min_val = INT_MAX; 1397ec681f3Smrg count = 0; 1407ec681f3Smrg rb_tree_foreach_rev_safe(struct rb_test_node, n, tree, node) { 1417ec681f3Smrg /* Everything should be in increasing order */ 1427ec681f3Smrg assert(n->key <= min_val); 1437ec681f3Smrg if (n->key < min_val) { 1447ec681f3Smrg min_val = n->key; 1457ec681f3Smrg } else { 1467ec681f3Smrg /* Things should be stable, i.e., given equal keys, they should 1477ec681f3Smrg * show up in the list in order of insertion. We insert them 1487ec681f3Smrg * in the order they are in in the array. 1497ec681f3Smrg */ 1507ec681f3Smrg assert(prev == NULL || prev > n); 1517ec681f3Smrg } 1527ec681f3Smrg 1537ec681f3Smrg prev = n; 1547ec681f3Smrg count++; 1557ec681f3Smrg } 1567ec681f3Smrg assert(count == expected_count); 1577ec681f3Smrg} 1587ec681f3Smrg 1597ec681f3Smrgstatic void 1607ec681f3Smrgvalidate_search(struct rb_tree *tree, int first_number, 1617ec681f3Smrg int last_number) 1627ec681f3Smrg{ 1637ec681f3Smrg struct rb_node *n; 1647ec681f3Smrg struct rb_test_node *tn; 1657ec681f3Smrg 1667ec681f3Smrg /* Search for all of the values */ 1677ec681f3Smrg for (int i = first_number; i <= last_number; i++) { 1687ec681f3Smrg n = rb_tree_search(tree, &test_numbers[i], rb_test_node_cmp_void); 1697ec681f3Smrg tn = rb_node_data(struct rb_test_node, n, node); 1707ec681f3Smrg assert(tn->key == test_numbers[i]); 1717ec681f3Smrg 1727ec681f3Smrg n = rb_tree_search_sloppy(tree, &test_numbers[i], 1737ec681f3Smrg rb_test_node_cmp_void); 1747ec681f3Smrg tn = rb_node_data(struct rb_test_node, n, node); 1757ec681f3Smrg assert(tn->key == test_numbers[i]); 1767ec681f3Smrg } 1777ec681f3Smrg 1787ec681f3Smrg int missing_key = NON_EXISTANT_NUMBER; 1797ec681f3Smrg n = rb_tree_search(tree, &missing_key, rb_test_node_cmp_void); 1807ec681f3Smrg assert(n == NULL); 1817ec681f3Smrg 1827ec681f3Smrg n = rb_tree_search_sloppy(tree, &missing_key, rb_test_node_cmp_void); 1837ec681f3Smrg if (rb_tree_is_empty(tree)) { 1847ec681f3Smrg assert(n == NULL); 1857ec681f3Smrg } else { 1867ec681f3Smrg assert(n != NULL); 1877ec681f3Smrg tn = rb_node_data(struct rb_test_node, n, node); 1887ec681f3Smrg assert(tn->key != missing_key); 1897ec681f3Smrg if (tn->key < missing_key) { 1907ec681f3Smrg struct rb_node *next = rb_node_next(n); 1917ec681f3Smrg if (next != NULL) { 1927ec681f3Smrg struct rb_test_node *tnext = 1937ec681f3Smrg rb_node_data(struct rb_test_node, next, node); 1947ec681f3Smrg assert(missing_key < tnext->key); 1957ec681f3Smrg } 1967ec681f3Smrg } else { 1977ec681f3Smrg struct rb_node *prev = rb_node_prev(n); 1987ec681f3Smrg if (prev != NULL) { 1997ec681f3Smrg struct rb_test_node *tprev = 2007ec681f3Smrg rb_node_data(struct rb_test_node, prev, node); 2017ec681f3Smrg assert(missing_key > tprev->key); 2027ec681f3Smrg } 2037ec681f3Smrg } 2047ec681f3Smrg } 2057ec681f3Smrg} 2067ec681f3Smrg 2077ec681f3Smrgint 2087ec681f3Smrgmain() 2097ec681f3Smrg{ 2107ec681f3Smrg struct rb_test_node nodes[ARRAY_SIZE(test_numbers)]; 2117ec681f3Smrg struct rb_tree tree; 2127ec681f3Smrg 2137ec681f3Smrg rb_tree_init(&tree); 2147ec681f3Smrg 2157ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_numbers); i++) { 2167ec681f3Smrg nodes[i].key = test_numbers[i]; 2177ec681f3Smrg rb_tree_insert(&tree, &nodes[i].node, rb_test_node_cmp); 2187ec681f3Smrg rb_tree_validate(&tree); 2197ec681f3Smrg validate_tree_order(&tree, i + 1); 2207ec681f3Smrg validate_search(&tree, 0, i); 2217ec681f3Smrg } 2227ec681f3Smrg 2237ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_numbers); i++) { 2247ec681f3Smrg rb_tree_remove(&tree, &nodes[i].node); 2257ec681f3Smrg rb_tree_validate(&tree); 2267ec681f3Smrg validate_tree_order(&tree, ARRAY_SIZE(test_numbers) - i - 1); 2277ec681f3Smrg validate_search(&tree, i + 1, ARRAY_SIZE(test_numbers) - 1); 2287ec681f3Smrg } 2297ec681f3Smrg} 230