Skip to content

Commit

Permalink
Removed cache_offset from mail_index_record and changed it to use ext…
Browse files Browse the repository at this point in the history
…ension

instead. Added possibility to register sync and expunge handlers for
extensions. Changed the way extension resets work: all extension updates
which were committed without having seen the reset are ignored.

--HG--
branch : HEAD
  • Loading branch information
sirainen committed Nov 6, 2004
1 parent 36aa869 commit 6a19e10
Show file tree
Hide file tree
Showing 23 changed files with 857 additions and 494 deletions.
1 change: 1 addition & 0 deletions src/lib-index/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ libindex_a_SOURCES = \
mail-cache-fields.c \
mail-cache-lookup.c \
mail-cache-transaction.c \
mail-cache-sync-update.c \
mail-index.c \
mail-index-fsck.c \
mail-index-lock.c \
Expand Down
22 changes: 16 additions & 6 deletions src/lib-index/mail-cache-compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ mail_cache_compress_callback(struct mail_cache_view *view, uint32_t field,
return 1;
}

static uint32_t
get_next_file_seq(struct mail_cache *cache, struct mail_index_view *view)
{
const struct mail_index_ext *ext;
uint32_t file_seq;

ext = mail_index_view_get_ext(view, cache->ext_id);
file_seq = ext != NULL ? ext->reset_id + 1 : (uint32_t)ioloop_time;
return file_seq != 0 ? file_seq : 1;
}

