Code

Handle last_update/interval in the core rather than in memstore.
authorSebastian Harl <sh@tokkee.org>
Tue, 13 Oct 2015 19:24:17 +0000 (21:24 +0200)
committerSebastian Harl <sh@tokkee.org>
Tue, 13 Oct 2015 19:24:17 +0000 (21:24 +0200)
For this purpose, let the sdb_plugin_store_* functions fetch the latest
revision of the object to determine the last update interval and last
recorded interval. The memstore now expects both values to be passed in
whenever storing/updating an object.

src/core/memstore.c
src/core/plugin.c
src/include/core/memstore.h
t/unit/core/store_expr_test.c
t/unit/core/store_json_test.c
t/unit/core/store_lookup_test.c
t/unit/core/store_test.c

index 15c4202..2449827 100644 (file)
@@ -65,10 +65,11 @@ typedef struct {
        int type;
        const char *name;
        sdb_time_t last_update;
+       sdb_time_t interval;
        const char * const *backends;
        size_t backends_num;
 } store_obj_t;
-#define STORE_OBJ_INIT { NULL, NULL, 0, NULL, 0, NULL, 0 }
+#define STORE_OBJ_INIT { NULL, NULL, 0, NULL, 0, 0, NULL, 0 }
 
 static sdb_type_t host_type;
 static sdb_type_t service_type;
@@ -109,14 +110,7 @@ static int
 store_obj_init(sdb_object_t *obj, va_list ap)
 {
        sdb_memstore_obj_t *sobj = STORE_OBJ(obj);
-
        sobj->type = va_arg(ap, int);
-
-       sobj->last_update = va_arg(ap, sdb_time_t);
-       sobj->interval = 0;
-       sobj->backends = NULL;
-       sobj->backends_num = 0;
-       sobj->parent = NULL;
        return 0;
 } /* store_obj_init */
 
@@ -248,8 +242,7 @@ attr_init(sdb_object_t *obj, va_list ap)
        const sdb_data_t *value;
        int ret;
 
-       /* this will consume the first two arguments
-        * (type and last_update) of ap */
+       /* this will consume the first argument (type) of ap */
        ret = store_obj_init(obj, ap);
        if (ret)
                return ret;
@@ -347,37 +340,8 @@ store_obj(store_obj_t *obj, sdb_memstore_obj_t **updated_obj)
 
        assert(obj->parent_tree);
 
-       if (obj->last_update <= 0)
-               obj->last_update = sdb_gettime();
-
        old = STORE_OBJ(sdb_avltree_lookup(obj->parent_tree, obj->name));
        if (old) {
-               if (old->last_update > obj->last_update) {
-                       sdb_log(SDB_LOG_DEBUG, "memstore: Cannot update %s '%s' - "
-                                       "value too old (%"PRIsdbTIME" < %"PRIsdbTIME")",
-                                       SDB_STORE_TYPE_TO_NAME(obj->type), obj->name,
-                                       obj->last_update, old->last_update);
-                       /* don't report an error; the object may be updated by multiple
-                        * backends */
-                       status = 1;
-               }
-               else if (old->last_update == obj->last_update) {
-                       /* don't report an error and also don't even log this to avoid
-                        * excessive noise on high sampling frequencies */
-                       status = 1;
-               }
-               else {
-                       sdb_time_t interval = obj->last_update - old->last_update;
-                       old->last_update = obj->last_update;
-                       if (interval) {
-                               if (old->interval)
-                                       old->interval = (sdb_time_t)((0.9 * (double)old->interval)
-                                                       + (0.1 * (double)interval));
-                               else
-                                       old->interval = interval;
-                       }
-               }
-
                new = old;
                sdb_object_deref(SDB_OBJ(old));
        }
