changeset 1600:993fe64a5e20 HEAD

Destroy all unused indexes 10 seconds after use. Before we destroyed them only when opening a new index.
author Timo Sirainen <tss@iki.fi>
date Mon, 07 Jul 2003 01:55:22 +0300
parents 4c4d0d771350
children 5d3d87ab83c1
files src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c
diffstat 4 files changed, 72 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-storage.c	Sun Jul 06 22:28:38 2003 +0300
+++ b/src/lib-storage/index/index-storage.c	Mon Jul 07 01:55:22 2003 +0300
@@ -29,6 +29,21 @@
 };
 
 static struct index_list *indexes = NULL;
+static struct timeout *to_index = NULL;
+static int index_storage_refcount = 0;
+
+void index_storage_init(struct mail_storage *storage __attr_unused__)
+{
+	index_storage_refcount++;
+}
+
+void index_storage_deinit(struct mail_storage *storage __attr_unused__)
+{
+	if (--index_storage_refcount > 0)
+		return;
+
+        index_storage_destroy_unrefed();
+}
 
 void index_storage_add(struct mail_index *index)
 {
@@ -83,30 +98,15 @@
 	return match;
 }
 
-void index_storage_unref(struct mail_index *index)
-{
-	struct index_list *list;
-
-	for (list = indexes; list != NULL; list = list->next) {
-		if (list->index == index) {
-			i_assert(list->refcount > 0);
-			list->refcount--;
-			list->destroy_time = ioloop_time + INDEX_CACHE_TIMEOUT;
-			return;
-		}
-	}
-
-	i_unreached();
-}
-
-void index_storage_destroy_unrefed(void)
+static void destroy_unrefed(int all)
 {
 	struct index_list **list, *rec;
 
 	for (list = &indexes; *list != NULL;) {
 		rec = *list;
 
-		if (rec->refcount == 0) {
+		if (rec->refcount == 0 &&
+		    (all || rec->destroy_time <= ioloop_time)) {
 			rec->index->free(rec->index);
 			*list = rec->next;
 			i_free(rec);
@@ -114,6 +114,39 @@
 			list = &(*list)->next;
 		}
 	}
+
+	if (indexes == NULL && to_index != NULL) {
+		timeout_remove(to_index);
+		to_index = NULL;
+	}
+}
+
+static void index_removal_timeout(void *context __attr_unused__)
+{
+	destroy_unrefed(FALSE);
+}
+
+void index_storage_unref(struct mail_index *index)
+{
+	struct index_list *list;
+
+	for (list = indexes; list != NULL; list = list->next) {
+		if (list->index == index)
+			break;
+	}
+
+	i_assert(list != NULL);
+	i_assert(list->refcount > 0);
+
+	list->refcount--;
+	list->destroy_time = ioloop_time + INDEX_CACHE_TIMEOUT;
+	if (to_index == NULL)
+		to_index = timeout_add(1000, index_removal_timeout, NULL);
+}
+
+void index_storage_destroy_unrefed(void)
+{
+	destroy_unrefed(TRUE);
 }
 
 static enum mail_data_field get_data_fields(const char *fields)
@@ -264,9 +297,9 @@
 }
 
 struct index_mailbox *
-index_storage_init(struct mail_storage *storage, struct mailbox *box,
-		   struct mail_index *index, const char *name,
-		   int readonly, int fast)
+index_storage_mailbox_init(struct mail_storage *storage, struct mailbox *box,
+			   struct mail_index *index, const char *name,
+			   int readonly, int fast)
 {
 	struct index_mailbox *ibox;
 	enum mail_index_open_flags flags;
@@ -327,11 +360,11 @@
 	} while (0);
 
 	mail_storage_set_index_error(ibox);
-	index_storage_close(&ibox->box);
+	index_storage_mailbox_free(&ibox->box);
 	return NULL;
 }
 
-int index_storage_close(struct mailbox *box)
+int index_storage_mailbox_free(struct mailbox *box)
 {
 	struct index_mailbox *ibox = (struct index_mailbox *) box;
 
--- a/src/lib-storage/index/index-storage.h	Sun Jul 06 22:28:38 2003 +0300
+++ b/src/lib-storage/index/index-storage.h	Mon Jul 07 01:55:22 2003 +0300
@@ -46,11 +46,14 @@
 void index_storage_unref(struct mail_index *index);
 void index_storage_destroy_unrefed(void);
 
+void index_storage_init(struct mail_storage *storage);
+void index_storage_deinit(struct mail_storage *storage);
+
 struct index_mailbox *
-index_storage_init(struct mail_storage *storage, struct mailbox *box,
-		   struct mail_index *index, const char *name,
-		   int readonly, int fast);
-int index_storage_close(struct mailbox *box);
+index_storage_mailbox_init(struct mail_storage *storage, struct mailbox *box,
+			   struct mail_index *index, const char *name,
+			   int readonly, int fast);
+int index_storage_mailbox_free(struct mailbox *box);
 
 int index_storage_sync_and_lock(struct index_mailbox *ibox,
 				int sync_size, int minimal_sync,
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sun Jul 06 22:28:38 2003 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Jul 07 01:55:22 2003 +0300
@@ -86,11 +86,14 @@
 	storage->control_dir = i_strdup(home_expand(control_dir));
 	storage->user = i_strdup(user);
 	storage->callbacks = i_new(struct mail_storage_callbacks, 1);
+	index_storage_init(storage);
 	return storage;
 }
 
 static void maildir_free(struct mail_storage *storage)
 {
+	index_storage_deinit(storage);
+
 	i_free(storage->dir);
 	i_free(storage->inbox_file);
 	i_free(storage->index_dir);
@@ -334,8 +337,8 @@
 		index_storage_add(index);
 	}
 
-	ibox = index_storage_init(storage, &maildir_mailbox, index, name,
-				  readonly, fast);
+	ibox = index_storage_mailbox_init(storage, &maildir_mailbox,
+					  index, name, readonly, fast);
 	if (ibox != NULL)
 		ibox->expunge_locked = maildir_expunge_locked;
 	return (struct mailbox *) ibox;
@@ -674,7 +677,7 @@
 	}
 	ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
 
-	return index_storage_close(box) && !failed;
+	return index_storage_mailbox_free(box) && !failed;
 }
 
 static void maildir_storage_auto_sync(struct mailbox *box,
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Jul 06 22:28:38 2003 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Mon Jul 07 01:55:22 2003 +0300
@@ -343,8 +343,8 @@
 		index_storage_add(index);
 	}
 
-	ibox = index_storage_init(storage, &mbox_mailbox, index,
-				  name, readonly, fast);
+	ibox = index_storage_mailbox_init(storage, &mbox_mailbox, index,
+					  name, readonly, fast);
 	if (ibox != NULL)
 		ibox->expunge_locked = mbox_expunge_locked;
 	return (struct mailbox *) ibox;
@@ -688,7 +688,7 @@
 	}
 	ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL);
 
-	return index_storage_close(box) && !failed;
+	return index_storage_mailbox_free(box) && !failed;
 }
 
 static void mbox_storage_auto_sync(struct mailbox *box,