dovecot-2.2: lib-dict: Added async API for lookup and iteration.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 2 14:35:46 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/d40d7f24ffcf
changeset: 19064:d40d7f24ffcf
user: Timo Sirainen <tss at iki.fi>
date: Wed Sep 02 17:34:43 2015 +0300
description:
lib-dict: Added async API for lookup and iteration.
diffstat:
src/lib-dict/dict-client.c | 3 ++-
src/lib-dict/dict-file.c | 3 ++-
src/lib-dict/dict-fs.c | 1 +
src/lib-dict/dict-memcached-ascii.c | 3 ++-
src/lib-dict/dict-memcached.c | 1 +
src/lib-dict/dict-private.h | 8 ++++++++
src/lib-dict/dict-redis.c | 3 ++-
src/lib-dict/dict-sql.c | 3 ++-
src/lib-dict/dict.c | 30 ++++++++++++++++++++++++++++++
src/lib-dict/dict.h | 29 +++++++++++++++++++++++++++--
10 files changed, 77 insertions(+), 7 deletions(-)
diffs (229 lines):
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-client.c
--- a/src/lib-dict/dict-client.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-client.c Wed Sep 02 17:34:43 2015 +0300
@@ -852,6 +852,7 @@
client_dict_set,
client_dict_unset,
client_dict_append,
- client_dict_atomic_inc
+ client_dict_atomic_inc,
+ NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-file.c
--- a/src/lib-dict/dict-file.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-file.c Wed Sep 02 17:34:43 2015 +0300
@@ -650,6 +650,7 @@
dict_transaction_memory_set,
dict_transaction_memory_unset,
dict_transaction_memory_append,
- dict_transaction_memory_atomic_inc
+ dict_transaction_memory_atomic_inc,
+ NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-fs.c
--- a/src/lib-dict/dict-fs.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-fs.c Wed Sep 02 17:34:43 2015 +0300
@@ -284,6 +284,7 @@
dict_transaction_memory_set,
dict_transaction_memory_unset,
NULL,
+ NULL,
NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-memcached-ascii.c
--- a/src/lib-dict/dict-memcached-ascii.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-memcached-ascii.c Wed Sep 02 17:34:43 2015 +0300
@@ -663,6 +663,7 @@
dict_transaction_memory_set,
dict_transaction_memory_unset,
dict_transaction_memory_append,
- dict_transaction_memory_atomic_inc
+ dict_transaction_memory_atomic_inc,
+ NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-memcached.c
--- a/src/lib-dict/dict-memcached.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-memcached.c Wed Sep 02 17:34:43 2015 +0300
@@ -390,6 +390,7 @@
NULL,
NULL,
NULL,
+ NULL,
NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-private.h
--- a/src/lib-dict/dict-private.h Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-private.h Wed Sep 02 17:34:43 2015 +0300
@@ -35,6 +35,9 @@
const char *key, const char *value);
void (*atomic_inc)(struct dict_transaction_context *ctx,
const char *key, long long diff);
+
+ void (*lookup_async)(struct dict *dict, const char *key,
+ dict_lookup_callback_t *callback, void *context);
};
struct dict {
@@ -45,6 +48,11 @@
struct dict_iterate_context {
struct dict *dict;
+
+ dict_iterate_callback_t *async_callback;
+ void *async_context;
+
+ unsigned int has_more:1;
};
struct dict_transaction_context {
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-redis.c
--- a/src/lib-dict/dict-redis.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-redis.c Wed Sep 02 17:34:43 2015 +0300
@@ -801,6 +801,7 @@
redis_set,
redis_unset,
redis_append,
- redis_atomic_inc
+ redis_atomic_inc,
+ NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict-sql.c
--- a/src/lib-dict/dict-sql.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict-sql.c Wed Sep 02 17:34:43 2015 +0300
@@ -946,7 +946,8 @@
sql_dict_set,
sql_dict_unset,
sql_dict_append,
- sql_dict_atomic_inc
+ sql_dict_atomic_inc,
+ NULL
}
};
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict.c
--- a/src/lib-dict/dict.c Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict.c Wed Sep 02 17:34:43 2015 +0300
@@ -119,6 +119,23 @@
return dict->v.lookup(dict, pool, key, value_r);
}
+void dict_lookup_async(struct dict *dict, const char *key,
+ dict_lookup_callback_t *callback, void *context)
+{
+ if (dict->v.lookup_async == NULL) {
+ struct dict_lookup_result result;
+
+ memset(&result, 0, sizeof(result));
+ result.ret = dict_lookup(dict, pool_datastack_create(),
+ key, &result.value);
+ if (result.ret < 0)
+ result.error = "Lookup failed";
+ callback(&result, context);
+ return;
+ }
+ return dict->v.lookup_async(dict, key, callback, context);
+}
+
struct dict_iterate_context *
dict_iterate_init(struct dict *dict, const char *path,
enum dict_iterate_flags flags)
@@ -154,6 +171,19 @@
ctx->dict->v.iterate(ctx, key_r, value_r);
}
+void dict_iterate_set_async_callback(struct dict_iterate_context *ctx,
+ dict_iterate_callback_t *callback,
+ void *context)
+{
+ ctx->async_callback = callback;
+ ctx->async_context = context;
+}
+
+bool dict_iterate_has_more(struct dict_iterate_context *ctx)
+{
+ return ctx->has_more;
+}
+
int dict_iterate_deinit(struct dict_iterate_context **_ctx)
{
struct dict_iterate_context *ctx = *_ctx;
diff -r dd083fddda5e -r d40d7f24ffcf src/lib-dict/dict.h
--- a/src/lib-dict/dict.h Wed Sep 02 17:28:41 2015 +0300
+++ b/src/lib-dict/dict.h Wed Sep 02 17:34:43 2015 +0300
@@ -5,6 +5,7 @@
#define DICT_PATH_SHARED "shared/"
struct dict;
+struct dict_iterate_context;
enum dict_iterate_flags {
/* Recurse to all the sub-hierarchies (e.g. iterating "foo/" will
@@ -18,7 +19,9 @@
DICT_ITERATE_FLAG_NO_VALUE = 0x08,
/* Don't recurse at all. This is basically the same as dict_lookup(),
but it'll return all the rows instead of only the first one. */
- DICT_ITERATE_FLAG_EXACT_KEY = 0x10
+ DICT_ITERATE_FLAG_EXACT_KEY = 0x10,
+ /* Perform iteration asynchronously. */
+ DICT_ITERATE_FLAG_ASYNC = 0x20
};
enum dict_data_type {
@@ -35,6 +38,15 @@
const char *home_dir;
};
+struct dict_lookup_result {
+ int ret;
+ const char *value;
+ const char *error;
+};
+
+typedef void dict_lookup_callback_t(const struct dict_lookup_result *result,
+ void *context);
+typedef void dict_iterate_callback_t(void *context);
typedef void dict_transaction_commit_callback_t(int ret, void *context);
void dict_driver_register(struct dict *driver);
@@ -55,7 +67,7 @@
struct dict **dict_r, const char **error_r);
/* Close dictionary. */
void dict_deinit(struct dict **dict);
-/* Wait for all pending asynchronous transaction commits to finish.
+/* Wait for all pending asynchronous operations to finish.
Returns 0 if ok, -1 if error. */
int dict_wait(struct dict *dict);
@@ -63,6 +75,8 @@
Returns 1 if found, 0 if not found and -1 if lookup failed. */
int dict_lookup(struct dict *dict, pool_t pool,
const char *key, const char **value_r);
+void dict_lookup_async(struct dict *dict, const char *key,
+ dict_lookup_callback_t *callback, void *context);
/* Iterate through all values in a path. flag indicates how iteration
is carried out */
@@ -72,6 +86,17 @@
struct dict_iterate_context *
dict_iterate_init_multiple(struct dict *dict, const char *const *paths,
enum dict_iterate_flags flags);
+/* Set async callback. Note that if dict_iterate_init() already did all the
+ work, this callback may never be called. So after dict_iterate_init() you
+ should call dict_iterate() in any case to see if all the results are
+ already available. */
+void dict_iterate_set_async_callback(struct dict_iterate_context *ctx,
+ dict_iterate_callback_t *callback,
+ void *context);
+/* If dict_iterate() returns FALSE, the iteration may be finished or if this
+ is an async iteration it may be waiting for more data. If this function
+ returns TRUE, the dict callback is called again with more data. */
+bool dict_iterate_has_more(struct dict_iterate_context *ctx);
bool dict_iterate(struct dict_iterate_context *ctx,
const char **key_r, const char **value_r);
/* Returns 0 = ok, -1 = iteration failed */
More information about the dovecot-cvs
mailing list