dovecot-2.2: lib-dict: Moved "in-memory transaction" code from d...

dovecot at dovecot.org dovecot at dovecot.org
Wed Aug 15 16:56:29 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/e266c31ebd02
changeset: 14905:e266c31ebd02
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Aug 15 16:55:44 2012 +0300
description:
lib-dict: Moved "in-memory transaction" code from dict-file to more generic API.

diffstat:

 src/lib-dict/Makefile.am               |    6 +-
 src/lib-dict/dict-file.c               |  135 ++++++--------------------------
 src/lib-dict/dict-transaction-memory.c |   72 +++++++++++++++++
 src/lib-dict/dict-transaction-memory.h |   41 ++++++++++
 4 files changed, 144 insertions(+), 110 deletions(-)

diffs (truncated from 387 to 300 lines):

diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/Makefile.am
--- a/src/lib-dict/Makefile.am	Wed Aug 15 12:05:28 2012 +0300
+++ b/src/lib-dict/Makefile.am	Wed Aug 15 16:55:44 2012 +0300
@@ -15,7 +15,8 @@
 	dict-client.c \
 	dict-file.c \
 	dict-memcached.c \
-	dict-redis.c
+	dict-redis.c \
+	dict-transaction-memory.c
 
 libdict_la_SOURCES = \
 	$(base_sources)
@@ -33,7 +34,8 @@
 	dict-client.h \
 	dict-private.h \
 	dict-sql.h \
-	dict-sql-settings.h
+	dict-sql-settings.h \
+	dict-transaction-memory.h
 
 pkginc_libdir=$(pkgincludedir)
 pkginc_lib_HEADERS = $(headers)
diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/dict-file.c
--- a/src/lib-dict/dict-file.c	Wed Aug 15 12:05:28 2012 +0300
+++ b/src/lib-dict/dict-file.c	Wed Aug 15 16:55:44 2012 +0300
@@ -8,6 +8,7 @@
 #include "nfs-workarounds.h"
 #include "istream.h"
 #include "ostream.h"
+#include "dict-transaction-memory.h"
 #include "dict-private.h"
 
 #include <stdio.h>
@@ -44,31 +45,6 @@
 	unsigned int failed:1;
 };
 
