Code

memstore: Let get_child() support arbitrary parent and child elements.
authorSebastian Harl <sh@tokkee.org>
Tue, 13 Oct 2015 19:13:05 +0000 (21:13 +0200)
committerSebastian Harl <sh@tokkee.org>
Tue, 13 Oct 2015 19:13:05 +0000 (21:13 +0200)
src/core/memstore.c
src/include/core/memstore.h
t/unit/core/store_test.c

index d886a1f..15c4202 100644 (file)
@@ -483,6 +483,18 @@ get_host_children(host_t *host, int type)
                return host->services;
 } /* get_host_children */
 
+static sdb_avltree_t *
+get_obj_attrs(sdb_memstore_obj_t *obj)
+{
+       if (obj->type == SDB_HOST)
+               return HOST(obj)->attributes;
+       else if (obj->type == SDB_SERVICE)
+               return SVC(obj)->attributes;
+       else if (obj->type == SDB_METRIC)
+               return METRIC(obj)->attributes;
+       return NULL;
+} /* get_obj_attrs */
+
 /*
  * store writer API
  */
@@ -522,10 +534,8 @@ store_attribute(sdb_store_attribute_t *attr, sdb_object_t *user_data)
                obj.parent_tree = get_host_children(host, SDB_ATTRIBUTE);
                break;
        case SDB_SERVICE:
-               children = get_host_children(host, SDB_SERVICE);
-               break;
        case SDB_METRIC:
-               children = get_host_children(host, SDB_METRIC);
+               children = get_host_children(host, attr->parent_type);
                break;
        default:
                status = -1;
@@ -804,14 +814,17 @@ sdb_memstore_get_host(sdb_memstore_t *store, const char *name)
 } /* sdb_memstore_get_host */
 
 sdb_memstore_obj_t *
