From 311ac6c6189df40b68a03503e2744c03c317d8b6 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Tue, 1 Apr 2014 21:52:39 +0200 Subject: [PATCH] store: Added sdb_store_lookup(). 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 | 31 +++++++++++++++++++++++++++++++ src/include/core/store.h | 20 ++++++++++++++++++++ t/core/store_lookup_test.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/src/core/store_lookup.c b/src/core/store_lookup.c index d4a3d6c..35c53e5 100644 --- a/src/core/store_lookup.c +++ b/src/core/store_lookup.c @@ -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 : */ diff --git a/src/include/core/store.h b/src/include/core/store.h index a149b1d..25bd91a 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -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. * diff --git a/t/core/store_lookup_test.c b/t/core/store_lookup_test.c index 74274f8..465bb08 100644 --- a/t/core/store_lookup_test.c +++ b/t/core/store_lookup_test.c @@ -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: " + ""); + fail_unless(i != NULL, + "sdb_store_lookup callback received NULL user_data; " + "expected: "); + + ++(*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; -- 2.30.2