dovecot-2.2: dict: Implemented dict_append()

dovecot at dovecot.org dovecot at dovecot.org
Tue Aug 14 06:22:58 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/87e14707d210
changeset: 14900:87e14707d210
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Aug 14 06:22:44 2012 +0300
description:
dict: Implemented dict_append()

diffstat:

 src/lib-dict/dict-client.c    |  18 ++++++++++++++++++
 src/lib-dict/dict-client.h    |   1 +
 src/lib-dict/dict-file.c      |  27 +++++++++++++++++++++++++++
 src/lib-dict/dict-memcached.c |   1 +
 src/lib-dict/dict-private.h   |   2 ++
 src/lib-dict/dict-redis.c     |  22 ++++++++++++++++++++++
 src/lib-dict/dict-sql.c       |  12 ++++++++++++
 src/lib-dict/dict.c           |   9 +++++++++
 src/lib-dict/dict.h           |   3 +++
 9 files changed, 95 insertions(+), 0 deletions(-)

diffs (227 lines):

diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-client.c
--- a/src/lib-dict/dict-client.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-client.c	Tue Aug 14 06:22:44 2012 +0300
@@ -785,6 +785,23 @@
 	} T_END;
 }
 
+static void client_dict_append(struct dict_transaction_context *_ctx,
+			       const char *key, const char *value)
+{
+	struct client_dict_transaction_context *ctx =
+		(struct client_dict_transaction_context *)_ctx;
+
+	T_BEGIN {
+		const char *query;
+
+		query = t_strdup_printf("%c%u\t%s\t%s\n",
+					DICT_PROTOCOL_CMD_APPEND, ctx->id,
+					dict_client_escape(key),
+					dict_client_escape(value));
+		client_dict_send_transaction_query(ctx, query);
+	} T_END;
+}
+
 static void client_dict_atomic_inc(struct dict_transaction_context *_ctx,
 				   const char *key, long long diff)
 {
@@ -816,6 +833,7 @@
 		client_dict_transaction_rollback,
 		client_dict_set,
 		client_dict_unset,
+		client_dict_append,
 		client_dict_atomic_inc
 	}
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-client.h
--- a/src/lib-dict/dict-client.h	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-client.h	Tue Aug 14 06:22:44 2012 +0300
@@ -24,6 +24,7 @@
 
 	DICT_PROTOCOL_CMD_SET = 'S', /* <id> <key> <value> */
 	DICT_PROTOCOL_CMD_UNSET = 'U', /* <id> <key> */
+	DICT_PROTOCOL_CMD_APPEND = 'P', /* <id> <key> <value> */
 	DICT_PROTOCOL_CMD_ATOMIC_INC = 'A' /* <id> <key> <diff> */
 };
 
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-file.c
--- a/src/lib-dict/dict-file.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-file.c	Tue Aug 14 06:22:44 2012 +0300
@@ -47,6 +47,7 @@
 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
 };
 
@@ -347,6 +348,18 @@
 			}
 			hash_table_update(dict->hash, key, value);
 			break;
+		case FILE_DICT_CHANGE_TYPE_APPEND:
+			if (key == NULL)
+				key = p_strdup(dict->hash_pool, change->key);
+			if (old_value == NULL) {
+				value = p_strdup(dict->hash_pool,
+						 change->value.str);
+			} else {
+				value = p_strconcat(dict->hash_pool, old_value,
+						    change->value.str, NULL);
+			}
+			hash_table_update(dict->hash, key, value);
+			break;
 		case FILE_DICT_CHANGE_TYPE_UNSET:
 			if (old_value != NULL)
 				hash_table_remove(dict->hash, key);
@@ -606,6 +619,19 @@
 	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)
@@ -635,6 +661,7 @@
 		file_dict_transaction_rollback,
 		file_dict_set,
 		file_dict_unset,
+		file_dict_append,
 		file_dict_atomic_inc
 	}
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-memcached.c
--- a/src/lib-dict/dict-memcached.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-memcached.c	Tue Aug 14 06:22:44 2012 +0300
@@ -371,6 +371,7 @@
 		NULL,
 		NULL,
 		NULL,