@@ -385,7 +349,7 @@ store_obj(store_obj_t *obj, sdb_memstore_obj_t **updated_obj)
                if (obj->type == SDB_ATTRIBUTE) {
                        /* the value will be updated by the caller */
                        new = STORE_OBJ(sdb_object_create(obj->name, attribute_type,
-                                               obj->type, obj->last_update, NULL));
+                                               obj->type, NULL));
                }
                else {
                        sdb_type_t t;
@@ -394,8 +358,7 @@ store_obj(store_obj_t *obj, sdb_memstore_obj_t **updated_obj)
                                : obj->type == SDB_SERVICE
                                        ? service_type
                                        : metric_type;
-                       new = STORE_OBJ(sdb_object_create(obj->name, t,
-                                               obj->type, obj->last_update));
+                       new = STORE_OBJ(sdb_object_create(obj->name, t, obj->type));
                }
 
                if (new) {
@@ -417,6 +380,9 @@ store_obj(store_obj_t *obj, sdb_memstore_obj_t **updated_obj)
                return status;
        assert(new);
 
+       new->last_update = obj->last_update;
+       new->interval = obj->interval;
+
        if (new->parent != obj->parent) {
                // Avoid circular self-references which are not handled
                // correctly by the ref-count based management layer.
@@ -560,6 +526,7 @@ store_attribute(sdb_store_attribute_t *attr, sdb_object_t *user_data)
        obj.type = SDB_ATTRIBUTE;
        obj.name = attr->key;
        obj.last_update = attr->last_update;
+       obj.interval = attr->interval;
        obj.backends = attr->backends;
        obj.backends_num = attr->backends_num;
        if (! status)
@@ -585,7 +552,7 @@ static int
 store_host(sdb_store_host_t *host, sdb_object_t *user_data)
 {
        sdb_memstore_t *st = SDB_MEMSTORE(user_data);
-       store_obj_t obj = { NULL, st->hosts, SDB_HOST, NULL, 0, NULL, 0 };
+       store_obj_t obj = { NULL, st->hosts, SDB_HOST, NULL, 0, 0, NULL, 0 };
        int status = 0;
 
        if ((! host) || (! host->name))
@@ -593,6 +560,7 @@ store_host(sdb_store_host_t *host, sdb_object_t *user_data)
 
        obj.name = host->name;
        obj.last_update = host->last_update;
+       obj.interval = host->interval;
        obj.backends = host->backends;
        obj.backends_num = host->backends_num;
        pthread_rwlock_wrlock(&st->host_lock);
@@ -627,6 +595,7 @@ store_service(sdb_store_service_t *service, sdb_object_t *user_data)
 
        obj.name = service->name;
        obj.last_update = service->last_update;
+       obj.interval = service->interval;
        obj.backends = service->backends;
        obj.backends_num = service->backends_num;
        if (! status)
@@ -666,6 +635,7 @@ store_metric(sdb_store_metric_t *metric, sdb_object_t *user_data)
 
        obj.name = metric->name;
        obj.last_update = metric->last_update;
+       obj.interval = metric->interval;
        obj.backends = metric->backends;
        obj.backends_num = metric->backends_num;
        if (! status)
@@ -725,30 +695,32 @@ sdb_memstore_create(void)
 } /* sdb_memstore_create */
 
 int
-sdb_memstore_host(sdb_memstore_t *store, const char *name, sdb_time_t last_update)
+sdb_memstore_host(sdb_memstore_t *store, const char *name,
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_host_t host = {
-               name, last_update, 0, NULL, 0,
+               name, last_update, interval, NULL, 0,
        };
        return store_host(&host, SDB_OBJ(store));
 } /* sdb_memstore_host */
 
 int
 sdb_memstore_service(sdb_memstore_t *store, const char *hostname, const char *name,
-               sdb_time_t last_update)
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_service_t service = {
-               hostname, name, last_update, 0, NULL, 0,
+               hostname, name, last_update, interval, NULL, 0,
        };
        return store_service(&service, SDB_OBJ(store));
 } /* sdb_memstore_service */
 
 int
 sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *name,
-               sdb_metric_store_t *metric_store, sdb_time_t last_update)
+               sdb_metric_store_t *metric_store,
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_metric_t metric = {
-               hostname, name, { NULL, NULL }, last_update, 0, NULL, 0,
+               hostname, name, { NULL, NULL }, last_update, interval, NULL, 0,
        };
        if (metric_store) {
                metric.store.type = metric_store->type;
@@ -759,10 +731,12 @@ sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *nam
 
 int
 sdb_memstore_attribute(sdb_memstore_t *store, const char *hostname,
-               const char *key, const sdb_data_t *value, sdb_time_t last_update)
+               const char *key, const sdb_data_t *value,
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_attribute_t attr = {
-               NULL, SDB_HOST, hostname, key, SDB_DATA_INIT, last_update, 0, NULL, 0,
+               NULL, SDB_HOST, hostname, key, SDB_DATA_INIT,
+               last_update, interval, NULL, 0,
        };
        if (value) {
                attr.value = *value;
@@ -773,10 +747,11 @@ sdb_memstore_attribute(sdb_memstore_t *store, const char *hostname,
 int
 sdb_memstore_service_attr(sdb_memstore_t *store, const char *hostname,
                const char *service, const char *key, const sdb_data_t *value,
-               sdb_time_t last_update)
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_attribute_t attr = {
-               hostname, SDB_SERVICE, service, key, SDB_DATA_INIT, last_update, 0, NULL, 0,
+               hostname, SDB_SERVICE, service, key, SDB_DATA_INIT,
+               last_update, interval, NULL, 0,
        };
        if (value) {
                attr.value = *value;
@@ -787,10 +762,11 @@ sdb_memstore_service_attr(sdb_memstore_t *store, const char *hostname,
 int
 sdb_memstore_metric_attr(sdb_memstore_t *store, const char *hostname,
                const char *metric, const char *key, const sdb_data_t *value,
-               sdb_time_t last_update)
+               sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_attribute_t attr = {
-               hostname, SDB_METRIC, metric, key, SDB_DATA_INIT, last_update, 0, NULL, 0,
+               hostname, SDB_METRIC, metric, key, SDB_DATA_INIT,
+               last_update, interval, NULL, 0,
        };
        if (value) {
                attr.value = *value;
index 728e20c..76b0b1e 100644 (file)
@@ -661,6 +661,111 @@ plugin_add_callback(sdb_llist_t **list, const char *type,
        return 0;
 } /* plugin_add_callback */
 
+/*
+ * object meta-data
+ */
+
+typedef struct {
+       int obj_type;
+       sdb_time_t last_update;
+       sdb_time_t interval;
+} interval_fetcher_t;
+
+static int
+interval_fetcher_host(sdb_store_host_t *host, sdb_object_t *user_data)
+{
+       interval_fetcher_t *lu = SDB_OBJ_WRAPPER(user_data)->data;
+       lu->obj_type = SDB_HOST;
+       lu->last_update = host->last_update;
+       return 0;
+} /* interval_fetcher_host */
+
+static int
+interval_fetcher_service(sdb_store_service_t *svc, sdb_object_t *user_data)
+{
+       interval_fetcher_t *lu = SDB_OBJ_WRAPPER(user_data)->data;
+       lu->obj_type = SDB_SERVICE;
+       lu->last_update = svc->last_update;
+       return 0;
+} /* interval_fetcher_service */
+
+static int
+interval_fetcher_metric(sdb_store_metric_t *metric, sdb_object_t *user_data)
+{
+       interval_fetcher_t *lu = SDB_OBJ_WRAPPER(user_data)->data;
+       lu->obj_type = SDB_METRIC;
+       lu->last_update = metric->last_update;
+       return 0;
+} /* interval_fetcher_metric */
+
+static int
+interval_fetcher_attr(sdb_store_attribute_t *attr, sdb_object_t *user_data)
+{
+       interval_fetcher_t *lu = SDB_OBJ_WRAPPER(user_data)->data;
+       lu->obj_type = SDB_ATTRIBUTE;
+       lu->last_update = attr->last_update;
+       return 0;
+} /* interval_fetcher_attr */
+
+static sdb_store_writer_t interval_fetcher = {
+       interval_fetcher_host, interval_fetcher_service,
+       interval_fetcher_metric, interval_fetcher_attr,
+};
+
+static int
+get_interval(int obj_type, const char *hostname,
+               int parent_type, const char *parent, const char *name,
+               sdb_time_t last_update, sdb_time_t *interval_out)
+{
+       sdb_ast_fetch_t fetch = SDB_AST_FETCH_INIT;
+       char hn[hostname ? strlen(hostname) + 1 : 1];
+       char pn[parent ? strlen(parent) + 1 : 1];
+       char n[strlen(name) + 1];
+       int status;
+
+       interval_fetcher_t lu = { 0, 0, 0 };
+       sdb_object_wrapper_t obj = SDB_OBJECT_WRAPPER_STATIC(&lu);
+       sdb_time_t interval;
+
+       assert(name);
+
+       if (hostname)
+               strncpy(hn, hostname, sizeof(hn));
+       if (parent)
+               strncpy(pn, parent, sizeof(pn));
+       strncpy(n, name, sizeof(n));
+
+       fetch.obj_type = obj_type;
+       fetch.hostname = hostname ? hn : NULL;
+       fetch.parent_type = parent_type;
+       fetch.parent = parent ? pn : NULL;
+       fetch.name = n;
+
+       status = sdb_plugin_query(SDB_AST_NODE(&fetch),
+                       &interval_fetcher, SDB_OBJ(&obj), NULL);
+       if ((status < 0) || (lu.obj_type != obj_type) || (lu.last_update == 0)) {
+               *interval_out = 0;
+               return 0;
+       }
+
+       if (lu.last_update >= last_update) {
+               if (lu.last_update > last_update)
+                       sdb_log(SDB_LOG_DEBUG, "memstore: Cannot update %s '%s' - "
+                                       "value too old (%"PRIsdbTIME" < %"PRIsdbTIME")",
+                                       SDB_STORE_TYPE_TO_NAME(obj_type), name,
+                                       lu.last_update, last_update);
+               *interval_out = lu.interval;
+               return 1;
+       }
+
+       interval = last_update - lu.last_update;
+       if (lu.interval && interval)
+               interval = (sdb_time_t)((0.9 * (double)lu.interval)
+                               + (0.1 * (double)interval));
+       *interval_out = interval;
+       return 0;
+} /* get_interval */
+
 static void
 get_backend(char **backends, size_t *backends_num)
 {
@@ -1508,7 +1613,12 @@ sdb_plugin_store_host(const char *name, sdb_time_t last_update)
        }
 
        host.name = cname;
-       host.last_update = last_update;
+       host.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_HOST, NULL, -1, NULL, cname,
+                               host.last_update, &host.interval)) {
+               free(cname);
+               return 1;
+       }
        host.backends = (const char * const *)backends;
        get_backend(backends, &host.backends_num);
 
@@ -1556,7 +1666,12 @@ sdb_plugin_store_service(const char *hostname, const char *name,
 
        service.hostname = cname;
        service.name = name;
-       service.last_update = last_update;
+       service.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_SERVICE, cname, -1, NULL, name,
+                               service.last_update, &service.interval)) {
+               free(cname);
+               return 1;
+       }
        service.backends = (const char * const *)backends;
        get_backend(backends, &service.backends_num);
 
@@ -1576,7 +1691,7 @@ sdb_plugin_store_service(const char *hostname, const char *name,
                d.type = SDB_TYPE_STRING;
                d.data.string = cname;
                if (sdb_plugin_store_service_attribute(cname, name,
-                                       "hostname", &d, last_update))
+                                       "hostname", &d, service.last_update))
                        status = -1;
        }
 
@@ -1621,7 +1736,12 @@ sdb_plugin_store_metric(const char *hostname, const char *name,
                metric.store.type = store->type;
                metric.store.id = store->id;
        }
-       metric.last_update = last_update;
+       metric.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_METRIC, cname, -1, NULL, name,
+                               metric.last_update, &metric.interval)) {
+               free(cname);
+               return 1;
+       }
        metric.backends = (const char * const *)backends;
        get_backend(backends, &metric.backends_num);
 
