Code

store: Added sdb_store_lookup().
authorSebastian Harl <sh@tokkee.org>
Tue, 1 Apr 2014 19:52:39 +0000 (21:52 +0200)
committerSebastian Harl <sh@tokkee.org>
Tue, 1 Apr 2014 19:52:39 +0000 (21:52 +0200)
This function looks up objects from the store which match a user-specified
matcher. For each such object, a user-specified callback is executed.

src/core/store_lookup.c
src/include/core/store.h
t/core/store_lookup_test.c

index d4a3d6cccb83ba3612416faec7edd3b03995dedc..35c53e5b0b84c9818ac11a7a4004483a4ff27ac3 100644 (file)
@@ -111,6 +111,26 @@ typedef struct {
 } host_matcher_t;
 #define HOST_M(m) ((host_matcher_t *)(m))
 
+typedef struct {
+       sdb_store_matcher_t *m;
+       sdb_store_lookup_cb  cb;
+       void *user_data;
+} lookup_iter_data_t;
+
+/*
+ * private helper functions
+ */
+
+static int
+lookup_iter(sdb_store_base_t *obj, void *user_data)
+{
+       lookup_iter_data_t *d = user_data;
+
+       if (! sdb_store_matcher_matches(d->m, obj))
+               return d->cb(obj, d->user_data);
+       return 0;
+} /* lookup_iter */
+
 /*
  * matcher implementations
  */
@@ -543,5 +563,16 @@ sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj)
        return matchers[m->type](m, obj);
 } /* sdb_store_matcher_matches */
 
+int
+sdb_store_lookup(sdb_store_matcher_t *m, sdb_store_lookup_cb cb,
+               void *user_data)
+{
+       lookup_iter_data_t data = { m, cb, user_data };
+
+       if (! cb)
+               return -1;
+       return sdb_store_iterate(lookup_iter, &data);
+} /* sdb_store_lookup */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
 
index a149b1d714d3b245c36fad7c626d5dd40d564653..25bd91a9393daee17638ad3063c5a0259229df1b 100644 (file)
@@ -194,6 +194,26 @@ sdb_store_con_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right);
 int
 sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj);
 
+/*
+ * sdb_store_lookup_cb:
+ * Lookup callback. It is called for each matching object when looking up data
+ * in the store. The lookup aborts if the callback returns non-zero.
+ */
+typedef int (*sdb_store_lookup_cb)(sdb_store_base_t *obj, void *user_data);
+
+/*
+ * sdb_store_lookup:
+ * Look up objects in the store. The specified callback function is called for
+ * each object in the store matching 'm'.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_store_lookup(sdb_store_matcher_t *m, sdb_store_lookup_cb cb,
+               void *user_data);
+
 /*
  * Flags for serialization functions.
  *
index 74274f80c0cf0f8fc6ec75b7a4dcc909c1c19449..465bb08ca079004604ddc08d694d0192d509043c 100644 (file)
@@ -317,6 +317,35 @@ START_TEST(test_store_match_op)
 }
 END_TEST
 
+static int
+lookup_cb(sdb_store_base_t *obj, void *user_data)
+{
+       intptr_t *i = user_data;
+
+       fail_unless(obj != NULL,
+                       "sdb_store_lookup callback received NULL obj; expected: "
+                       "<store base obj>");
+       fail_unless(i != NULL,
+                       "sdb_store_lookup callback received NULL user_data; "
+                       "expected: <pointer to data>");
+
+       ++(*i);
+       return 0;
+} /* lookup_cb */
+
+START_TEST(test_lookup)
+{
+       intptr_t i = 0;
+       int check;
+
+       check = sdb_store_lookup(NULL, lookup_cb, &i);
+       fail_unless(check == 0,
+                       "sdb_store_lookup() = %d; expected: 0", check);
+       fail_unless(i == 3,
+                       "sdb_store_lookup called callback %d times; expected: 3", (int)i);
+}
+END_TEST
+
 Suite *
 core_store_lookup_suite(void)
 {
@@ -327,6 +356,7 @@ core_store_lookup_suite(void)
        tcase_add_checked_fixture(tc, populate, sdb_store_clear);
        tcase_add_test(tc, test_store_match);
        tcase_add_test(tc, test_store_match_op);
+       tcase_add_test(tc, test_lookup);
        suite_add_tcase(s, tc);
 
        return s;