]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota-count: Cache quota usage within the same ioloop run.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 29 Apr 2016 14:21:26 +0000 (17:21 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 29 Apr 2016 14:21:26 +0000 (17:21 +0300)
This mainly means that when both STORAGE and MESSAGES quota is looked up we
don't need to calculate them twice.

src/plugins/quota/quota-count.c

index a03e17822c3d2b5761213ea46b9ca5f891644913..2d2c352ab84ab7ae7ae90215dcb2fc92880aafbe 100644 (file)
@@ -1,9 +1,17 @@
 /* Copyright (c) 2006-2016 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "mailbox-list-iter.h"
 #include "quota-private.h"
 
+struct count_quota_root {
+       struct quota_root root;
+
+       struct timeval cache_timeval;
+       uint64_t cached_bytes, cached_count;
+};
+
 struct quota_mailbox_iter {
        struct quota_root *root;
        struct mail_namespace *ns;
@@ -137,10 +145,19 @@ quota_mailbox_iter_next(struct quota_mailbox_iter *iter)
 
 int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r)
 {
+       struct count_quota_root *croot = (struct count_quota_root *)root;
        struct quota_mailbox_iter *iter;
        const struct mailbox_info *info;
        int ret = 0, ret2;
 
+       if (croot->cache_timeval.tv_usec == ioloop_timeval.tv_usec &&
+           croot->cache_timeval.tv_sec == ioloop_timeval.tv_sec &&
+           ioloop_timeval.tv_sec != 0) {
+               *bytes_r = croot->cached_bytes;
+               *count_r = croot->cached_count;
+               return 1;
+       }
+
        *bytes_r = *count_r = 0;
        if (root->recounting)
                return 0;
@@ -159,12 +176,20 @@ int quota_count(struct quota_root *root, uint64_t *bytes_r, uint64_t *count_r)
        }
        quota_mailbox_iter_deinit(&iter);
        root->recounting = FALSE;
+       if (ret > 0) {
+               croot->cache_timeval = ioloop_timeval;
+               croot->cached_bytes = *bytes_r;
+               croot->cached_count = *count_r;
+       }
        return ret < 0 ? -1 : 0;
 }
 
 static struct quota_root *count_quota_alloc(void)
 {
-       return i_new(struct quota_root, 1);
+       struct count_quota_root *root;
+
+       root = i_new(struct count_quota_root, 1);
+       return &root->root;
 }
 
 static int count_quota_init(struct quota_root *root, const char *args,
@@ -273,6 +298,9 @@ static int
 count_quota_update(struct quota_root *root,
                   struct quota_transaction_context *ctx)
 {
+       struct count_quota_root *croot = (struct count_quota_root *)root;
+
+       croot->cache_timeval.tv_sec = 0;
        if (ctx->recalculate) {
                if (quota_count_recalculate(root) < 0)
                        return -1;