dovecot-2.2: quota: Code cleanup - abstract out iteration of mai...

dovecot at dovecot.org dovecot at dovecot.org
Mon Sep 28 13:09:55 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/78a027250652
changeset: 19244:78a027250652
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Sep 28 16:06:43 2015 +0300
description:
quota: Code cleanup - abstract out iteration of mailboxes related to a quota root.

diffstat:

 src/plugins/quota/quota-count.c |  110 +++++++++++++++++++++++++++------------
 1 files changed, 76 insertions(+), 34 deletions(-)

diffs (148 lines):

diff -r b7a0b0d86651 -r 78a027250652 src/plugins/quota/quota-count.c
--- a/src/plugins/quota/quota-count.c	Mon Sep 28 15:51:45 2015 +0300
+++ b/src/plugins/quota/quota-count.c	Mon Sep 28 16:06:43 2015 +0300
@@ -4,6 +4,15 @@
 #include "mailbox-list-iter.h"
 #include "quota-private.h"
 
+struct quota_mailbox_iter {
+	struct quota_root *root;
+	struct mail_namespace *ns;
+	unsigned int ns_idx;
+	struct mailbox_list_iterate_context *iter;
+	struct mailbox_info info;
+	bool failed;
+};
+
 extern struct quota_backend quota_backend_count;
 
 static int
@@ -49,44 +58,81 @@
 	return ret;
 }
 
+static struct quota_mailbox_iter *
+quota_mailbox_iter_begin(struct quota_root *root)
+{
+	struct quota_mailbox_iter *iter;
+
+	iter = i_new(struct quota_mailbox_iter, 1);
+	iter->root = root;
+	return iter;
+}
+
 static int
-quota_count_namespace(struct quota_root *root, struct mail_namespace *ns,
-		      uint64_t *bytes, uint64_t *count)
+quota_mailbox_iter_deinit(struct quota_mailbox_iter **_iter)
 {
-	struct mailbox_list_iterate_context *ctx;
-	const struct mailbox_info *info;
-	int ret = 0;
+	struct quota_mailbox_iter *iter = *_iter;
+	int ret = iter->failed ? -1 : 0;
 
-	ctx = mailbox_list_iter_init(ns->list, "*",
-				     MAILBOX_LIST_ITER_SKIP_ALIASES |
-				     MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
-	while ((info = mailbox_list_iter_next(ctx)) != NULL) {
-		if ((info->flags & (MAILBOX_NONEXISTENT |
-				    MAILBOX_NOSELECT)) == 0) {
-			ret = quota_count_mailbox(root, ns, info->vname,
-						  bytes, count);
-			if (ret < 0)
-				break;
+	*_iter = NULL;
+
+	if (iter->iter != NULL) {
+		if (mailbox_list_iter_deinit(&iter->iter) < 0) {
+			i_error("quota: Listing namespace '%s' failed: %s",
+				iter->ns->prefix,
+				mailbox_list_get_last_error(iter->ns->list, NULL));
+			ret = -1;
 		}
 	}
-	if (mailbox_list_iter_deinit(&ctx) < 0) {
+	i_free(iter);
+	return ret;
+}
+
+static const struct mailbox_info *
+quota_mailbox_iter_next(struct quota_mailbox_iter *iter)
+{
+	struct mail_namespace *const *namespaces;
+	const struct mailbox_info *info;
+	unsigned int count;
+
+	if (iter->iter == NULL) {
+		namespaces = array_get(&iter->root->quota->namespaces, &count);
+		if (iter->ns_idx >= count)
+			return NULL;
+
+		iter->ns = namespaces[iter->ns_idx++];
+		iter->iter = mailbox_list_iter_init(iter->ns->list, "*",
+			MAILBOX_LIST_ITER_SKIP_ALIASES |
+			MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
+	}
+	while ((info = mailbox_list_iter_next(iter->iter)) != NULL) {
+		if ((info->flags & (MAILBOX_NONEXISTENT |
+				    MAILBOX_NOSELECT)) == 0)
+			return info;
+	}
+	if (mailbox_list_iter_deinit(&iter->iter) < 0) {
 		i_error("quota: Listing namespace '%s' failed: %s",
-			ns->prefix, mailbox_list_get_last_error(ns->list, NULL));
-		ret = -1;
+			iter->ns->prefix,
+			mailbox_list_get_last_error(iter->ns->list, NULL));
+		iter->failed = TRUE;
 	}
-	if (ns->prefix_len > 0 && ret == 0 &&
-	    (ns->prefix_len != 6 || strncasecmp(ns->prefix, "INBOX", 5) != 0)) {
+	if (iter->ns->prefix_len > 0 &&
+	    (iter->ns->prefix_len != 6 ||
+	     strncasecmp(iter->ns->prefix, "INBOX", 5) != 0)) {
 		/* if the namespace prefix itself exists, count it also */
-		const char *name = t_strndup(ns->prefix, ns->prefix_len-1);
-		ret = quota_count_mailbox(root, ns, name, bytes, count);
+		iter->info.ns = iter->ns;
+		iter->info.vname = t_strndup(iter->ns->prefix,
+					     iter->ns->prefix_len-1);
+		return &iter->info;
 	}
-	return ret;
+	/* try the next namespace */
+	return quota_mailbox_iter_next(iter);
 }
 
 int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r)
 {
-	struct mail_namespace *const *namespaces;
-	unsigned int i, count;
+	struct quota_mailbox_iter *iter;
+	const struct mailbox_info *info;
 	int ret = 0;
 
 	*bytes_r = *count_r = 0;
@@ -94,16 +140,12 @@
 		return 0;
 	root->recounting = TRUE;
 
-	namespaces = array_get(&root->quota->namespaces, &count);
-	for (i = 0; i < count; i++) {
-		if (!quota_root_is_namespace_visible(root, namespaces[i]))
-			continue;
-
-		ret = quota_count_namespace(root, namespaces[i],
-					    bytes_r, count_r);
-		if (ret < 0)
-			break;
+	iter = quota_mailbox_iter_begin(root);
+	while (ret >= 0 && (info = quota_mailbox_iter_next(iter)) != NULL) {
+		ret = quota_count_mailbox(root, info->ns, info->vname,
+					  bytes_r, count_r);
 	}
+	quota_mailbox_iter_deinit(&iter);
 	root->recounting = FALSE;
 	return ret;
 }


More information about the dovecot-cvs mailing list