static void destroy_unrefed(bool all)
{
	struct mail_index_alloc_cache_list **list, *rec;
	bool seen_ref0 = FALSE;

	for (list = &indexes; *list != NULL;) {
		rec = *list;

		if (rec->refcount == 0 &&
		    (all || rec->destroy_time <= ioloop_time)) {
			*list = rec->next;
			mail_index_alloc_cache_list_free(rec);
		} else {
			if (rec->refcount == 0)
				seen_ref0 = TRUE;
			if (all && rec->index->open_count == 1 &&
			    rec->referenced) {
				/* we're the only one keeping this index open.
				   we might be here, because the caller is
				   deleting this mailbox and wants its indexes
				   to be closed. so close it. */
				rec->referenced = FALSE;
				mail_index_close(rec->index);
			}
			list = &(*list)->next;
		}
	}

	if (!seen_ref0 && to_index != NULL)
		timeout_remove(&to_index);
}
static struct mail_index_alloc_cache_list *
mail_index_alloc_cache_find(const char *mailbox_path, const char *index_dir,
			    const struct stat *index_st)
{
	struct mail_index_alloc_cache_list **indexp, *rec, *match;
	unsigned int destroy_count;
	struct stat st;

	destroy_count = 0; match = NULL;
	for (indexp = &indexes; *indexp != NULL;) {
		rec = *indexp;

		if (match != NULL) {
			/* already found the index. we're just going through
			   the rest of them to drop 0 refcounts */
		} else if (rec->refcount == 0 && rec->index->open_count == 0) {
			/* index is already closed. don't even try to
			   reuse it. */
		} else if (index_dir != NULL && rec->index_dir_ino != 0) {
			if (index_st->st_ino == rec->index_dir_ino &&
			    CMP_DEV_T(index_st->st_dev, rec->index_dir_dev)) {
				/* make sure the directory still exists.
				   it might have been renamed and we're trying
				   to access it via its new path now. */
				if (stat(rec->index->dir, &st) < 0 ||
				    st.st_ino != index_st->st_ino ||
				    !CMP_DEV_T(st.st_dev, index_st->st_dev))
					rec->destroy_time = 0;
				else
					match = rec;
			}
		} else if (mailbox_path != NULL && rec->mailbox_path != NULL &&
			   index_dir == NULL && rec->index_dir_ino == 0) {
			if (strcmp(mailbox_path, rec->mailbox_path) == 0)
				match = rec;
		}

		if (rec->refcount == 0 && rec != match) {
			if (rec->destroy_time <= ioloop_time ||
			    destroy_count >= INDEX_CACHE_MAX) {
				*indexp = rec->next;
				mail_index_alloc_cache_list_free(rec);
				continue;
			} else {
				destroy_count++;
			}
		}

                indexp = &(*indexp)->next;
	}
	return match;
}
static void destroy_unrefed(bool all)
{
	struct mail_index_alloc_cache_list **list, *rec;
	bool seen_ref0 = FALSE;

	for (list = &indexes; *list != NULL;) {
		rec = *list;

		if (rec->refcount == 0 &&
		    (all || rec->destroy_time <= ioloop_time)) {
			*list = rec->next;
			mail_index_alloc_cache_list_free(rec);
		} else {
			if (rec->refcount == 0)
				seen_ref0 = TRUE;
			list = &(*list)->next;
		}
	}

	if (!seen_ref0 && to_index != NULL)
		timeout_remove(&to_index);
}