@@ -1641,7 +1761,7 @@ sdb_plugin_store_metric(const char *hostname, const char *name,
                d.type = SDB_TYPE_STRING;
                d.data.string = cname;
                if (sdb_plugin_store_metric_attribute(cname, name,
-                                       "hostname", &d, last_update))
+                                       "hostname", &d, metric.last_update))
                        status = -1;
        }
 
@@ -1679,7 +1799,12 @@ sdb_plugin_store_attribute(const char *hostname, const char *key,
        attr.parent = cname;
        attr.key = key;
        attr.value = *value;
-       attr.last_update = last_update;
+       attr.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_ATTRIBUTE, cname, -1, NULL, key,
+                               attr.last_update, &attr.interval)) {
+               free(cname);
+               return 1;
+       }
        attr.backends = (const char * const *)backends;
        get_backend(backends, &attr.backends_num);
 
@@ -1728,7 +1853,12 @@ sdb_plugin_store_service_attribute(const char *hostname, const char *service,
        attr.parent = service;
        attr.key = key;
        attr.value = *value;
-       attr.last_update = last_update;
+       attr.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_ATTRIBUTE, cname, SDB_SERVICE, service, key,
+                               attr.last_update, &attr.interval)) {
+               free(cname);
+               return 1;
+       }
        attr.backends = (const char * const *)backends;
        get_backend(backends, &attr.backends_num);
 
