Code

avltree: Added sdb_avltree_lookup().
authorSebastian Harl <sh@tokkee.org>
Wed, 9 Jul 2014 19:49:30 +0000 (21:49 +0200)
committerSebastian Harl <sh@tokkee.org>
Wed, 9 Jul 2014 19:49:30 +0000 (21:49 +0200)
src/include/utils/avltree.h
src/utils/avltree.c
t/unit/utils/avltree_test.c

index 548c69506d0215ae8d893ffc18ea7e7646486969..ca3bf0876e132029e861359e89a64a5690b203bd 100644 (file)
@@ -57,6 +57,9 @@ sdb_avltree_clear(sdb_avltree_t *tree);
 int
 sdb_avltree_insert(sdb_avltree_t *tree, sdb_object_t *obj);
 
+sdb_object_t *
+sdb_avltree_lookup(sdb_avltree_t *tree, const sdb_object_t *ref);
+
 sdb_avltree_iter_t *
 sdb_avltree_get_iter(sdb_avltree_t *tree);
 
index 353a3849c2c307c975413d72a9dba64dfc0f7258..56bc57d3087b69bccc42c20fde8cdfcd835f8162 100644 (file)
@@ -362,6 +362,31 @@ sdb_avltree_insert(sdb_avltree_t *tree, sdb_object_t *obj)
        return 0;
 } /* sdb_avltree_insert */
 
+sdb_object_t *
+sdb_avltree_lookup(sdb_avltree_t *tree, const sdb_object_t *ref)
+{
+       node_t *n;
+
+       if (! tree)
+               return NULL;
+
+       n = tree->root;
+       while (n) {
+               int diff = tree->cmp(n->obj, ref);
+
+               if (! diff) {
+                       sdb_object_ref(n->obj);
+                       return n->obj;
+               }
+
+               if (diff < 0)
+                       n = n->right;
+               else
+                       n = n->left;
+       }
+       return NULL;
+} /* sdb_avltree_lookup_by_name */
+
 sdb_avltree_iter_t *
 sdb_avltree_get_iter(sdb_avltree_t *tree)
 {
index 0488693d112d139afb935b333ab79941318cb739..3526e4107df078c5fa2f3aa99913f25659bccbf3 100644 (file)
@@ -66,6 +66,8 @@ static sdb_object_t test_data[] = {
        SDB_OBJECT_STATIC("a"),
 };
 
+static char *unused_names[] = { "x", "y", "z" };
+
 static void
 populate(void)
 {
@@ -153,6 +155,38 @@ START_TEST(test_insert)
 }
 END_TEST
 
+START_TEST(test_lookup)
+{
+       size_t i;
+
+       populate();
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(test_data); ++i) {
+               sdb_object_t ref = SDB_OBJECT_STATIC(test_data[i].name);
+               sdb_object_t *obj;
+
+               obj = sdb_avltree_lookup(tree, &ref);
+               fail_unless(obj != NULL,
+                               "sdb_avltree_lookup(<tree>, <%s>) = NULL; "
+                               "expected: <obj>", ref.name);
+               fail_unless(obj == &test_data[i],
+                               "sdb_avltree_lookup(<tree>, <%s>) = %p (%s); "
+                               "expected: %p, (%s)", ref.name, obj, obj->name,
+                               &test_data[i], test_data[i].name);
+       }
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(unused_names); ++i) {
+               sdb_object_t ref = SDB_OBJECT_STATIC(unused_names[i]);
+               sdb_object_t *obj;
+
+               obj = sdb_avltree_lookup(tree, &ref);
+               fail_unless(obj == NULL,
+                               "sdb_avltree_lookup(<tree>, <%s> = %p (%s); "
+                               "expected: NULL", ref.name, obj, obj ? obj->name : "<nil>");
+       }
+}
+END_TEST
+
 START_TEST(test_iter)
 {
        sdb_avltree_iter_t *iter;
@@ -213,6 +247,7 @@ util_avltree_suite(void)
        tcase_add_checked_fixture(tc, setup, teardown);
        tcase_add_test(tc, test_null);
        tcase_add_test(tc, test_insert);
+       tcase_add_test(tc, test_lookup);
        tcase_add_test(tc, test_iter);
        suite_add_tcase(s, tc);