Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/plugins/imap-quota/imap-quota-plugin.c @ 9564:efe0efc22d22 HEAD
imap-quota: Iterate quota roots only once when replying to GETQUOTAROOT.
This halves the required dict lookup count.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 20 Apr 2010 13:02:29 +0300 |
parents | 00cd9aacd03c |
children |
comparison
equal
deleted
inserted
replaced
9563:002b58bab1f5 | 9564:efe0efc22d22 |
---|---|
1 /* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */ | 1 /* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */ |
2 | 2 |
3 #include "common.h" | 3 #include "common.h" |
4 #include "str.h" | 4 #include "str.h" |
5 #include "ostream.h" | |
5 #include "imap-quote.h" | 6 #include "imap-quote.h" |
6 #include "mail-namespace.h" | 7 #include "mail-namespace.h" |
7 #include "commands.h" | 8 #include "commands.h" |
8 #include "quota.h" | 9 #include "quota.h" |
9 #include "quota-plugin.h" | 10 #include "quota-plugin.h" |
27 return t_strdup_printf("%s%c%s", owner->username, | 28 return t_strdup_printf("%s%c%s", owner->username, |
28 QUOTA_USER_SEPARATOR, name); | 29 QUOTA_USER_SEPARATOR, name); |
29 } | 30 } |
30 | 31 |
31 static void | 32 static void |
32 quota_send(struct client_command_context *cmd, struct mail_user *owner, | 33 quota_reply_write(string_t *str, struct mail_user *user, |
33 struct quota_root *root) | 34 struct mail_user *owner, struct quota_root *root) |
34 { | 35 { |
35 const char *name, *const *list; | 36 const char *name, *const *list; |
36 string_t *str; | |
37 unsigned int i; | 37 unsigned int i; |
38 uint64_t value, limit; | 38 uint64_t value, limit; |
39 int ret; | 39 int ret = 0; |
40 | 40 |
41 str = t_str_new(128); | |
42 str_append(str, "* QUOTA "); | 41 str_append(str, "* QUOTA "); |
43 name = imap_quota_root_get_name(cmd->client->user, owner, root); | 42 name = imap_quota_root_get_name(user, owner, root); |
44 imap_quote_append_string(str, name, FALSE); | 43 imap_quote_append_string(str, name, FALSE); |
45 | 44 |
46 str_append(str, " ("); | 45 str_append(str, " ("); |
47 list = quota_root_get_resources(root); | 46 list = quota_root_get_resources(root); |
48 for (i = 0; *list != NULL; list++) { | 47 for (i = 0; *list != NULL; list++) { |
49 ret = quota_get_resource(root, "", *list, &value, &limit); | 48 ret = quota_get_resource(root, "", *list, &value, &limit); |
49 if (ret < 0) | |
50 break; | |
50 if (ret > 0) { | 51 if (ret > 0) { |
51 if (i > 0) | 52 if (i > 0) |
52 str_append_c(str, ' '); | 53 str_append_c(str, ' '); |
53 str_printfa(str, "%s %llu %llu", *list, | 54 str_printfa(str, "%s %llu %llu", *list, |
54 (unsigned long long)value, | 55 (unsigned long long)value, |
55 (unsigned long long)limit); | 56 (unsigned long long)limit); |
56 i++; | 57 i++; |
57 } else if (ret < 0) { | 58 } |
58 client_send_line(cmd->client, | 59 } |
59 "* BAD Internal quota calculation error"); | 60 str_append(str, ")\r\n"); |
60 } | 61 |
61 } | 62 if (ret < 0) |
62 str_append_c(str, ')'); | 63 str_append(str, "* BAD Internal quota calculation error\r\n"); |
63 client_send_line(cmd->client, str_c(str)); | |
64 } | 64 } |
65 | 65 |
66 static bool cmd_getquotaroot(struct client_command_context *cmd) | 66 static bool cmd_getquotaroot(struct client_command_context *cmd) |
67 { | 67 { |
68 struct client *client = cmd->client; | 68 struct client *client = cmd->client; |
70 struct mail_namespace *ns; | 70 struct mail_namespace *ns; |
71 struct mailbox *box; | 71 struct mailbox *box; |
72 struct quota_root_iter *iter; | 72 struct quota_root_iter *iter; |
73 struct quota_root *root; | 73 struct quota_root *root; |
74 const char *orig_mailbox, *mailbox, *name; | 74 const char *orig_mailbox, *mailbox, *name; |
75 string_t *str; | 75 string_t *quotaroot_reply, *quota_reply; |
76 | 76 |
77 /* <mailbox> */ | 77 /* <mailbox> */ |
78 if (!client_read_string_args(cmd, 1, &mailbox)) | 78 if (!client_read_string_args(cmd, 1, &mailbox)) |
79 return FALSE; | 79 return FALSE; |
80 | 80 |
102 mailbox_close(&box); | 102 mailbox_close(&box); |
103 client_send_tagline(cmd, "NO Not showing other users' quota."); | 103 client_send_tagline(cmd, "NO Not showing other users' quota."); |
104 return TRUE; | 104 return TRUE; |
105 } | 105 } |
106 | 106 |
107 /* send QUOTAROOT reply */ | 107 /* build QUOTAROOT reply and QUOTA reply for all quota roots */ |
108 str = t_str_new(128); | 108 quotaroot_reply = t_str_new(128); |
109 str_append(str, "* QUOTAROOT "); | 109 quota_reply = t_str_new(256); |
110 imap_quote_append_string(str, orig_mailbox, FALSE); | 110 str_append(quotaroot_reply, "* QUOTAROOT "); |
111 imap_quote_append_string(quotaroot_reply, mailbox, FALSE); | |
111 | 112 |
112 iter = quota_root_iter_init(box); | 113 iter = quota_root_iter_init(box); |
113 while ((root = quota_root_iter_next(iter)) != NULL) { | 114 while ((root = quota_root_iter_next(iter)) != NULL) { |
114 str_append_c(str, ' '); | 115 str_append_c(quotaroot_reply, ' '); |
115 name = imap_quota_root_get_name(client->user, ns->owner, root); | 116 name = imap_quota_root_get_name(client->user, ns->owner, root); |
116 imap_quote_append_string(str, name, FALSE); | 117 imap_quote_append_string(quotaroot_reply, name, FALSE); |
117 } | 118 |
118 quota_root_iter_deinit(&iter); | 119 quota_reply_write(quota_reply, client->user, ns->owner, root); |
119 client_send_line(client, str_c(str)); | 120 } |
120 | |
121 /* send QUOTA reply for each quotaroot */ | |
122 iter = quota_root_iter_init(box); | |
123 while ((root = quota_root_iter_next(iter)) != NULL) | |
124 quota_send(cmd, ns->owner, root); | |
125 quota_root_iter_deinit(&iter); | 121 quota_root_iter_deinit(&iter); |
126 mailbox_close(&box); | 122 mailbox_close(&box); |
127 | 123 |
124 /* send replies */ | |
125 client_send_line(client, str_c(quotaroot_reply)); | |
126 o_stream_send(client->output, str_data(quota_reply), | |
127 str_len(quota_reply)); | |
128 client_send_tagline(cmd, "OK Getquotaroot completed."); | 128 client_send_tagline(cmd, "OK Getquotaroot completed."); |
129 return TRUE; | 129 return TRUE; |
130 } | 130 } |
131 | 131 |
132 static bool cmd_getquota(struct client_command_context *cmd) | 132 static bool cmd_getquota(struct client_command_context *cmd) |
133 { | 133 { |
134 struct mail_user *owner = cmd->client->user; | 134 struct mail_user *owner = cmd->client->user; |
135 struct quota_root *root; | 135 struct quota_root *root; |
136 const char *root_name, *p; | 136 const char *root_name, *p; |
137 string_t *quota_reply; | |
137 | 138 |
138 /* <quota root> */ | 139 /* <quota root> */ |
139 if (!client_read_string_args(cmd, 1, &root_name)) | 140 if (!client_read_string_args(cmd, 1, &root_name)) |
140 return FALSE; | 141 return FALSE; |
141 | 142 |
159 if (root == NULL) { | 160 if (root == NULL) { |
160 client_send_tagline(cmd, "NO Quota root doesn't exist."); | 161 client_send_tagline(cmd, "NO Quota root doesn't exist."); |
161 return TRUE; | 162 return TRUE; |
162 } | 163 } |
163 | 164 |
164 quota_send(cmd, owner, root); | 165 quota_reply = t_str_new(128); |
166 quota_reply_write(quota_reply, cmd->client->user, owner, root); | |
167 o_stream_send(cmd->client->output, str_data(quota_reply), | |
168 str_len(quota_reply)); | |
169 | |
165 client_send_tagline(cmd, "OK Getquota completed."); | 170 client_send_tagline(cmd, "OK Getquota completed."); |
166 return TRUE; | 171 return TRUE; |
167 } | 172 } |
168 | 173 |
169 static bool cmd_setquota(struct client_command_context *cmd) | 174 static bool cmd_setquota(struct client_command_context *cmd) |