diff options
Diffstat (limited to 'src/old-stats/mail-domain.c')
-rw-r--r-- | src/old-stats/mail-domain.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/old-stats/mail-domain.c b/src/old-stats/mail-domain.c new file mode 100644 index 0000000..140fc15 --- /dev/null +++ b/src/old-stats/mail-domain.c @@ -0,0 +1,133 @@ +/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "hash.h" +#include "llist.h" +#include "global-memory.h" +#include "stats-settings.h" +#include "mail-stats.h" +#include "mail-domain.h" + +static HASH_TABLE(char *, struct mail_domain *) mail_domains_hash; +/* domains are sorted by their last_update timestamp, oldest first */ +static struct mail_domain *mail_domains_head, *mail_domains_tail; +struct mail_domain *stable_mail_domains; + +static size_t mail_domain_memsize(const struct mail_domain *domain) +{ + return sizeof(*domain) + strlen(domain->name) + 1; +} + +struct mail_domain *mail_domain_login_create(const char *name) +{ + struct mail_domain *domain; + + domain = hash_table_lookup(mail_domains_hash, name); + if (domain != NULL) { + return domain; + } + + domain = i_malloc(MALLOC_ADD(sizeof(struct mail_domain), stats_alloc_size())); + domain->stats = (void *)(domain + 1); + domain->name = i_strdup(name); + domain->reset_timestamp = ioloop_time; + + hash_table_insert(mail_domains_hash, domain->name, domain); + DLLIST_PREPEND_FULL(&stable_mail_domains, domain, + stable_prev, stable_next); + global_memory_alloc(mail_domain_memsize(domain)); + return domain; +} + +void mail_domain_login(struct mail_domain *domain) +{ + domain->num_logins++; + domain->num_connected_sessions++; + mail_domain_refresh(domain, NULL); +} + +void mail_domain_disconnected(struct mail_domain *domain) +{ + i_assert(domain->num_connected_sessions > 0); + domain->num_connected_sessions--; + mail_global_disconnected(); +} + +struct mail_domain *mail_domain_lookup(const char *name) +{ + return hash_table_lookup(mail_domains_hash, name); +} + +void mail_domain_ref(struct mail_domain *domain) +{ + domain->refcount++; +} + +void mail_domain_unref(struct mail_domain **_domain) +{ + struct mail_domain *domain = *_domain; + + i_assert(domain->refcount > 0); + domain->refcount--; + + *_domain = NULL; +} + +static void mail_domain_free(struct mail_domain *domain) +{ + i_assert(domain->refcount == 0); + i_assert(domain->users == NULL); + + global_memory_free(mail_domain_memsize(domain)); + hash_table_remove(mail_domains_hash, domain->name); + DLLIST_REMOVE_FULL(&stable_mail_domains, domain, + stable_prev, stable_next); + DLLIST2_REMOVE_FULL(&mail_domains_head, &mail_domains_tail, domain, + sorted_prev, sorted_next); + + i_free(domain->name); + i_free(domain); +} + +void mail_domain_refresh(struct mail_domain *domain, + const struct stats *diff_stats) +{ + if (diff_stats != NULL) + stats_add(domain->stats, diff_stats); + domain->last_update = ioloop_timeval; + DLLIST2_REMOVE_FULL(&mail_domains_head, &mail_domains_tail, domain, + sorted_prev, sorted_next); + DLLIST2_APPEND_FULL(&mail_domains_head, &mail_domains_tail, domain, + sorted_prev, sorted_next); + mail_global_refresh(diff_stats); +} + +void mail_domains_free_memory(void) +{ + unsigned int diff; + + while (mail_domains_head != NULL && mail_domains_head->refcount == 0) { + mail_domain_free(mail_domains_head); + + if (global_used_memory < stats_settings->memory_limit || + mail_domains_head == NULL) + break; + + diff = ioloop_time - mail_domains_head->last_update.tv_sec; + if (diff < stats_settings->domain_min_time) + break; + } +} + +void mail_domains_init(void) +{ + hash_table_create(&mail_domains_hash, default_pool, 0, str_hash, strcmp); +} + +void mail_domains_deinit(void) +{ + while (mail_domains_head != NULL) + mail_domain_free(mail_domains_head); + hash_table_destroy(&mail_domains_hash); +} |