@@ -1777,7 +1907,12 @@ sdb_plugin_store_metric_attribute(const char *hostname, const char *metric,
        attr.parent = metric;
        attr.key = key;
        attr.value = *value;
-       attr.last_update = last_update;
+       attr.last_update = last_update ? last_update : sdb_gettime();
+       if (get_interval(SDB_ATTRIBUTE, cname, SDB_METRIC, metric, key,
+                               attr.last_update, &attr.interval)) {
+               free(cname);
+               return 1;
+       }
        attr.backends = (const char * const *)backends;
        get_backend(backends, &attr.backends_num);
 
index 7c180fd..8c1739e 100644 (file)
@@ -117,24 +117,27 @@ sdb_memstore_create(void);
  * canonical.
  */
 int
-sdb_memstore_host(sdb_memstore_t *store, const char *name, sdb_time_t last_update);
+sdb_memstore_host(sdb_memstore_t *store, const char *name,
+               sdb_time_t last_update, sdb_time_t interval);
 int
 sdb_memstore_service(sdb_memstore_t *store, const char *hostname, const char *name,
-               sdb_time_t last_update);
+               sdb_time_t last_update, sdb_time_t interval);
 int
 sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *name,
-               sdb_metric_store_t *metric_store, sdb_time_t last_update);
+               sdb_metric_store_t *metric_store,
+               sdb_time_t last_update, sdb_time_t interval);
 int
 sdb_memstore_attribute(sdb_memstore_t *store, const char *hostname,
-               const char *key, const sdb_data_t *value, sdb_time_t last_update);
+               const char *key, const sdb_data_t *value,
+               sdb_time_t last_update, sdb_time_t interval);
 int
 sdb_memstore_service_attr(sdb_memstore_t *store, const char *hostname,
                const char *service, const char *key, const sdb_data_t *value,
-               sdb_time_t last_update);
+               sdb_time_t last_update, sdb_time_t interval);
 int
 sdb_memstore_metric_attr(sdb_memstore_t *store, const char *hostname,
                const char *metric, const char *key, const sdb_data_t *value,
-               sdb_time_t last_update);
+               sdb_time_t last_update, sdb_time_t interval);
 
 /*
  * sdb_memstore_get_host:
index 1bf560e..c73ab34 100644 (file)
@@ -98,39 +98,39 @@ populate(void)
        ck_assert(store != NULL);
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(hosts); ++i) {
-               int status = sdb_memstore_host(store, hosts[i], 1);
+               int status = sdb_memstore_host(store, hosts[i], 1, 0);
                ck_assert(status == 0);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(metrics); ++i) {
                int status = sdb_memstore_metric(store, metrics[i].host,
-                               metrics[i].metric, /* store */ NULL, 1);
+                               metrics[i].metric, /* store */ NULL, 1, 0);
                ck_assert(status == 0);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(services); ++i) {
                int status = sdb_memstore_service(store, services[i].host,
-                               services[i].service, 1);
+                               services[i].service, 1, 0);
                ck_assert(status == 0);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(attrs); ++i) {
                int status = sdb_memstore_attribute(store, attrs[i].host,
-                               attrs[i].name, &attrs[i].value, 1);
+                               attrs[i].name, &attrs[i].value, 1, 0);
                ck_assert(status == 0);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(svc_attrs); ++i) {
                int status = sdb_memstore_service_attr(store, svc_attrs[i].host,
                                svc_attrs[i].service, svc_attrs[i].name,
-                               &svc_attrs[i].value, 1);
+                               &svc_attrs[i].value, 1, 0);
                ck_assert(status == 0);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(metric_attrs); ++i) {
                int status = sdb_memstore_metric_attr(store, metric_attrs[i].host,
                                metric_attrs[i].metric, metric_attrs[i].name,
-                               &metric_attrs[i].value, 1);
+                               &metric_attrs[i].value, 1, 0);
                ck_assert(status == 0);
        }
 } /* populate */
