# HG changeset patch # User Timo Sirainen # Date 1271757749 -10800 # Node ID efe0efc22d22910eb78711add8b8bd350a6fceee # Parent 002b58bab1f532f1319f0331b81110ab2467e579 imap-quota: Iterate quota roots only once when replying to GETQUOTAROOT. This halves the required dict lookup count. diff -r 002b58bab1f5 -r efe0efc22d22 src/plugins/imap-quota/imap-quota-plugin.c --- a/src/plugins/imap-quota/imap-quota-plugin.c Fri Apr 16 16:44:15 2010 +0300 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Tue Apr 20 13:02:29 2010 +0300 @@ -2,6 +2,7 @@ #include "common.h" #include "str.h" +#include "ostream.h" #include "imap-quote.h" #include "mail-namespace.h" #include "commands.h" @@ -29,24 +30,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, ' '); @@ -54,13 +55,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) @@ -72,7 +72,7 @@ struct quota_root_iter *iter; struct quota_root *root; const char *orig_mailbox, *mailbox, *name; - string_t *str; + string_t *quotaroot_reply, *quota_reply; /* */ if (!client_read_string_args(cmd, 1, &mailbox)) @@ -104,27 +104,27 @@ return TRUE; } - /* send QUOTAROOT reply */ - str = t_str_new(128); - str_append(str, "* QUOTAROOT "); - imap_quote_append_string(str, orig_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_close(&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; } @@ -134,6 +134,7 @@ struct mail_user *owner = cmd->client->user; struct quota_root *root; const char *root_name, *p; + string_t *quota_reply; /* */ if (!client_read_string_args(cmd, 1, &root_name)) @@ -161,7 +162,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; }