]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap-quota: Iterate quota roots only once when replying to GETQUOTAROOT.
authorTimo Sirainen <tss@iki.fi>
Fri, 16 Apr 2010 13:42:58 +0000 (16:42 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 16 Apr 2010 13:42:58 +0000 (16:42 +0300)
This halves the required dict lookup count.

--HG--
branch : HEAD

src/plugins/imap-quota/imap-quota-plugin.c

index 2224abd9ed7cc971797967968cf6285aa2016a15..19276af48fe689a8c42c65e934476fc1667a589b 100644 (file)
@@ -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 @@ imap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
 }
 
 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 @@ quota_send(struct client_command_context *cmd, struct mail_user *owner,
                                    (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 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
        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 @@ static bool cmd_getquotaroot(struct client_command_context *cmd)
        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);
-       }
-       quota_root_iter_deinit(&iter);
-       client_send_line(client, str_c(str));
+               imap_quote_append_string(quotaroot_reply, name, FALSE);
 
-       /* 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_reply_write(quota_reply, client->user, 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 @@ static bool cmd_getquota(struct client_command_context *cmd)
        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 @@ static bool cmd_getquota(struct client_command_context *cmd)
                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;
 }