index 461c583..a0447b6 100644 (file)
@@ -50,45 +50,43 @@ populate(void)
        store = sdb_memstore_create();
        ck_assert(store != NULL);
 
-       sdb_memstore_host(store, "h1", 1 * SDB_INTERVAL_SECOND);
-       sdb_memstore_host(store, "h2", 3 * SDB_INTERVAL_SECOND);
+       sdb_memstore_host(store, "h1", 1 * SDB_INTERVAL_SECOND, 0);
+       sdb_memstore_host(store, "h2", 3 * SDB_INTERVAL_SECOND, 0);
 
        datum.type = SDB_TYPE_STRING;
        datum.data.string = "v1";
-       sdb_memstore_attribute(store, "h1", "k1", &datum, 1 * SDB_INTERVAL_SECOND);
+       sdb_memstore_attribute(store, "h1", "k1", &datum, 1 * SDB_INTERVAL_SECOND, 0);
        datum.data.string = "v2";
-       sdb_memstore_attribute(store, "h1", "k2", &datum, 2 * SDB_INTERVAL_SECOND);
+       sdb_memstore_attribute(store, "h1", "k2", &datum, 2 * SDB_INTERVAL_SECOND, 0);
        datum.data.string = "v3";
-       sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND);
+       sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND, 0);
 
+/* TODO: move these tests into generic store tests */
+#if 0
        /* make sure that older updates don't overwrite existing values */
        datum.data.string = "fail";
-       sdb_memstore_attribute(store, "h1", "k2", &datum, 1 * SDB_INTERVAL_SECOND);
-       sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND);
+       sdb_memstore_attribute(store, "h1", "k2", &datum, 1 * SDB_INTERVAL_SECOND, 0);
+       sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND, 0);
+#endif
 
-       sdb_memstore_metric(store, "h1", "m1", /* store */ NULL, 2 * SDB_INTERVAL_SECOND);
-       sdb_memstore_metric(store, "h1", "m2", /* store */ NULL, 1 * SDB_INTERVAL_SECOND);
-       sdb_memstore_metric(store, "h2", "m1", /* store */ NULL, 1 * SDB_INTERVAL_SECOND);
+       sdb_memstore_metric(store, "h1", "m1", /* store */ NULL, 2 * SDB_INTERVAL_SECOND, 0);
+       sdb_memstore_metric(store, "h1", "m2", /* store */ NULL, 1 * SDB_INTERVAL_SECOND, 0);
+       sdb_memstore_metric(store, "h2", "m1", /* store */ NULL, 1 * SDB_INTERVAL_SECOND, 0);
 
-       sdb_memstore_service(store, "h2", "s1", 1 * SDB_INTERVAL_SECOND);
-       sdb_memstore_service(store, "h2", "s2", 2 * SDB_INTERVAL_SECOND);
+       sdb_memstore_service(store, "h2", "s1", 1 * SDB_INTERVAL_SECOND, 0);
+       sdb_memstore_service(store, "h2", "s2", 2 * SDB_INTERVAL_SECOND, 0);
 
        datum.type = SDB_TYPE_INTEGER;
        datum.data.integer = 42;
        sdb_memstore_metric_attr(store, "h1", "m1", "k3",
-                       &datum, 2 * SDB_INTERVAL_SECOND);
+                       &datum, 2 * SDB_INTERVAL_SECOND, 0);
 
        datum.data.integer = 123;
        sdb_memstore_service_attr(store, "h2", "s2", "k1",
-                       &datum, 2 * SDB_INTERVAL_SECOND);
+                       &datum, 2 * SDB_INTERVAL_SECOND, 0);
        datum.data.integer = 4711;
        sdb_memstore_service_attr(store, "h2", "s2", "k2",
-                       &datum, 1 * SDB_INTERVAL_SECOND);
-
-       /* don't overwrite k1 */
-       datum.data.integer = 666;
-       sdb_memstore_service_attr(store, "h2", "s2", "k1",
-                       &datum, 2 * SDB_INTERVAL_SECOND);
+                       &datum, 1 * SDB_INTERVAL_SECOND, 0);
 } /* populate */
 
 static void