-sdb_memstore_get_child(sdb_memstore_obj_t *host, int type, const char *name)
+sdb_memstore_get_child(sdb_memstore_obj_t *obj, int type, const char *name)
 {
-       sdb_avltree_t *children;
+       sdb_avltree_t *children = NULL;
 
-       if ((! host) || (host->type != SDB_HOST) || (! name))
+       if ((! obj) || (! name))
                return NULL;
 
-       children = get_host_children(HOST(host), type);
+       if (type & SDB_ATTRIBUTE)
+               children = get_obj_attrs(obj);
+       else if (obj->type == SDB_HOST)
+               children = get_host_children(HOST(obj), type);
        if (! children)
                return NULL;
        return STORE_OBJ(sdb_avltree_lookup(children, name));
@@ -876,23 +889,12 @@ int
 sdb_memstore_get_attr(sdb_memstore_obj_t *obj, const char *name, sdb_data_t *res,
                sdb_memstore_matcher_t *filter)
 {
-       sdb_avltree_t *tree = NULL;
        sdb_memstore_obj_t *attr;
 
        if ((! obj) || (! name))
                return -1;
 
-       if (obj->type == SDB_HOST)
-               tree = HOST(obj)->attributes;
-       else if (obj->type == SDB_SERVICE)
-               tree = SVC(obj)->attributes;
-       else if (obj->type == SDB_METRIC)
-               tree = METRIC(obj)->attributes;
-
-       if (! tree)
-               return -1;
-
-       attr = STORE_OBJ(sdb_avltree_lookup(tree, name));
+       attr = STORE_OBJ(sdb_avltree_lookup(get_obj_attrs(obj), name));
        if (! attr)
                return -1;
        if (filter && (! sdb_memstore_matcher_matches(filter, attr, NULL))) {
index 8590156..7c180fd 100644 (file)
@@ -148,7 +148,7 @@ sdb_memstore_get_host(sdb_memstore_t *store, const char *name);
 
 /*
  * sdb_memstore_get_child:
- * Retrieve a host's child object of the specified type and name. The
+ * Retrieve an object's child object of the specified type and name. The
  * reference count of the child object will be incremented before returning
  * it. The caller is responsible for releasing the object once it's no longer
  * used.
@@ -158,7 +158,7 @@ sdb_memstore_get_host(sdb_memstore_t *store, const char *name);
  *  - NULL else
  */
 sdb_memstore_obj_t *
-sdb_memstore_get_child(sdb_memstore_obj_t *host, int type, const char *name);
+sdb_memstore_get_child(sdb_memstore_obj_t *obj, int type, const char *name);
 
 /*
  * sdb_memstore_get_field:
index 9445c64..7ddd50b 100644 (file)
@@ -544,28 +544,34 @@ START_TEST(test_get_child)
 {
        struct {
                const char *host;
+               int parent_type;
+               const char *parent;
                const char *name;
                int type;
                int expected;
        } golden_data[] = {
-               { "h1", NULL, SDB_HOST,       0 },
-               { "h1", NULL, SDB_SERVICE,   -1 },
-               { "h1", NULL, SDB_METRIC,    -1 },
-               { "h1", NULL, SDB_ATTRIBUTE, -1 },
-               { "h2", NULL, SDB_HOST,       0 },
-               { "h2", NULL, SDB_SERVICE,   -1 },
-               { "h2", NULL, SDB_METRIC,    -1 },
-               { "h2", NULL, SDB_ATTRIBUTE, -1 },
-               { "h3", NULL, SDB_HOST,      -1 },
-               { "h1", "k1", SDB_ATTRIBUTE,  0 },
-               { "h1", "x1", SDB_ATTRIBUTE, -1 },
-               { "h2", "k1", SDB_ATTRIBUTE, -1 },
-               { "h1", "k1", SDB_SERVICE,   -1 },
-               { "h1", "k1", SDB_METRIC,    -1 },
-               { "h1", "s1", SDB_SERVICE,   -1 },
-               { "h2", "s1", SDB_SERVICE,    0 },
-               { "h1", "m2", SDB_METRIC,     0 },
-               { "h2", "m2", SDB_METRIC,    -1 },
+               { "h1",          -1, NULL, NULL, SDB_HOST,       0 },
+               { "h1",          -1, NULL, NULL, SDB_SERVICE,   -1 },
+               { "h1",          -1, NULL, NULL, SDB_METRIC,    -1 },
+               { "h1",          -1, NULL, NULL, SDB_ATTRIBUTE, -1 },
+               { "h2",          -1, NULL, NULL, SDB_HOST,       0 },
+               { "h2",          -1, NULL, NULL, SDB_SERVICE,   -1 },
+               { "h2",          -1, NULL, NULL, SDB_METRIC,    -1 },
+               { "h2",          -1, NULL, NULL, SDB_ATTRIBUTE, -1 },
+               { "h3",          -1, NULL, NULL, SDB_HOST,      -1 },
+               { "h1",          -1, NULL, "k1", SDB_ATTRIBUTE,  0 },
+               { "h1",          -1, NULL, "x1", SDB_ATTRIBUTE, -1 },
+               { "h2",          -1, NULL, "k1", SDB_ATTRIBUTE, -1 },
+               { "h1",          -1, NULL, "k1", SDB_SERVICE,   -1 },
+               { "h1",          -1, NULL, "k1", SDB_METRIC,    -1 },
+               { "h1",          -1, NULL, "s1", SDB_SERVICE,   -1 },
+               { "h2",          -1, NULL, "s1", SDB_SERVICE,    0 },
+               { "h1",          -1, NULL, "m2", SDB_METRIC,     0 },
+               { "h2",          -1, NULL, "m2", SDB_METRIC,    -1 },
+               { "h1",  SDB_METRIC, "m1", "k3", SDB_ATTRIBUTE,  0 },
+               { "h1",  SDB_METRIC, "m1", "x1", SDB_ATTRIBUTE, -1 },
+               { "h2", SDB_SERVICE, "s2", "k1", SDB_ATTRIBUTE,  0 },
+               { "h2", SDB_SERVICE, "s2", "x1", SDB_ATTRIBUTE, -1 },
        };
 
        size_t i;
@@ -577,6 +583,13 @@ START_TEST(test_get_child)
                const char *expected_name = golden_data[i].host;
 
                obj = sdb_memstore_get_host(store, golden_data[i].host);
+               if (golden_data[i].parent) {
+                       sdb_memstore_obj_t *o;
+                       o = sdb_memstore_get_child(obj,
+                                       golden_data[i].parent_type, golden_data[i].parent);
+                       sdb_object_deref(SDB_OBJ(obj));
+                       obj = o;
+               }
                if (golden_data[i].expected && (golden_data[i].type == SDB_HOST))
                        fail_unless(obj == NULL,
                                        "sdb_memstore_get_host(%s) = %p; expected: NULL",