Esempio n. 1
0
void mail_cache_lookup_iter_init(struct mail_cache_view *view, uint32_t seq,
				 struct mail_cache_lookup_iterate_ctx *ctx_r)
{
	struct mail_cache_lookup_iterate_ctx *ctx = ctx_r;
	int ret;

	if (!view->cache->opened)
		(void)mail_cache_open_and_verify(view->cache);

	memset(ctx, 0, sizeof(*ctx));
	ctx->view = view;
	ctx->seq = seq;

	if (!MAIL_CACHE_IS_UNUSABLE(view->cache)) {
		/* look up the first offset */
		ret = mail_cache_lookup_offset(view->cache, view->view, seq,
					       &ctx->offset);
		if (ret <= 0) {
			ctx->stop = TRUE;
			ctx->failed = ret < 0;
		}
	}
	ctx->remap_counter = view->cache->remap_counter;

	memset(&view->loop_track, 0, sizeof(view->loop_track));
}
Esempio n. 2
0
static int
mail_cache_lookup_iter_next_record(struct mail_cache_lookup_iterate_ctx *ctx)
{
	struct mail_cache_view *view = ctx->view;

	if (ctx->failed)
		return -1;

	if (ctx->rec != NULL)
		ctx->offset = ctx->rec->prev_offset;
	if (ctx->offset == 0) {
		/* end of this record list. check newly appended data. */
		if (view->trans_seq1 > ctx->seq ||
		    view->trans_seq2 < ctx->seq)
			return 0;
		/* check data still in memory. this works for recent mails
		   even with INDEX=MEMORY */
		if (!ctx->memory_appends_checked) {
			if (mail_cache_lookup_iter_transaction(ctx))
				return 1;
			ctx->memory_appends_checked = TRUE;
		}
		if (MAIL_CACHE_IS_UNUSABLE(view->cache))
			return 0;

		/* check data already written to cache file */
		if (ctx->disk_appends_checked ||
		    mail_cache_lookup_offset(view->cache, view->trans_view,
					     ctx->seq, &ctx->offset) <= 0)
			return 0;

		ctx->disk_appends_checked = TRUE;
		ctx->remap_counter = view->cache->remap_counter;
		memset(&view->loop_track, 0, sizeof(view->loop_track));
	}

	if (ctx->stop)
		return 0;

	/* look up the next record */
	if (mail_cache_get_record(view->cache, ctx->offset, &ctx->rec) < 0)
		return -1;
	if (mail_cache_track_loops(&view->loop_track, ctx->offset,
				   ctx->rec->size)) {
		mail_cache_set_corrupted(view->cache,
					 "record list is circular");
		return -1;
	}
	ctx->remap_counter = view->cache->remap_counter;

	ctx->pos = sizeof(*ctx->rec);
	ctx->rec_size = ctx->rec->size;
	return 1;
}