index 0c99ee1..0c30160 100644 (file)
@@ -80,33 +80,33 @@ populate(void)
        ck_assert(store != NULL);
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(hosts); ++i) {
-               int status = sdb_memstore_host(store, hosts[i], 1);
+               int status = sdb_memstore_host(store, hosts[i], 1, 0);
                fail_unless(status == 0,
-                               "sdb_memstore_host(%s, 1) = %d; expected: 0",
+                               "sdb_memstore_host(%s, 1, 0) = %d; expected: 0",
                                hosts[i], status);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(metrics); ++i) {
                int status = sdb_memstore_metric(store, metrics[i].host,
-                               metrics[i].metric, /* store */ NULL, 1);
+                               metrics[i].metric, /* store */ NULL, 1, 0);
                fail_unless(status == 0,
-                               "sdb_memstore_metric(%s, %s, NULL, 1) = %d; expected: 0",
+                               "sdb_memstore_metric(%s, %s, NULL, 1, 0) = %d; expected: 0",
                                metrics[i].host, metrics[i].metric, status);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(services); ++i) {
                int status = sdb_memstore_service(store, services[i].host,
-                               services[i].service, 1);
+                               services[i].service, 1, 0);
                fail_unless(status == 0,
-                               "sdb_memstore_service(%s, %s, 1) = %d; expected: 0",
+                               "sdb_memstore_service(%s, %s, 1, 0) = %d; expected: 0",
                                services[i].host, services[i].service, status);
        }
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(attrs); ++i) {
                int status = sdb_memstore_attribute(store, attrs[i].host,
-                               attrs[i].name, &attrs[i].value, 1);
+                               attrs[i].name, &attrs[i].value, 1, 0);
                fail_unless(status == 0,
-                               "sdb_memstore_attribute(%s, %s, <val>, 1) = %d; expected: 0",
+                               "sdb_memstore_attribute(%s, %s, <val>, 1, 0) = %d; expected: 0",
                                attrs[i].host, attrs[i].name, status);
        }
 } /* populate */
index 7ddd50b..50d041e 100644 (file)
@@ -52,41 +52,41 @@ populate(void)
 {
        sdb_data_t datum;
 
-       sdb_memstore_host(store, "h1", 1);
-       sdb_memstore_host(store, "h2", 3);
+       sdb_memstore_host(store, "h1", 1, 0);
+       sdb_memstore_host(store, "h2", 3, 0);
 
        datum.type = SDB_TYPE_STRING;
        datum.data.string = "v1";
-       sdb_memstore_attribute(store, "h1", "k1", &datum, 1);
+       sdb_memstore_attribute(store, "h1", "k1", &datum, 1, 0);
        datum.data.string = "v2";
-       sdb_memstore_attribute(store, "h1", "k2", &datum, 2);
+       sdb_memstore_attribute(store, "h1", "k2", &datum, 2, 0);
        datum.data.string = "v3";
-       sdb_memstore_attribute(store, "h1", "k3", &datum, 2);
+       sdb_memstore_attribute(store, "h1", "k3", &datum, 2, 0);
 
        /* make sure that older updates don't overwrite existing values */
        datum.data.string = "fail";
-       sdb_memstore_attribute(store, "h1", "k2", &datum, 1);
-       sdb_memstore_attribute(store, "h1", "k3", &datum, 2);
+       sdb_memstore_attribute(store, "h1", "k2", &datum, 1, 0);
+       sdb_memstore_attribute(store, "h1", "k3", &datum, 2, 0);
 
-       sdb_memstore_metric(store, "h1", "m1", /* store */ NULL, 2);
-       sdb_memstore_metric(store, "h1", "m2", /* store */ NULL, 1);
-       sdb_memstore_metric(store, "h2", "m1", /* store */ NULL, 1);
+       sdb_memstore_metric(store, "h1", "m1", /* store */ NULL, 2, 0);
+       sdb_memstore_metric(store, "h1", "m2", /* store */ NULL, 1, 0);
+       sdb_memstore_metric(store, "h2", "m1", /* store */ NULL, 1, 0);
 
-       sdb_memstore_service(store, "h2", "s1", 1);
-       sdb_memstore_service(store, "h2", "s2", 2);
+       sdb_memstore_service(store, "h2", "s1", 1, 0);
+       sdb_memstore_service(store, "h2", "s2", 2, 0);
 
        datum.type = SDB_TYPE_INTEGER;
        datum.data.integer = 42;
-       sdb_memstore_metric_attr(store, "h1", "m1", "k3", &datum, 2);
+       sdb_memstore_metric_attr(store, "h1", "m1", "k3", &datum, 2, 0);
 
        datum.data.integer = 123;
-       sdb_memstore_service_attr(store, "h2", "s2", "k1", &datum, 2);
+       sdb_memstore_service_attr(store, "h2", "s2", "k1", &datum, 2, 0);
        datum.data.integer = 4711;
-       sdb_memstore_service_attr(store, "h2", "s2", "k2", &datum, 1);
+       sdb_memstore_service_attr(store, "h2", "s2", "k2", &datum, 1, 0);
 
        /* don't overwrite k1 */
        datum.data.integer = 666;
-       sdb_memstore_service_attr(store, "h2", "s2", "k1", &datum, 2);
+       sdb_memstore_service_attr(store, "h2", "s2", "k1", &datum, 2, 0);
 } /* populate */
 
 static void
@@ -105,21 +105,17 @@ START_TEST(test_store_host)
        } golden_data[] = {
                { "a", 1, 0 },
                { "a", 2, 0 },
-               { "a", 1, 1 },
                { "b", 1, 0 },
-               { "b", 1, 1 },
-               { "A", 1, 1 }, /* case-insensitive */
-               { "A", 3, 0 },
        };
 
        struct {
                const char *name;
                bool        have;
        } golden_hosts[] = {
-               { "a", 1 == 1 },
-               { "b", 1 == 1 },
-               { "c", 0 == 1 },
-               { "A", 1 == 1 },
+               { "a", 1 },
+               { "b", 1 },
+               { "c", 0 },
+               { "A", 1 },
        };
 
        size_t i;