-enum file_dict_change_type {
-	FILE_DICT_CHANGE_TYPE_SET,
-	FILE_DICT_CHANGE_TYPE_UNSET,
-	FILE_DICT_CHANGE_TYPE_APPEND,
-	FILE_DICT_CHANGE_TYPE_INC
-};
-
-struct file_dict_change {
-	enum file_dict_change_type type;
-	const char *key;
-	union {
-		const char *str;
-		long long diff;
-	} value;
-};
-
-struct file_dict_transaction_context {
-	struct dict_transaction_context ctx;
-
-	pool_t pool;
-	ARRAY_DEFINE(changes, struct file_dict_change);
-
-	unsigned int atomic_inc_not_found:1;
-};
-
 static struct dotlock_settings file_dict_dotlock_settings = {
 	.timeout = 60*2,
 	.stale_timeout = 60,
@@ -290,24 +266,23 @@
 static struct dict_transaction_context *
 file_dict_transaction_init(struct dict *_dict)
 {
-	struct file_dict_transaction_context *ctx;
+	struct dict_transaction_memory_context *ctx;
 	pool_t pool;
 
 	pool = pool_alloconly_create("file dict transaction", 2048);
-	ctx = p_new(pool, struct file_dict_transaction_context, 1);
-	ctx->ctx.dict = _dict;
-	ctx->pool = pool;
-	p_array_init(&ctx->changes, pool, 32);
+	ctx = p_new(pool, struct dict_transaction_memory_context, 1);
+	dict_transaction_memory_init(ctx, _dict, pool);
 	return &ctx->ctx;
 }
 
-static void file_dict_apply_changes(struct file_dict_transaction_context *ctx)
+static void file_dict_apply_changes(struct dict_transaction_memory_context *ctx,
+				    bool *atomic_inc_not_found_r)
 {
 	struct file_dict *dict = (struct file_dict *)ctx->ctx.dict;
 	const char *tmp;
 	char *key, *value, *old_value;
 	void *orig_key, *orig_value;
-	const struct file_dict_change *change;
+	const struct dict_transaction_memory_change *change;
 	unsigned int new_len;
 	long long diff;
 
@@ -323,9 +298,9 @@
 		value = NULL;
 
 		switch (change->type) {
-		case FILE_DICT_CHANGE_TYPE_INC:
+		case DICT_CHANGE_TYPE_INC:
 			if (old_value == NULL) {
-				ctx->atomic_inc_not_found = TRUE;
+				*atomic_inc_not_found_r = TRUE;
 				break;
 			}
 			diff = strtoll(old_value, NULL, 10) +
@@ -339,7 +314,7 @@
 				value = old_value;
 			}
 			/* fall through */
-		case FILE_DICT_CHANGE_TYPE_SET:
+		case DICT_CHANGE_TYPE_SET:
 			if (key == NULL)
 				key = p_strdup(dict->hash_pool, change->key);
 			if (value == NULL) {
@@ -348,7 +323,7 @@
 			}
 			hash_table_update(dict->hash, key, value);
 			break;
-		case FILE_DICT_CHANGE_TYPE_APPEND:
+		case DICT_CHANGE_TYPE_APPEND:
 			if (key == NULL)
 				key = p_strdup(dict->hash_pool, change->key);
 			if (old_value == NULL) {
@@ -360,7 +335,7 @@
 			}
 			hash_table_update(dict->hash, key, value);
 			break;
-		case FILE_DICT_CHANGE_TYPE_UNSET:
+		case DICT_CHANGE_TYPE_UNSET:
 			if (old_value != NULL)
 				hash_table_remove(dict->hash, key);
 			break;
@@ -466,7 +441,8 @@
 	return ret < 0 ? -1 : 0;
 }
 
-static int file_dict_write_changes(struct file_dict_transaction_context *ctx)
+static int file_dict_write_changes(struct dict_transaction_memory_context *ctx,
+				   bool *atomic_inc_not_found_r)
 {
 	struct file_dict *dict = (struct file_dict *)ctx->ctx.dict;
 	struct dotlock *dotlock = NULL;
@@ -477,6 +453,8 @@
 	void *key, *value;
 	int fd = -1;
 
+	*atomic_inc_not_found_r = FALSE;
+
 	switch (dict->lock_method) {
 	case FILE_LOCK_METHOD_FCNTL:
 	case FILE_LOCK_METHOD_FLOCK:
@@ -519,7 +497,7 @@
 		/* get initial permissions from parent directory */
 		(void)fd_copy_parent_dir_permissions(dict->path, fd, temp_path);
 	}
-	file_dict_apply_changes(ctx);
+	file_dict_apply_changes(ctx, atomic_inc_not_found_r);
 
 	output = o_stream_create_fd(fd, 0, FALSE);
 	o_stream_cork(output);
@@ -569,13 +547,14 @@
 			     dict_transaction_commit_callback_t *callback,
 			     void *context)
 {
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
+	struct dict_transaction_memory_context *ctx =
+		(struct dict_transaction_memory_context *)_ctx;
+	bool atomic_inc_not_found;
 	int ret;
 
-	if (file_dict_write_changes(ctx) < 0)
+	if (file_dict_write_changes(ctx, &atomic_inc_not_found) < 0)
 		ret = -1;
-	else if (ctx->atomic_inc_not_found)
+	else if (atomic_inc_not_found)
 		ret = 0;
 	else
 		ret = 1;
@@ -586,66 +565,6 @@
 	return ret;
 }
 
-static void file_dict_transaction_rollback(struct dict_transaction_context *_ctx)
-{
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
-
-	pool_unref(&ctx->pool);
-}
-
-static void file_dict_set(struct dict_transaction_context *_ctx,
-			  const char *key, const char *value)
-{
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
-	struct file_dict_change *change;
-
-	change = array_append_space(&ctx->changes);
-	change->type = FILE_DICT_CHANGE_TYPE_SET;
-	change->key = p_strdup(ctx->pool, key);
-	change->value.str = p_strdup(ctx->pool, value);
-}
-
-static void file_dict_unset(struct dict_transaction_context *_ctx,
-			    const char *key)
-{
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
-	struct file_dict_change *change;
-
-	change = array_append_space(&ctx->changes);
-	change->type = FILE_DICT_CHANGE_TYPE_UNSET;
-	change->key = p_strdup(ctx->pool, key);
-}
-
-static void file_dict_append(struct dict_transaction_context *_ctx,
-			     const char *key, const char *value)
-{
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
-	struct file_dict_change *change;
-
-	change = array_append_space(&ctx->changes);
-	change->type = FILE_DICT_CHANGE_TYPE_APPEND;
-	change->key = p_strdup(ctx->pool, key);
-	change->value.str = p_strdup(ctx->pool, value);
-}
-
-static void
-file_dict_atomic_inc(struct dict_transaction_context *_ctx,
-		     const char *key, long long diff)
-{
-	struct file_dict_transaction_context *ctx =
-		(struct file_dict_transaction_context *)_ctx;
-	struct file_dict_change *change;
-
-	change = array_append_space(&ctx->changes);
-	change->type = FILE_DICT_CHANGE_TYPE_INC;
-	change->key = p_strdup(ctx->pool, key);
-	change->value.diff = diff;
-}
-
 struct dict dict_driver_file = {
 	.name = "file",
 	{
@@ -658,10 +577,10 @@
 		file_dict_iterate_deinit,
 		file_dict_transaction_init,
 		file_dict_transaction_commit,
-		file_dict_transaction_rollback,
-		file_dict_set,
-		file_dict_unset,
-		file_dict_append,
-		file_dict_atomic_inc
+		dict_transaction_memory_rollback,
+		dict_transaction_memory_set,
+		dict_transaction_memory_unset,
+		dict_transaction_memory_append,
+		dict_transaction_memory_atomic_inc
 	}
 };
diff -r aba24a5cc9ff -r e266c31ebd02 src/lib-dict/dict-transaction-memory.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-dict/dict-transaction-memory.c	Wed Aug 15 16:55:44 2012 +0300
@@ -0,0 +1,72 @@
+/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "dict-transaction-memory.h"
+
+void dict_transaction_memory_init(struct dict_transaction_memory_context *ctx,
+				  struct dict *dict, pool_t pool)
+{
+	ctx->ctx.dict = dict;
+	ctx->pool = pool;
+	p_array_init(&ctx->changes, pool, 32);
+}
+
+void dict_transaction_memory_rollback(struct dict_transaction_context *_ctx)
+{
+	struct dict_transaction_memory_context *ctx =
+		(struct dict_transaction_memory_context *)_ctx;
+
+	pool_unref(&ctx->pool);
+}
+
+void dict_transaction_memory_set(struct dict_transaction_context *_ctx,
+				 const char *key, const char *value)
+{
+	struct dict_transaction_memory_context *ctx =
+		(struct dict_transaction_memory_context *)_ctx;
+	struct dict_transaction_memory_change *change;
+
+	change = array_append_space(&ctx->changes);


More information about the dovecot-cvs mailing list