changeset 9362:ea522175c549 HEAD

dict quota: When updating quota, recalculate it when necessary.
author Timo Sirainen <tss@iki.fi>
date Sun, 06 Sep 2009 20:45:21 -0400
parents a1b92a251bb9
children 1ec784dd4773
files src/plugins/quota/quota-dict.c
diffstat 1 files changed, 21 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/quota/quota-dict.c	Sun Sep 06 20:44:00 2009 -0400
+++ b/src/plugins/quota/quota-dict.c	Sun Sep 06 20:45:21 2009 -0400
@@ -83,8 +83,10 @@
 {
 	struct dict_quota_root *root = (struct dict_quota_root *)_root;
 
-	if (root->dict != NULL)
+	if (root->dict != NULL) {
+		(void)dict_wait(root->dict);
 		dict_deinit(&root->dict);
+	}
 	i_free(root);
 }
 
@@ -114,7 +116,7 @@
 		dict_set(dt, DICT_QUOTA_CURRENT_COUNT_PATH, dec2str(count));
 	} T_END;
 
-	dict_transaction_commit_async(&dt);
+	dict_transaction_commit_async(&dt, NULL, NULL);
 	*value_r = want_bytes ? bytes : count;
 	return 1;
 }
@@ -159,19 +161,30 @@
 	return ret;
 }
 
+static void dict_quota_update_callback(int ret, void *context)
+{
+	struct dict_quota_root *root = context;
+	uint64_t value;
+
+	if (ret == 0) {
+		/* row doesn't exist, need to recalculate it */
+		(void)dict_quota_count(root, TRUE, &value);
+	}
+}
+
 static int
 dict_quota_update(struct quota_root *_root, 
 		  struct quota_transaction_context *ctx)
 {
 	struct dict_quota_root *root = (struct dict_quota_root *) _root;
 	struct dict_transaction_context *dt;
-
-	dt = dict_transaction_begin(root->dict);
+	uint64_t value;
 
 	if (ctx->recalculate) {
-		dict_unset(dt, DICT_QUOTA_CURRENT_BYTES_PATH);
-		dict_unset(dt, DICT_QUOTA_CURRENT_COUNT_PATH);
+		if (dict_quota_count(root, TRUE, &value) < 0)
+			return -1;
 	} else {
+		dt = dict_transaction_begin(root->dict);
 		if (ctx->bytes_used != 0) {
 			dict_atomic_inc(dt, DICT_QUOTA_CURRENT_BYTES_PATH,
 					ctx->bytes_used);
@@ -180,9 +193,9 @@
 			dict_atomic_inc(dt, DICT_QUOTA_CURRENT_COUNT_PATH,
 					ctx->count_used);
 		}
+		dict_transaction_commit_async(&dt, dict_quota_update_callback,
+					      root);
 	}
-	
-	dict_transaction_commit_async(&dt);
 	return 0;
 }