@@ -128,9 +124,9 @@ START_TEST(test_store_host)
                int status;
 
                status = sdb_memstore_host(store, golden_data[i].name,
-                               golden_data[i].last_update);
+                               golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_memstore_host(%s, %d) = %d; expected: %d",
+                               "sdb_memstore_host(%s, %d, 0) = %d; expected: %d",
                                golden_data[i].name, (int)golden_data[i].last_update,
                                status, golden_data[i].expected);
        }
@@ -155,7 +151,7 @@ START_TEST(test_store_get_host)
        size_t i;
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_hosts); ++i) {
-               int status = sdb_memstore_host(store, golden_hosts[i], 1);
+               int status = sdb_memstore_host(store, golden_hosts[i], 1, 0);
                fail_unless(status >= 0,
                                "sdb_memstore_host(%s) = %d; expected: >=0",
                                golden_hosts[i], status);
@@ -214,16 +210,14 @@ START_TEST(test_store_attr)
                { "k", "k",  "v",  1, -1 }, /* retry to ensure the host is not created */
                { "l", "k1", "v1", 1,  0 },
                { "l", "k1", "v2", 2,  0 },
-               { "l", "k1", "v3", 2,  1 },
                { "l", "k2", "v1", 1,  0 },
                { "m", "k",  "v1", 1,  0 },
-               { "m", "k",  "v2", 1,  1 },
        };
 
        size_t i;
 
-       sdb_memstore_host(store, "l", 1);
-       sdb_memstore_host(store, "m", 1);
+       sdb_memstore_host(store, "l", 1, 0);
+       sdb_memstore_host(store, "m", 1, 0);
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                sdb_data_t datum;
                int status;
@@ -234,11 +228,11 @@ START_TEST(test_store_attr)
 
                status = sdb_memstore_attribute(store, golden_data[i].host,
                                golden_data[i].key, &datum,
-                               golden_data[i].last_update);
+                               golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
                                "sdb_memstore_attribute(%s, %s, %s, %d) = %d; expected: %d",
                                golden_data[i].host, golden_data[i].key, golden_data[i].value,
-                               golden_data[i].last_update, status, golden_data[i].expected);
+                               golden_data[i].last_update, status, golden_data[i].expected, 0);
        }
 }
 END_TEST
@@ -261,13 +255,11 @@ START_TEST(test_store_metric)
                { "l", "m1", NULL,    1,  0 },
                { "l", "m1", &store1, 2,  0 },
                { "l", "m1", &store1, 3,  0 },
-               { "l", "m1", NULL,    3,  1 },
                { "l", "m2", &store1, 1,  0 },
                { "l", "m2", &store2, 2,  0 },
                { "l", "m2", NULL,    3,  0 },
                { "m", "m",  &store1, 1,  0 },
                { "m", "m",  NULL,    2,  0 },
-               { "m", "m",  NULL,    2,  1 },
                { "m", "m",  &store1, 3,  0 },
                { "m", "m",  &store2, 4,  0 },
                { "m", "m",  NULL,    5,  0 },
@@ -275,16 +267,16 @@ START_TEST(test_store_metric)
 
        size_t i;
 
-       sdb_memstore_host(store, "m", 1);
-       sdb_memstore_host(store, "l", 1);
+       sdb_memstore_host(store, "m", 1, 0);
+       sdb_memstore_host(store, "l", 1, 0);
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                int status;
 
                status = sdb_memstore_metric(store, golden_data[i].host,
                                golden_data[i].metric, golden_data[i].store,
-                               golden_data[i].last_update);
+                               golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_memstore_metric(%s, %s, %p, %d) = %d; expected: %d",
+                               "sdb_memstore_metric(%s, %s, %p, %d, 0) = %d; expected: %d",
                                golden_data[i].host, golden_data[i].metric,
                                golden_data[i].store, golden_data[i].last_update,
                                status, golden_data[i].expected);
