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