dovecot-2.0: imap-quota: Iterate quota roots only once when repl...

dovecot at dovecot.org dovecot at dovecot.org
Fri Apr 16 16:44:18 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/4b14271e04db
changeset: 11163:4b14271e04db
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Apr 16 16:42:58 2010 +0300
description:
imap-quota: Iterate quota roots only once when replying to GETQUOTAROOT.
This halves the required dict lookup count.

diffstat:

 src/plugins/imap-quota/imap-quota-plugin.c |  57 +++++++++++++++-------------
 1 files changed, 31 insertions(+), 26 deletions(-)

diffs (131 lines):

diff -r bf08bb1807cf -r 4b14271e04db src/plugins/imap-quota/imap-quota-plugin.c
--- a/src/plugins/imap-quota/imap-quota-plugin.c	Fri Apr 16 16:14:15 2010 +0300
+++ b/src/plugins/imap-quota/imap-quota-plugin.c	Fri Apr 16 16:42:58 2010 +0300
@@ -2,6 +2,7 @@
 
 #include "imap-common.h"
 #include "str.h"
+#include "ostream.h"
 #include "imap-quote.h"
 #include "mail-namespace.h"
 #include "imap-commands.h"
@@ -32,24 +33,24 @@
 }
 
 static void
-quota_send(struct client_command_context *cmd, struct mail_user *owner,
-	   struct quota_root *root)
+quota_reply_write(string_t *str, struct mail_user *user,
+		  struct mail_user *owner, struct quota_root *root)
 {
         const char *name, *const *list;
-	string_t *str;
 	unsigned int i;
 	uint64_t value, limit;
-	int ret;
+	int ret = 0;
 
-	str = t_str_new(128);
 	str_append(str, "* QUOTA ");
-	name = imap_quota_root_get_name(cmd->client->user, owner, root);
+	name = imap_quota_root_get_name(user, owner, root);
 	imap_quote_append_string(str, name, FALSE);
 
 	str_append(str, " (");
 	list = quota_root_get_resources(root);
 	for (i = 0; *list != NULL; list++) {
 		ret = quota_get_resource(root, "", *list, &value, &limit);
+		if (ret < 0)
+			break;
 		if (ret > 0) {
 			if (i > 0)
 				str_append_c(str, ' ');
@@ -57,13 +58,12 @@
 				    (unsigned long long)value,
 				    (unsigned long long)limit);
 			i++;
-		} else if (ret < 0) {
-			client_send_line(cmd->client, 
-				"* BAD Internal quota calculation error");
 		}
 	}
-	str_append_c(str, ')');
-	client_send_line(cmd->client, str_c(str));
+	str_append(str, ")\r\n");
+
+	if (ret < 0)
+		str_append(str, "* BAD Internal quota calculation error\r\n");
 }
 
 static bool cmd_getquotaroot(struct client_command_context *cmd)
@@ -75,7 +75,7 @@
 	struct quota_root_iter *iter;
         struct quota_root *root;
 	const char *mailbox, *storage_name, *name;
-	string_t *str;
+	string_t *quotaroot_reply, *quota_reply;
 
 	/* <mailbox> */
 	if (!client_read_string_args(cmd, 1, &mailbox))
@@ -98,27 +98,27 @@
 	box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_READONLY |
 			    MAILBOX_FLAG_KEEP_RECENT);
 
-	/* send QUOTAROOT reply */
-	str = t_str_new(128);
-	str_append(str, "* QUOTAROOT ");
-	imap_quote_append_string(str, mailbox, FALSE);
+	/* build QUOTAROOT reply and QUOTA reply for all quota roots */
+	quotaroot_reply = t_str_new(128);
+	quota_reply = t_str_new(256);
+	str_append(quotaroot_reply, "* QUOTAROOT ");
+	imap_quote_append_string(quotaroot_reply, mailbox, FALSE);
 
 	iter = quota_root_iter_init(box);
 	while ((root = quota_root_iter_next(iter)) != NULL) {
-		str_append_c(str, ' ');
+		str_append_c(quotaroot_reply, ' ');
 		name = imap_quota_root_get_name(client->user, ns->owner, root);
-		imap_quote_append_string(str, name, FALSE);
+		imap_quote_append_string(quotaroot_reply, name, FALSE);
+
+		quota_reply_write(quota_reply, client->user, ns->owner, root);
 	}
 	quota_root_iter_deinit(&iter);
-	client_send_line(client, str_c(str));
-
-	/* send QUOTA reply for each quotaroot */
-	iter = quota_root_iter_init(box);
-	while ((root = quota_root_iter_next(iter)) != NULL)
-		quota_send(cmd, ns->owner, root);
-	quota_root_iter_deinit(&iter);
 	mailbox_free(&box);
 
+	/* send replies */
+	client_send_line(client, str_c(quotaroot_reply));
+	o_stream_send(client->output, str_data(quota_reply),
+		      str_len(quota_reply));
 	client_send_tagline(cmd, "OK Getquotaroot completed.");
 	return TRUE;
 }
@@ -128,6 +128,7 @@
 	struct mail_user *owner = cmd->client->user;
         struct quota_root *root;
 	const char *root_name, *p;
+	string_t *quota_reply;
 
 	/* <quota root> */
 	if (!client_read_string_args(cmd, 1, &root_name))
@@ -150,7 +151,11 @@
 		return TRUE;
 	}
 
-	quota_send(cmd, owner, root);
+	quota_reply = t_str_new(128);
+	quota_reply_write(quota_reply, cmd->client->user, owner, root);
+	o_stream_send(cmd->client->output, str_data(quota_reply),
+		      str_len(quota_reply));
+
 	client_send_tagline(cmd, "OK Getquota completed.");
 	return TRUE;
 }


More information about the dovecot-cvs mailing list