@@ -309,30 +301,28 @@ START_TEST(test_store_metric_attr)
                /* retry, it should still fail */
                { "l", "mX", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1, -1 },
                { "l", "m1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
-               { "l", "m1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  1 },
                { "l", "m1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 2,  0 },
                { "l", "m1", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
-               { "l", "m1", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  1 },
                { "l", "m2", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
                { "m", "m1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
        };
 
        size_t i;
 
-       sdb_memstore_host(store, "m", 1);
-       sdb_memstore_host(store, "l", 1);
-       sdb_memstore_metric(store, "m", "m1", NULL, 1);
-       sdb_memstore_metric(store, "l", "m1", NULL, 1);
-       sdb_memstore_metric(store, "l", "m2", NULL, 1);
+       sdb_memstore_host(store, "m", 1, 0);
+       sdb_memstore_host(store, "l", 1, 0);
+       sdb_memstore_metric(store, "m", "m1", NULL, 1, 0);
+       sdb_memstore_metric(store, "l", "m1", NULL, 1, 0);
+       sdb_memstore_metric(store, "l", "m2", NULL, 1, 0);
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                int status;
 
                status = sdb_memstore_metric_attr(store, golden_data[i].host,
                                golden_data[i].metric, golden_data[i].attr,
-                               &golden_data[i].value, golden_data[i].last_update);
+                               &golden_data[i].value, golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_memstore_metric_attr(%s, %s, %s, %d, %d) = %d; "
+                               "sdb_memstore_metric_attr(%s, %s, %s, %d, %d, 0) = %d; "
                                "expected: %d", golden_data[i].host, golden_data[i].metric,
                                golden_data[i].attr, golden_data[i].value.data.integer,
                                golden_data[i].last_update, status, golden_data[i].expected);
@@ -352,23 +342,21 @@ START_TEST(test_store_service)
                { "k", "s",  1, -1 }, /* retry to ensure the host is not created */
                { "l", "s1", 1,  0 },
                { "l", "s1", 2,  0 },
-               { "l", "s1", 2,  1 },
                { "l", "s2", 1,  0 },
                { "m", "s",  1,  0 },
-               { "m", "s",  1,  1 },
        };
 
        size_t i;
 
-       sdb_memstore_host(store, "m", 1);
-       sdb_memstore_host(store, "l", 1);
+       sdb_memstore_host(store, "m", 1, 0);
+       sdb_memstore_host(store, "l", 1, 0);
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                int status;
 
                status = sdb_memstore_service(store, golden_data[i].host,
-                               golden_data[i].svc, golden_data[i].last_update);
+                               golden_data[i].svc, golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_memstore_service(%s, %s, %d) = %d; expected: %d",
+                               "sdb_memstore_service(%s, %s, %d, 0) = %d; expected: %d",
                                golden_data[i].host, golden_data[i].svc,
                                golden_data[i].last_update, status, golden_data[i].expected);
        }
@@ -392,30 +380,28 @@ START_TEST(test_store_service_attr)
                /* retry, it should still fail */
                { "l", "sX", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1, -1 },
                { "l", "s1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
-               { "l", "s1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  1 },
                { "l", "s1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 2,  0 },
                { "l", "s1", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
-               { "l", "s1", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  1 },
                { "l", "s2", "a2", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
                { "m", "s1", "a1", { SDB_TYPE_INTEGER, { .integer = 123 } }, 1,  0 },
        };
 
        size_t i;
 
-       sdb_memstore_host(store, "m", 1);
-       sdb_memstore_host(store, "l", 1);
-       sdb_memstore_service(store, "m", "s1", 1);
-       sdb_memstore_service(store, "l", "s1", 1);
-       sdb_memstore_service(store, "l", "s2", 1);
+       sdb_memstore_host(store, "m", 1, 0);
+       sdb_memstore_host(store, "l", 1, 0);
+       sdb_memstore_service(store, "m", "s1", 1, 0);
+       sdb_memstore_service(store, "l", "s1", 1, 0);
+       sdb_memstore_service(store, "l", "s2", 1, 0);
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                int status;
 
                status = sdb_memstore_service_attr(store, golden_data[i].host,
                                golden_data[i].svc, golden_data[i].attr,
-                               &golden_data[i].value, golden_data[i].last_update);
+                               &golden_data[i].value, golden_data[i].last_update, 0);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_memstore_service_attr(%s, %s, %s, %d, %d) = %d; "
+                               "sdb_memstore_service_attr(%s, %s, %s, %d, %d, 0) = %d; "
                                "expected: %d", golden_data[i].host, golden_data[i].svc,
                                golden_data[i].attr, golden_data[i].value.data.integer,
                                golden_data[i].last_update, status, golden_data[i].expected);
@@ -477,10 +463,8 @@ START_TEST(test_get_field)
        sdb_time_t now = sdb_gettime();
        int check;
 
-       sdb_memstore_host(store, "host", 10);
-       sdb_memstore_host(store, "host", 20);
-       sdb_memstore_attribute(store, "host", "attr", &get_field_data[_i].value, 10);
-       sdb_memstore_attribute(store, "host", "attr", &get_field_data[_i].value, 20);
+       sdb_memstore_host(store, "host", 20, 10);
+       sdb_memstore_attribute(store, "host", "attr", &get_field_data[_i].value, 20, 10);
 
        if (get_field_data[_i].hostname) {
                obj = sdb_memstore_get_host(store, get_field_data[_i].hostname);
@@ -642,6 +626,8 @@ START_TEST(test_get_child)
 }
 END_TEST
 
+/* TODO: move these tests into generic store tests */
+#if 0
 START_TEST(test_interval)
 {
        sdb_memstore_obj_t *host;
@@ -697,6 +683,7 @@ START_TEST(test_interval)
        sdb_object_deref(SDB_OBJ(host));
 }
 END_TEST
+#endif
 
 static int
 scan_count(sdb_memstore_obj_t *obj, sdb_memstore_matcher_t *filter, void *user_data)
@@ -802,7 +789,6 @@ TEST_MAIN("core::store")
        tcase_add_test(tc, test_store_service_attr);
        TC_ADD_LOOP_TEST(tc, get_field);
        tcase_add_test(tc, test_get_child);
-       tcase_add_test(tc, test_interval);
        tcase_add_test(tc, test_scan);
        ADD_TCASE(tc);
 }