static int
mail_cache_copy(struct mail_cache *cache, struct mail_index_view *view, int fd)
{
Expand Down Expand Up @@ -131,15 +142,15 @@ mail_cache_copy(struct mail_cache *cache, struct mail_index_view *view, int fd)
memset(&hdr, 0, sizeof(hdr));
hdr.version = MAIL_CACHE_VERSION;
hdr.indexid = idx_hdr->indexid;
hdr.file_seq = idx_hdr->cache_file_seq + 1;
hdr.file_seq = get_next_file_seq(cache, view);
o_stream_send(output, &hdr, sizeof(hdr));

memset(&ctx, 0, sizeof(ctx));
ctx.buffer = buffer_create_dynamic(default_pool, 4096);
ctx.field_seen = buffer_create_dynamic(default_pool, 64);
ctx.field_seen_value = 0;

mail_index_reset_cache(t, hdr.file_seq);
mail_index_ext_reset(t, cache->ext_id, hdr.file_seq);

for (seq = 1; seq <= message_count; seq++) {
ctx.new_msg = seq >= first_new_seq;
Expand All @@ -161,12 +172,11 @@ mail_cache_copy(struct mail_cache *cache, struct mail_index_view *view, int fd)
if (cache_rec.size == sizeof(cache_rec))
continue;

mail_index_update_cache(t, seq, hdr.file_seq,
output->offset, &old_offset);
mail_index_update_ext(t, seq, cache->ext_id, &output->offset,
&old_offset);

buffer_write(ctx.buffer, 0, &cache_rec, sizeof(cache_rec));
o_stream_send(output, buffer_get_data(ctx.buffer, NULL),
cache_rec.size);
o_stream_send(output, ctx.buffer->data, cache_rec.size);
}

if (cache->fields_count != 0) {
Expand Down
38 changes: 27 additions & 11 deletions src/lib-index/mail-cache-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,37 @@ mail_cache_get_record(struct mail_cache *cache, uint32_t offset)
return cache_rec;
}

static int mail_cache_lookup_offset(struct mail_cache_view *view, uint32_t seq,
uint32_t *offset_r)
static int
mail_cache_lookup_offset(struct mail_cache *cache, struct mail_index_view *view,
uint32_t seq, uint32_t *offset_r)
{
const struct mail_index_record *rec;
struct mail_index_map *map;
const struct mail_index_ext *ext;
const void *data;
uint32_t idx;
int i, ret;

for (i = 0; i < 2; i++) {
if (mail_index_lookup_full(view->view, seq, &map, &rec) < 0)
return -1;
if (mail_index_lookup_ext_full(view, seq, cache->ext_id,
&map, &data) < 0)
return -1;
if (data == NULL)
return 0;

if (map->hdr->cache_file_seq == view->cache->hdr->file_seq) {
*offset_r = rec->cache_offset;
if (!mail_index_map_get_ext_idx(map, cache->ext_id, &idx)) {
/* no cache */
return 0;
}

ext = map->extensions->data;
ext += idx;

for (i = 0; i < 2; i++) {
if (cache->hdr->file_seq == ext->reset_id) {
*offset_r = *((const uint32_t *)data);
return 1;
}

if ((ret = mail_cache_reopen(view->cache)) <= 0)
if ((ret = mail_cache_reopen(cache)) <= 0)
return ret;
}

Expand Down Expand Up @@ -170,7 +184,8 @@ int mail_cache_foreach(struct mail_cache_view *view, uint32_t seq,
if (view->cached_offset_seq == seq)
offset = view->cached_offset;
else {
if ((ret = mail_cache_lookup_offset(view, seq, &offset)) <= 0)
if ((ret = mail_cache_lookup_offset(view->cache, view->view,
seq, &offset)) <= 0)
return ret;

view->cached_offset_seq = seq;
Expand All @@ -191,7 +206,8 @@ int mail_cache_foreach(struct mail_cache_view *view, uint32_t seq,
}

if (ret > 0 && view->trans_seq1 <= seq && view->trans_seq2 >= seq &&
mail_cache_transaction_lookup(view->transaction, seq, &offset)) {
mail_cache_lookup_offset(view->cache, view->trans_view,
seq, &offset)) {
buffer_set_used_size(view->offsets_buf, 0);
while (offset != 0 && ret > 0) {
if (buffer_find_offset(view->offsets_buf, offset)) {
Expand Down
12 changes: 8 additions & 4 deletions src/lib-index/mail-cache-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct mail_cache_field_private {

struct mail_cache {
struct mail_index *index;
uint32_t ext_id;

char *filepath;
int fd;
Expand Down Expand Up @@ -142,7 +143,7 @@ struct mail_cache {

struct mail_cache_view {
struct mail_cache *cache;
struct mail_index_view *view;
struct mail_index_view *view, *trans_view;

struct mail_cache_transaction_ctx *transaction;
uint32_t trans_seq1, trans_seq2;
Expand Down Expand Up @@ -183,9 +184,6 @@ int mail_cache_foreach(struct mail_cache_view *view, uint32_t seq,
int mail_cache_transaction_commit(struct mail_cache_transaction_ctx *ctx);
void mail_cache_transaction_rollback(struct mail_cache_transaction_ctx *ctx);

int mail_cache_transaction_lookup(struct mail_cache_transaction_ctx *ctx,
uint32_t seq, uint32_t *offset_r);

int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size);
void mail_cache_file_close(struct mail_cache *cache);
int mail_cache_reopen(struct mail_cache *cache);
Expand All @@ -201,6 +199,12 @@ void mail_cache_decision_lookup(struct mail_cache_view *view, uint32_t seq,
void mail_cache_decision_add(struct mail_cache_view *view, uint32_t seq,
uint32_t field);

int mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq, const void *data, void **context);
int mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq, void *old_data, const void *new_data,
void **context);

void mail_cache_set_syscall_error(struct mail_cache *cache,
const char *function);

Expand Down
133 changes: 133 additions & 0 deletions src/lib-index/mail-cache-sync-update.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* Copyright (C) 2004 Timo Sirainen */

#include "lib.h"
#include "mail-cache-private.h"
#include "mail-index-view-private.h"
#include "mail-index-sync-private.h"

struct mail_cache_sync_context {
unsigned int locked:1;
unsigned int lock_failed:1;
};

static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
struct mail_cache_sync_context *ctx)
{
if (ctx == NULL)
return;

if (ctx->locked)
mail_cache_unlock(sync_ctx->view->index->cache);
i_free(ctx);
}

static int mail_cache_handler_init(struct mail_cache_sync_context **ctx_r,
struct mail_cache *cache)
{
struct mail_cache_sync_context *ctx = *ctx_r;
int ret;

if (ctx == NULL)
ctx = *ctx_r = i_new(struct mail_cache_sync_context, 1);

if (ctx->locked || ctx->lock_failed)
return 1;

if (!ctx->locked) {
if ((ret = mail_cache_lock(cache)) <= 0) {
ctx->lock_failed = TRUE;
return ret;
}
ctx->locked = TRUE;
}
return 1;
}

static int get_cache_file_seq(struct mail_index_view *view,
uint32_t *cache_file_seq_r)
{
const struct mail_index_ext *ext;

ext = mail_index_view_get_ext(view, view->index->cache->ext_id);
if (ext == NULL)
return 0;

*cache_file_seq_r = ext->reset_id;
return 1;
}

int mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq __attr_unused__,
const void *data, void **context)
{
struct mail_index_view *view = sync_ctx->view;
struct mail_cache_sync_context *ctx = *context;
struct mail_cache *cache = view->index->cache;
const uint32_t *cache_offset = data;
uint32_t cache_file_seq;
int ret;

if (data == NULL) {
mail_cache_handler_deinit(sync_ctx, ctx);
*context = NULL;
return 1;
}

if (*cache_offset == 0)
return 1;

ret = mail_cache_handler_init(&ctx, cache);
*context = ctx;
if (ret <= 0)
return ret < 0 ? -1 : 1;

if (!get_cache_file_seq(view, &cache_file_seq))
return 1;

if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
cache_file_seq != cache->hdr->file_seq)
(void)mail_cache_delete(cache, *cache_offset);
return 1;
}

int mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq __attr_unused__,
void *old_data, const void *new_data,
void **context)
{
struct mail_index_view *view = sync_ctx->view;
struct mail_cache_sync_context *ctx = *context;
const uint32_t *old_cache_offset = old_data;
const uint32_t *new_cache_offset = new_data;
uint32_t cache_file_seq;
int ret;

if (new_cache_offset == NULL) {
mail_cache_handler_deinit(sync_ctx, ctx);
*context = NULL;
return 1;
}

if (*old_cache_offset == 0)
return 1;

/* we'll need to link the old and new cache records */
ret = mail_cache_handler_init(&ctx, view->index->cache);
*context = ctx;
if (ret <= 0)
return ret < 0 ? -1 : 1;

if (!get_cache_file_seq(view, &cache_file_seq))
return 1;

if (cache_file_seq != view->index->cache->hdr->file_seq) {
/* cache has been compressed, don't modify it */
return 1;
}

if (mail_cache_link(view->index->cache,
*old_cache_offset, *new_cache_offset) < 0)
return -1;

return 1;
}
13 changes: 4 additions & 9 deletions src/lib-index/mail-cache-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ mail_cache_get_transaction(struct mail_cache_view *view,

i_assert(view->transaction == NULL);
view->transaction = ctx;
view->trans_view = mail_index_transaction_open_updated_view(t);

t->cache_trans_ctx = ctx;
return ctx;
Expand Down Expand Up @@ -436,9 +437,9 @@ mail_cache_transaction_flush(struct mail_cache_transaction_ctx *ctx)
is updated to point to old cache record when index is being
synced. */
for (; seq_idx < seq_limit; seq_idx++) {
mail_index_update_cache(ctx->trans, seq[seq_idx],
cache->hdr->file_seq,
write_offset, &old_offset);
mail_index_update_ext(ctx->trans, seq[seq_idx],
cache->ext_id, &write_offset,
&old_offset);
if (old_offset != 0) {
/* we added records for this message multiple
times in this same uncommitted transaction.
Expand Down Expand Up @@ -689,12 +690,6 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
buffer_append(ctx->cache_data, null4, 4 - (data_size & 3));
}

int mail_cache_transaction_lookup(struct mail_cache_transaction_ctx *ctx,
uint32_t seq, uint32_t *offset_r)
{
return mail_index_update_cache_lookup(ctx->trans, seq, offset_r);
}

static int mail_cache_link_unlocked(struct mail_cache *cache,
uint32_t old_offset, uint32_t new_offset)
{
Expand Down

0 comments on commit 6a19e10

Please sign in to comment.