+		NULL,
 		NULL
 	}
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-private.h
--- a/src/lib-dict/dict-private.h	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-private.h	Tue Aug 14 06:22:44 2012 +0300
@@ -31,6 +31,8 @@
 		    const char *key, const char *value);
 	void (*unset)(struct dict_transaction_context *ctx,
 		      const char *key);
+	void (*append)(struct dict_transaction_context *ctx,
+		       const char *key, const char *value);
 	void (*atomic_inc)(struct dict_transaction_context *ctx,
 			   const char *key, long long diff);
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-redis.c
--- a/src/lib-dict/dict-redis.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-redis.c	Tue Aug 14 06:22:44 2012 +0300
@@ -624,6 +624,27 @@
 	ctx->cmd_count++;
 }
 
+static void redis_append(struct dict_transaction_context *_ctx,
+			 const char *key, const char *value)
+{
+	struct redis_dict_transaction_context *ctx =
+		(struct redis_dict_transaction_context *)_ctx;
+	struct redis_dict *dict = (struct redis_dict *)_ctx->dict;
+	const char *cmd;
+
+	if (redis_check_transaction(ctx) < 0)
+		return;
+
+	key = redis_dict_get_full_key(dict, key);
+	cmd = t_strdup_printf("*3\r\n$6\r\nAPPEND\r\n$%u\r\n%s\r\n$%u\r\n%s\r\n",
+			      (unsigned int)strlen(key), key,
+			      (unsigned int)strlen(value), value);
+	if (o_stream_send_str(dict->conn.conn.output, cmd) < 0)
+		ctx->failed = TRUE;
+	redis_input_state_add(dict, REDIS_INPUT_STATE_MULTI);
+	ctx->cmd_count++;
+}
+
 static void redis_atomic_inc(struct dict_transaction_context *_ctx,
 			     const char *key, long long diff)
 {
@@ -661,6 +682,7 @@
 		redis_transaction_rollback,
 		redis_set,
 		redis_unset,
+		redis_append,
 		redis_atomic_inc
 	}
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict-sql.c
--- a/src/lib-dict/dict-sql.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict-sql.c	Tue Aug 14 06:22:44 2012 +0300
@@ -730,6 +730,17 @@
 	} T_END;
 }
 
+static void
+sql_dict_append(struct dict_transaction_context *_ctx,
+		const char *key ATTR_UNUSED, const char *value ATTR_UNUSED)
+{
+	struct sql_dict_transaction_context *ctx =
+		(struct sql_dict_transaction_context *)_ctx;
+
+	i_error("sql dict: Append command not implemented currently");
+	ctx->failed = TRUE;
+}
+
 static unsigned int *
 sql_dict_next_inc_row(struct sql_dict_transaction_context *ctx)
 {
@@ -890,6 +901,7 @@
 		sql_dict_transaction_rollback,
 		sql_dict_set,
 		sql_dict_unset,
+		sql_dict_append,
 		sql_dict_atomic_inc
 	}
 };
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict.c
--- a/src/lib-dict/dict.c	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict.c	Tue Aug 14 06:22:44 2012 +0300
@@ -212,6 +212,15 @@
 	ctx->changed = TRUE;
 }
 
+void dict_append(struct dict_transaction_context *ctx,
+		 const char *key, const char *value)
+{
+	i_assert(dict_key_prefix_is_valid(key));
+
+	ctx->dict->v.append(ctx, key, value);
+	ctx->changed = TRUE;
+}
+
 void dict_atomic_inc(struct dict_transaction_context *ctx,
 		     const char *key, long long diff)
 {
diff -r f9d0ea98157f -r 87e14707d210 src/lib-dict/dict.h
--- a/src/lib-dict/dict.h	Mon Aug 13 15:23:32 2012 +0300
+++ b/src/lib-dict/dict.h	Tue Aug 14 06:22:44 2012 +0300
@@ -77,6 +77,9 @@
 /* Unset a record in dictionary, identified by key*/
 void dict_unset(struct dict_transaction_context *ctx,
 		const char *key);
+/* Append to an existing key in dictionary. Preferably an atomic operation. */
+void dict_append(struct dict_transaction_context *ctx,
+		 const char *key, const char *value);
 /* Increase/decrease a numeric value in dictionary. Note that the value is
    changed when transaction is being committed, so you can't know beforehand
    what the value will become. The value is updated only if it already exists,


More information about the dovecot-cvs mailing list