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