summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fe955da)
raw | patch | inline | side by side (parent: fe955da)
author | Sebastian Harl <sh@tokkee.org> | |
Tue, 30 Sep 2014 14:40:52 +0000 (07:40 -0700) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Tue, 30 Sep 2014 17:29:41 +0000 (19:29 +0200) |
This takes into account any filters and, thus, might mean that filters have to
be evaluated multiple times: once for determining if there are any children
and then again while serializing the data. This is because filtering happens
during serialization at which point it's too late to skip a host.
be evaluated multiple times: once for determining if there are any children
and then again while serializing the data. This is because filtering happens
during serialization at which point it's too late to skip a host.
src/core/store.c | patch | blob | history | |
src/frontend/query.c | patch | blob | history | |
src/include/core/store.h | patch | blob | history | |
t/integration/simple_query.sh | patch | blob | history |
diff --git a/src/core/store.c b/src/core/store.c
index e14f27c0e4141482c4edea27f59eca97bc4abdcb..8cb30efaea88a250284cb569db2ae07b05d7fa12 100644 (file)
--- a/src/core/store.c
+++ b/src/core/store.c
if ((! h) || (h->type != SDB_HOST) || (! buf))
return -1;
+ /* This function ignores SKIP_EMPTY flags given that the current
+ * implementation sucks and it's nut currently used when calling this
+ * function directly. */
+
sdb_strbuf_append(buf, "{\"name\": \"%s\", ", SDB_OBJ(host)->name);
store_common_tojson(h, buf);
return 0;
} /* sdb_store_host_tojson */
+static _Bool
+has_children(sdb_avltree_t *tree, sdb_store_matcher_t *filter)
+{
+ sdb_avltree_iter_t *iter;
+
+ if (! filter)
+ return sdb_avltree_size(tree) > 0;
+
+ iter = sdb_avltree_get_iter(tree);
+ while (sdb_avltree_iter_has_next(iter)) {
+ sdb_store_obj_t *sobj = STORE_OBJ(sdb_avltree_iter_get_next(iter));
+ if (sdb_store_matcher_matches(filter, sobj, NULL)) {
+ sdb_avltree_iter_destroy(iter);
+ return 1;
+ }
+ }
+ sdb_avltree_iter_destroy(iter);
+ return 0;
+} /* has_children */
+
int
sdb_store_tojson(sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags)
{
if (filter && (! sdb_store_matcher_matches(filter, host, NULL)))
continue;
+ /*
+ * XXX: This approach sucks but it's the best we can do at the moment.
+ * In the future, all store lookups should be split into multiple
+ * steps instead: first, retrieve all relevant objects and apply all
+ * pre-processing operations and then format it for the wire.
+ */
+ if ((flags & SDB_SKIP_EMPTY_SERVICES)
+ && (! has_children(HOST(host)->services, filter)))
+ continue;
+ if ((flags & SDB_SKIP_EMPTY_METRICS)
+ && (! has_children(HOST(host)->metrics, filter)))
+ continue;
+
if (sdb_strbuf_len(buf) > len)
sdb_strbuf_append(buf, ",");
len = sdb_strbuf_len(buf);
diff --git a/src/frontend/query.c b/src/frontend/query.c
index 0ee734c4ee24428d98efa324b4a1237054fad62d..1751ba57e7a9a241b148cbc4f4dc391787cf0c44 100644 (file)
--- a/src/frontend/query.c
+++ b/src/frontend/query.c
if (type == SDB_HOST)
flags = SDB_SKIP_ALL;
else if (type == SDB_SERVICE)
- flags = SDB_SKIP_ALL & (~SDB_SKIP_SERVICES);
+ flags = (SDB_SKIP_ALL & (~SDB_SKIP_SERVICES))
+ | SDB_SKIP_EMPTY_SERVICES;
else if (type == SDB_METRIC)
- flags = SDB_SKIP_ALL & (~SDB_SKIP_METRICS);
+ flags = (SDB_SKIP_ALL & (~SDB_SKIP_METRICS))
+ | SDB_SKIP_EMPTY_METRICS;
else {
sdb_log(SDB_LOG_ERR, "frontend: Invalid object type %d "
"for LIST command", type);
index fa974bbd1f7f93656992423ad3891f3b66d6b645..d5a76941c06255085215a77215c2cd17b0b89f3c 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
/*
* Flags for serialization functions.
*
- * By default, the full object will be included in the serialized output. When
- * specifying any of the flags, the respective information will be left out.
+ * By default, the full host object will be included in the serialized output.
+ * When specifying any of the flags, the respective information will be left
+ * out. The SKIP_EMPTY flags may be used to skip host objects entirely.
*/
enum {
SDB_SKIP_ATTRIBUTES = 1 << 0,
SDB_SKIP_METRICS = 1 << 2,
SDB_SKIP_SERVICE_ATTRIBUTES = 1 << 3,
- SDB_SKIP_ALL = 0xffff,
+ SDB_SKIP_ALL = (1 << 8) - 1,
+
+ /* skip hosts if they do not reference any services/metrics */
+ SDB_SKIP_EMPTY_SERVICES = 1 << 8,
+ SDB_SKIP_EMPTY_METRICS = 1 << 9,
};
/*
index 900db90c01519c00c93095fd5eae902c0a906a93..b6394432d1111cd9e9aa58ee7f58a9329dcaee83 100755 (executable)
| grep -F '"host1.example.com"' \
| grep -F '"host2.example.com"' \
| grep -F '"localhost"' \
- | grep -F '"other.host.name"' \
| grep -F '"some.host.name"' \
| grep -F '"mock service"' \
| grep -F '"other service"' \