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