dovecot-2.2: lib-dict: dict-fs implements now minimal iteration ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Sep 18 15:46:30 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/979e5a007248
changeset: 17824:979e5a007248
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Sep 18 17:46:18 2014 +0200
description:
lib-dict: dict-fs implements now minimal iteration support.

diffstat:

 src/lib-dict/dict-fs.c |  94 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 91 insertions(+), 3 deletions(-)

diffs (118 lines):

diff -r 9b65f3f583a3 -r 979e5a007248 src/lib-dict/dict-fs.c
--- a/src/lib-dict/dict-fs.c	Thu Sep 18 17:39:49 2014 +0200
+++ b/src/lib-dict/dict-fs.c	Thu Sep 18 17:46:18 2014 +0200
@@ -14,6 +14,16 @@
 	char *username;
 };
 
+struct fs_dict_iterate_context {
+	struct dict_iterate_context ctx;
+	const char **paths;
+	unsigned int path_idx;
+	enum dict_iterate_flags flags;
+	pool_t value_pool;
+	struct fs_iter *fs_iter;
+	bool failed;
+};
+
 static int
 fs_dict_init(struct dict *driver, const char *uri,
 	     const struct dict_settings *set,
@@ -106,6 +116,84 @@
 	return ret;
 }
 
+static struct dict_iterate_context *
+fs_dict_iterate_init(struct dict *_dict, const char *const *paths,
+		     enum dict_iterate_flags flags)
+{
+	struct fs_dict *dict = (struct fs_dict *)_dict;
+	struct fs_dict_iterate_context *iter;
+
+	/* these flags are not supported for now */
+	i_assert((flags & DICT_ITERATE_FLAG_RECURSE) == 0);
+	i_assert((flags & (DICT_ITERATE_FLAG_SORT_BY_KEY |
+			   DICT_ITERATE_FLAG_SORT_BY_VALUE)) == 0);
+
+	iter = i_new(struct fs_dict_iterate_context, 1);
+	iter->ctx.dict = _dict;
+	iter->paths = p_strarray_dup(default_pool, paths);
+	iter->flags = flags;
+	iter->value_pool = pool_alloconly_create("iterate value pool", 128);
+	iter->fs_iter = fs_iter_init(dict->fs,
+				     fs_dict_get_full_key(dict, paths[0]), 0);
+	return &iter->ctx;
+}
+
+static bool fs_dict_iterate(struct dict_iterate_context *ctx,
+			    const char **key_r, const char **value_r)
+{
+	struct fs_dict_iterate_context *iter =
+		(struct fs_dict_iterate_context *)ctx;
+	struct fs_dict *dict = (struct fs_dict *)ctx->dict;
+	const char *path;
+	int ret;
+
+	*key_r = fs_iter_next(iter->fs_iter);
+	if (*key_r == NULL) {
+		if (fs_iter_deinit(&iter->fs_iter) < 0) {
+			iter->failed = TRUE;
+			return FALSE;
+		}
+		if (iter->paths[++iter->path_idx] == NULL)
+			return FALSE;
+		path = fs_dict_get_full_key(dict, iter->paths[iter->path_idx]);
+		iter->fs_iter = fs_iter_init(dict->fs, path, 0);
+		return fs_dict_iterate(ctx, key_r, value_r);
+	}
+	if ((iter->flags & DICT_ITERATE_FLAG_NO_VALUE) != 0) {
+		*value_r = NULL;
+		return TRUE;
+	}
+	p_clear(iter->value_pool);
+	path = t_strconcat(iter->paths[iter->path_idx], *key_r, NULL);
+	if ((ret = fs_dict_lookup(ctx->dict, iter->value_pool, path, value_r)) < 0) {
+		/* I/O error */
+		iter->failed = TRUE;
+		return FALSE;
+	} else if (ret == 0) {
+		/* file was just deleted, just skip to next one */
+		return fs_dict_iterate(ctx, key_r, value_r);
+	}
+	return TRUE;
+}
+
+static int fs_dict_iterate_deinit(struct dict_iterate_context *ctx)
+{
+	struct fs_dict_iterate_context *iter =
+		(struct fs_dict_iterate_context *)ctx;
+	int ret;
+
+	if (iter->fs_iter != NULL) {
+		if (fs_iter_deinit(&iter->fs_iter) < 0)
+			iter->failed = TRUE;
+	}
+	ret = iter->failed ? -1 : 0;
+
+	pool_unref(&iter->value_pool);
+	i_free(iter->paths);
+	i_free(iter);
+	return ret;
+}
+
 static struct dict_transaction_context *
 fs_dict_transaction_init(struct dict *_dict)
 {
@@ -186,9 +274,9 @@
 		fs_dict_deinit,
 		NULL,
 		fs_dict_lookup,
-		NULL,
-		NULL,
-		NULL,
+		fs_dict_iterate_init,
+		fs_dict_iterate,
+		fs_dict_iterate_deinit,
 		fs_dict_transaction_init,
 		fs_dict_transaction_commit,
 		dict_transaction_memory_rollback,


More information about the dovecot-cvs mailing list