[dovecot-cvs] dovecot/src/lib-index mail-index-fsck.c, 1.22,
1.23 mail-index-lock.c, 1.22, 1.23 mail-index-private.h, 1.21,
1.22 mail-index-sync-private.h, 1.8,
1.9 mail-index-sync-update.c, 1.29, 1.30 mail-index-sync.c,
1.23, 1.24 mail-index-transaction-private.h, 1.6,
1.7 mail-index-transaction-view.c, 1.1,
1.2 mail-index-transaction.c, 1.14,
1.15 mail-index-view-sync.c, 1.13, 1.14 mail-index-view.c,
1.17, 1.18 mail-index.c, 1.136, 1.137 mail-index.h, 1.119,
1.120 mail-transaction-log.c, 1.41,
1.42 mail-transaction-log.h, 1.13,
1.14 mail-transaction-util.c, 1.13,
1.14 mail-transaction-util.h, 1.7, 1.8
cras at procontrol.fi
cras at procontrol.fi
Thu Jun 24 14:10:44 EEST 2004
Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv3603/lib-index
Modified Files:
mail-index-fsck.c mail-index-lock.c mail-index-private.h
mail-index-sync-private.h mail-index-sync-update.c
mail-index-sync.c mail-index-transaction-private.h
mail-index-transaction-view.c mail-index-transaction.c
mail-index-view-sync.c mail-index-view.c mail-index.c
mail-index.h mail-transaction-log.c mail-transaction-log.h
mail-transaction-util.c mail-transaction-util.h
Log Message:
Record size is allowed to change between index files. This will allow adding
extensions dynamically for existing indexes.
Index: mail-index-fsck.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-fsck.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mail-index-fsck.c 13 Jun 2004 23:38:47 -0000 1.22
+++ mail-index-fsck.c 24 Jun 2004 11:10:41 -0000 1.23
@@ -75,7 +75,7 @@
hdr.first_deleted_uid_lowwater = rec->uid;
last_uid = rec->uid;
- rec = CONST_PTR_OFFSET(rec, index->record_size);
+ rec = CONST_PTR_OFFSET(rec, hdr.record_size);
}
if (hdr.next_uid <= last_uid) {
@@ -100,7 +100,7 @@
CHECK(first_unseen_uid_lowwater, <);
CHECK(first_deleted_uid_lowwater, <);
- if (mail_index_write_header(index, &hdr) < 0)
+ if (mail_index_write_base_header(index, &hdr) < 0)
return -1;
return 1;
Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mail-index-lock.c 20 Jun 2004 13:14:17 -0000 1.22
+++ mail-index-lock.c 24 Jun 2004 11:10:41 -0000 1.23
@@ -187,7 +187,7 @@
ret = write_full(fd, index->map->hdr, sizeof(*index->map->hdr));
if (ret < 0 || write_full(fd, index->map->records,
index->map->records_count *
- index->record_size) < 0) {
+ index->map->hdr->record_size) < 0) {
mail_index_file_set_syscall_error(index, path, "write_full()");
(void)close(fd);
(void)unlink(path);
Index: mail-index-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- mail-index-private.h 20 Jun 2004 09:13:14 -0000 1.21
+++ mail-index-private.h 24 Jun 2004 11:10:41 -0000 1.22
@@ -22,9 +22,15 @@
#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
((map)->buffer != NULL)
-#define MAIL_INDEX_MAP_IDX(index, map, idx) \
+#define MAIL_INDEX_MAP_IDX(map, idx) \
((struct mail_index_record *) \
- PTR_OFFSET((map)->records, (idx) * (index)->record_size))
+ PTR_OFFSET((map)->records, (idx) * (map)->hdr->record_size))
+
+struct mail_index_extra_record_info {
+ const char *name;
+ uint16_t offset;
+ uint16_t size;
+};
struct mail_index_map {
int refcount;
@@ -33,6 +39,9 @@
void *records; /* struct mail_index_record[] */
unsigned int records_count;
+ struct mail_index_extra_record_info *
+ extra_record_map[MAIL_INDEX_MAX_EXTRA_RECORDS];
+
void *mmap_base;
size_t mmap_size, mmap_used_size;
@@ -46,12 +55,6 @@
unsigned int write_to_disk:1;
};
-struct mail_index_extra_record_info {
- const char *name;
- uint16_t offset;
- uint16_t size;
-};
-
struct mail_index {
char *dir, *prefix;
@@ -65,8 +68,7 @@
buffer_t *extra_records_buf;
const struct mail_index_extra_record_info *extra_records;
unsigned int extra_records_count;
-
- unsigned int record_size;
+ unsigned int max_record_size;
char *filepath;
int fd;
@@ -95,8 +97,8 @@
unsigned int fsck:1;
};
-int mail_index_write_header(struct mail_index *index,
- const struct mail_index_header *hdr);
+int mail_index_write_base_header(struct mail_index *index,
+ const struct mail_index_header *hdr);
int mail_index_reopen(struct mail_index *index, int fd);
int mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
@@ -122,7 +124,7 @@
/* Unreference given mapping and unmap it if it's dropped to zero. */
void mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
struct mail_index_map *
-mail_index_map_to_memory(struct mail_index *index, struct mail_index_map *map);
+mail_index_map_to_memory(struct mail_index_map *map, uint32_t new_record_size);
int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
struct mail_index_map **map_r,
Index: mail-index-sync-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mail-index-sync-private.h 30 May 2004 04:32:36 -0000 1.8
+++ mail-index-sync-private.h 24 Jun 2004 11:10:41 -0000 1.9
@@ -5,12 +5,14 @@
struct mail_index *index;
struct mail_index_view *view;
- buffer_t *expunges_buf, *updates_buf, *appends_buf;
+ buffer_t *expunges_buf, *updates_buf;
const struct mail_transaction_expunge *expunges;
const struct mail_transaction_flag_update *updates;
size_t expunges_count, updates_count;
+ uint32_t append_uid_first, append_uid_last;
+
const struct mail_transaction_header *hdr;
const void *data;
Index: mail-index-sync-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- mail-index-sync-update.c 20 Jun 2004 13:02:08 -0000 1.29
+++ mail-index-sync-update.c 24 Jun 2004 11:10:41 -0000 1.30
@@ -56,7 +56,6 @@
static int sync_expunge(const struct mail_transaction_expunge *e, void *context)
{
struct mail_index_view *view = context;
- struct mail_index *index = view->index;
struct mail_index_map *map = view->map;
struct mail_index_header *hdr = &map->hdr_copy;
struct mail_index_record *rec;
@@ -72,15 +71,14 @@
return 1;
for (seq = seq1; seq <= seq2; seq++) {
- rec = MAIL_INDEX_MAP_IDX(index, map, seq-1);
+ rec = MAIL_INDEX_MAP_IDX(map, seq-1);
mail_index_header_update_counts(hdr, rec->flags, 0);
}
/* @UNSAFE */
count = seq2 - seq1 + 1;
- memmove(MAIL_INDEX_MAP_IDX(index, map, seq1-1),
- MAIL_INDEX_MAP_IDX(index, map, seq2),
- (map->records_count - seq2) * view->index->record_size);
+ memmove(MAIL_INDEX_MAP_IDX(map, seq1-1), MAIL_INDEX_MAP_IDX(map, seq2),
+ (map->records_count - seq2) * map->hdr->record_size);
map->records_count -= count;
hdr->messages_count -= count;
@@ -88,17 +86,20 @@
if (map->buffer != NULL) {
buffer_set_used_size(map->buffer, map->records_count *
- view->index->record_size);
+ map->hdr->record_size);
map->records = buffer_get_modifyable_data(map->buffer, NULL);
}
return 1;
}
-static int sync_append(const struct mail_index_record *rec, void *context)
+static int sync_append(const struct mail_transaction_append_header *hdr,
+ const struct mail_index_record *rec, void *context)
{
struct mail_index_view *view = context;
- struct mail_index *index = view->index;
struct mail_index_map *map = view->map;
+ void *dest;
+
+ i_assert(hdr->record_size <= map->hdr->record_size);
if (rec->uid < map->hdr_copy.next_uid) {
mail_transaction_log_view_set_corrupted(view->log_view,
@@ -108,16 +109,19 @@
}
if (MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
- i_assert(map->records_count * index->record_size ==
+ i_assert(map->records_count * map->hdr->record_size ==
buffer_get_used_size(map->buffer));
- buffer_append(map->buffer, rec, index->record_size);
+ dest = buffer_append_space_unsafe(map->buffer,
+ map->hdr->record_size);
map->records = buffer_get_modifyable_data(map->buffer, NULL);
} else {
- i_assert((map->records_count+1) * index->record_size <=
+ i_assert((map->records_count+1) * map->hdr->record_size <=
map->mmap_size);
- memcpy(MAIL_INDEX_MAP_IDX(index, map, map->records_count),
- rec, index->record_size);
+ dest = MAIL_INDEX_MAP_IDX(map, map->records_count);
}
+ memcpy(dest, rec, hdr->record_size);
+ memset(PTR_OFFSET(dest, hdr->record_size), 0,
+ map->hdr->record_size - hdr->record_size);
map->hdr_copy.messages_count++;
map->hdr_copy.next_uid = rec->uid+1;
@@ -161,7 +165,7 @@
flag_mask = ~u->remove_flags;
for (idx = seq1-1; idx < seq2; idx++) {
- rec = MAIL_INDEX_MAP_IDX(view->index, view->map, idx);
+ rec = MAIL_INDEX_MAP_IDX(view->map, idx);
old_flags = rec->flags;
rec->flags = (rec->flags & flag_mask) | u->add_flags;
@@ -187,7 +191,7 @@
view->map->hdr_copy.cache_file_seq = u->new_file_seq;
for (i = 0; i < view->messages_count; i++)
- MAIL_INDEX_MAP_IDX(view->index, view->map, i)->cache_offset = 0;
+ MAIL_INDEX_MAP_IDX(view->map, i)->cache_offset = 0;
return 1;
}
@@ -203,8 +207,8 @@
i_assert(ret == 0);
if (seq != 0) {
- MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1)->
- cache_offset = u->cache_offset;
+ MAIL_INDEX_MAP_IDX(view->map, seq-1)->cache_offset =
+ u->cache_offset;
}
return 1;
}
@@ -241,7 +245,7 @@
offset = view->index->extra_records[hdr->idx].offset;
size = view->index->extra_records[hdr->idx].size;
- rec = MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1);
+ rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
memcpy(PTR_OFFSET(rec, offset), u->data, size);
}
return 1;
@@ -259,7 +263,7 @@
i_assert(map == index->map);
size = map->hdr->header_size +
- (map->records_count + count) * index->record_size;
+ (map->records_count + count) * map->hdr->record_size;
if (size <= map->mmap_size)
return 0;
@@ -271,7 +275,7 @@
index->last_grow_count = count;
size = map->hdr->header_size +
- (map->records_count + count) * index->record_size;
+ (map->records_count + count) * map->hdr->record_size;
if (file_set_size(index->fd, (off_t)size) < 0)
return mail_index_set_syscall_error(index, "file_set_size()");
@@ -290,6 +294,18 @@
return 0;
}
+static void mail_index_sync_replace_map(struct mail_index_view *view,
+ struct mail_index_map *map)
+{
+ mail_index_unmap(view->index, view->map);
+ view->map = map;
+ view->map->refcount++;
+ mail_index_unmap(view->index, view->index->map);
+ view->index->map = map;
+ view->index->hdr = map->hdr;
+ map->write_to_disk = TRUE;
+}
+
int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
{
struct mail_index *index = sync_ctx->index;
@@ -335,18 +351,23 @@
replace the whole index file. to avoid extra disk
I/O we copy the index into memory rather than to
temporary file */
- map = mail_index_map_to_memory(index, map);
- mail_index_unmap(index, view->map);
- view->map = map;
- view->map->refcount++;
- mail_index_unmap(index, index->map);
- index->map = map;
- index->hdr = map->hdr;
- map->write_to_disk = TRUE;
+ map = mail_index_map_to_memory(map,
+ map->hdr->record_size);
+ mail_index_sync_replace_map(view, map);
}
if ((hdr->type & MAIL_TRANSACTION_APPEND) != 0) {
- count = hdr->size / index->record_size;
+ const struct mail_transaction_append_header *append_hdr;
+
+ append_hdr = data;
+ if (append_hdr->record_size > map->hdr->record_size) {
+ /* we have to grow our record size */
+ map = mail_index_map_to_memory(map,
+ append_hdr->record_size);
+ mail_index_sync_replace_map(view, map);
+ }
+ count = (hdr->size - sizeof(*append_hdr)) /
+ append_hdr->record_size;
if (mail_index_grow(index, view->map, count) < 0) {
ret = -1;
break;
@@ -381,7 +402,7 @@
const struct mail_index_record *rec;
for (i = 0; i < map->records_count; i++) {
- rec = MAIL_INDEX_MAP_IDX(index, map, i);
+ rec = MAIL_INDEX_MAP_IDX(map, i);
if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
map->hdr_copy.flags |=
MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
@@ -392,7 +413,7 @@
if (!MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
map->mmap_used_size = index->hdr->header_size +
- map->records_count * index->record_size;
+ map->records_count * map->hdr->record_size;
memcpy(map->mmap_base, &map->hdr_copy, sizeof(map->hdr_copy));
if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
Index: mail-index-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-sync.c 21 Jun 2004 14:44:47 -0000 1.23
+++ mail-index-sync.c 24 Jun 2004 11:10:41 -0000 1.24
@@ -80,11 +80,23 @@
mail_index_sync_sort_flags(ctx);
}
break;
- case MAIL_TRANSACTION_APPEND:
- buffer_append(ctx->appends_buf, ctx->data, ctx->hdr->size);
+ case MAIL_TRANSACTION_APPEND: {
+ const struct mail_transaction_append_header *hdr = ctx->data;
+ const struct mail_index_record *rec = ctx->data;
+
+ if (ctx->append_uid_first == 0 ||
+ rec->uid < ctx->append_uid_first)
+ ctx->append_uid_first = rec->uid;
+
+ rec = CONST_PTR_OFFSET(ctx->data,
+ ctx->hdr->size - hdr->record_size);
+ if (rec->uid > ctx->append_uid_last)
+ ctx->append_uid_last = rec->uid;
+
ctx->sync_appends = TRUE;
break;
}
+ }
}
static int mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx)
@@ -172,8 +184,6 @@
1024, (size_t)-1);
ctx->updates_buf = buffer_create_dynamic(default_pool,
1024, (size_t)-1);
- ctx->appends_buf = buffer_create_dynamic(default_pool,
- 1024, (size_t)-1);
if (mail_index_sync_read_and_sort(ctx) < 0) {
mail_index_sync_end(ctx);
return -1;
@@ -304,12 +314,8 @@
if (ctx->sync_appends) {
ctx->sync_appends = FALSE;
sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
- sync_rec->appends = buffer_get_data(ctx->appends_buf,
- &sync_rec->appends_count);
- sync_rec->appends_count /= ctx->index->record_size;
- sync_rec->uid1 = sync_rec->appends[0].uid;
- sync_rec->uid2 =
- sync_rec->appends[sync_rec->appends_count-1].uid;
+ sync_rec->uid1 = ctx->append_uid_first;
+ sync_rec->uid2 = ctx->append_uid_last;
return 1;
}
@@ -355,8 +361,6 @@
buffer_free(ctx->expunges_buf);
if (ctx->updates_buf != NULL)
buffer_free(ctx->updates_buf);
- if (ctx->appends_buf != NULL)
- buffer_free(ctx->appends_buf);
i_free(ctx);
return ret;
}
Index: mail-index-transaction-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction-private.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mail-index-transaction-private.h 22 Jun 2004 07:36:33 -0000 1.6
+++ mail-index-transaction-private.h 24 Jun 2004 11:10:41 -0000 1.7
@@ -8,6 +8,7 @@
buffer_t *appends;
uint32_t first_new_seq, last_new_seq;
+ unsigned int append_record_size;
buffer_t *expunges;
Index: mail-index-transaction-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction-view.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mail-index-transaction-view.c 22 Jun 2004 07:36:33 -0000 1.1
+++ mail-index-transaction-view.c 24 Jun 2004 11:10:41 -0000 1.2
@@ -130,7 +130,7 @@
*seq_r = seq;
break;
}
- rec = CONST_PTR_OFFSET(rec, view->index->record_size);
+ rec = CONST_PTR_OFFSET(rec, view->index->max_record_size);
}
return 0;
Index: mail-index-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-transaction.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mail-index-transaction.c 22 Jun 2004 07:36:33 -0000 1.14
+++ mail-index-transaction.c 24 Jun 2004 11:10:41 -0000 1.15
@@ -70,12 +70,10 @@
seq = (uint32_t *)&data[i];
i_assert(seq[0] <= view->map->records_count);
- seq[0] = MAIL_INDEX_MAP_IDX(view->index, view->map,
- seq[0]-1)->uid;
+ seq[0] = MAIL_INDEX_MAP_IDX(view->map, seq[0]-1)->uid;
if (range) {
i_assert(seq[1] <= view->map->records_count);
- seq[1] = MAIL_INDEX_MAP_IDX(view->index, view->map,
- seq[1]-1)->uid;
+ seq[1] = MAIL_INDEX_MAP_IDX(view->map, seq[1]-1)->uid;
}
}
}
@@ -139,6 +137,40 @@
mail_index_transaction_free(t);
}
+static void
+mail_index_transaction_update_append_size(struct mail_index_transaction *t)
+{
+ buffer_t *new_buf;
+ unsigned int new_record_size;
+ const void *src;
+ void *dest;
+ size_t i, size;
+
+ new_record_size = t->view->index->max_record_size;
+ if (t->append_record_size == new_record_size)
+ return;
+
+ i_assert(t->append_record_size < new_record_size);
+
+ if (t->append_record_size != 0) {
+ /* resize the records in buffer */
+ src = buffer_get_data(t->appends, &size);
+ size /= t->append_record_size;
+
+ new_buf = buffer_create_dynamic(default_pool,
+ size * new_record_size,
+ (size_t)-1);
+ for (i = 0; i < size; i++) {
+ dest = buffer_append_space_unsafe(new_buf,
+ new_record_size);
+ memcpy(dest, src, t->append_record_size);
+ src = CONST_PTR_OFFSET(src, t->append_record_size);
+ }
+ }
+
+ t->append_record_size = new_record_size;
+}
+
struct mail_index_record *
mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq)
{
@@ -146,9 +178,10 @@
i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq);
- pos = (seq - t->first_new_seq) * t->view->index->record_size;
- return buffer_get_space_unsafe(t->appends, pos,
- t->view->index->record_size);
+ mail_index_transaction_update_append_size(t);
+
+ pos = (seq - t->first_new_seq) * t->append_record_size;
+ return buffer_get_space_unsafe(t->appends, pos, t->append_record_size);
}
void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
@@ -159,7 +192,9 @@
if (t->appends == NULL) {
t->appends = buffer_create_dynamic(default_pool,
4096, (size_t)-1);
+ t->append_record_size = t->view->index->max_record_size;
}
+ mail_index_transaction_update_append_size(t);
/* sequence number is visible only inside given view,
so let it generate it */
@@ -168,9 +203,8 @@
else
*seq_r = t->last_new_seq = t->first_new_seq;
- rec = buffer_append_space_unsafe(t->appends,
- t->view->index->record_size);
- memset(rec, 0, t->view->index->record_size);
+ rec = buffer_append_space_unsafe(t->appends, t->append_record_size);
+ memset(rec, 0, t->append_record_size);
rec->uid = uid;
}
Index: mail-index-view-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-index-view-sync.c 13 Jun 2004 23:38:47 -0000 1.13
+++ mail-index-view-sync.c 24 Jun 2004 11:10:41 -0000 1.14
@@ -125,7 +125,8 @@
if (view->map != view->index->map)
ctx->sync_map_update = TRUE;
- map = mail_index_map_to_memory(view->index, view->map);
+ map = mail_index_map_to_memory(view->map,
+ view->map->hdr->record_size);
mail_index_unmap(view->index, view->map);
view->map = map;
}
Index: mail-index-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- mail-index-view.c 22 Jun 2004 07:36:33 -0000 1.17
+++ mail-index-view.c 24 Jun 2004 11:10:41 -0000 1.18
@@ -178,7 +178,7 @@
if (mail_index_view_lock(view) < 0)
return -1;
- rec = MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1);
+ rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
if (view->map == view->index->map) {
*map_r = view->map;
*rec_r = rec;
@@ -203,7 +203,7 @@
do {
// FIXME: we could be skipping more by uid diff
seq--;
- n_rec = MAIL_INDEX_MAP_IDX(view->index, map, seq);
+ n_rec = MAIL_INDEX_MAP_IDX(map, seq);
if (n_rec->uid <= uid)
break;
} while (seq > 0);
@@ -225,7 +225,7 @@
if (mail_index_view_lock(view) < 0)
return -1;
- *uid_r = MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1)->uid;
+ *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
return 0;
}
@@ -239,7 +239,7 @@
i_assert(view->messages_count <= view->map->records_count);
rec_base = view->map->records;
- record_size = view->index->record_size;
+ record_size = view->map->hdr->record_size;
idx = left_idx = *left_idx_p;
right_idx = view->messages_count;
@@ -301,8 +301,7 @@
left_idx = 0;
*first_seq_r = mail_index_bsearch_uid(view, first_uid, &left_idx, 1);
if (*first_seq_r == 0 ||
- MAIL_INDEX_MAP_IDX(view->index, view->map, *first_seq_r-1)->uid >
- last_uid) {
+ MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
*first_seq_r = 0;
*last_seq_r = 0;
return 0;
@@ -351,7 +350,7 @@
}
for (; seq <= view->messages_count; seq++) {
- rec = MAIL_INDEX_MAP_IDX(view->index, view->map, seq-1);
+ rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
if ((rec->flags & flags_mask) == (uint8_t)flags) {
*seq_r = seq;
break;
Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.136
retrieving revision 1.137
diff -u -d -r1.136 -r1.137
--- mail-index.c 20 Jun 2004 12:23:27 -0000 1.136
+++ mail-index.c 24 Jun 2004 11:10:41 -0000 1.137
@@ -31,7 +31,7 @@
index->extra_records_buf =
buffer_create_dynamic(index->extra_records_pool,
64, (size_t)-1);
- index->record_size = sizeof(struct mail_index_record);
+ index->max_record_size = sizeof(struct mail_index_record);
index->mode = 0600;
index->gid = (gid_t)-1;
@@ -66,7 +66,7 @@
i_assert(size % 4 == 0);
i_assert(!index->opened);
- i_assert(index->record_size + size <= 65535);
+ i_assert(index->max_record_size + size <= 65535);
if (index->extra_records_count >= MAIL_INDEX_MAX_EXTRA_RECORDS) {
i_panic("Maximum extra record count reached, "
@@ -78,14 +78,14 @@
memset(&info, 0, sizeof(info));
info.name = p_strdup(index->extra_records_pool, name);
info.size = size;
- info.offset = index->record_size;
+ info.offset = index->max_record_size;
buffer_append(index->extra_records_buf, &info, sizeof(info));
index->extra_records =
buffer_get_data(index->extra_records_buf, &buf_size);
index->extra_records_count = buf_size / sizeof(info);
- index->record_size += size;
+ index->max_record_size += size;
return index->extra_records_count-1;
}
@@ -132,11 +132,11 @@
return -1;
}
- if (hdr->record_size != index->record_size) {
+ if (hdr->record_size < sizeof(struct mail_index_record)) {
mail_index_set_error(index, "Corrupted index file %s: "
- "record_size mismatch: %d != %d",
+ "record_size too small: %u < %"PRIuSIZE_T,
index->filepath, hdr->record_size,
- (int)index->record_size);
+ sizeof(struct mail_index_record));
return -1;
}
@@ -227,11 +227,11 @@
hdr = map->mmap_base;
map->hdr = hdr;
map->mmap_used_size = hdr->header_size +
- hdr->messages_count * index->record_size;
+ hdr->messages_count * hdr->record_size;
if (map->mmap_used_size > map->mmap_size) {
records_count = (map->mmap_size - hdr->header_size) /
- index->record_size;
+ hdr->record_size;
mail_index_set_error(index, "Corrupted index file %s: "
"messages_count too large (%u > %u)",
index->filepath, hdr->messages_count,
@@ -271,7 +271,7 @@
pos += ret;
}
if (ret >= 0 && pos >= MAIL_INDEX_HEADER_MIN_SIZE) {
- records_size = hdr.messages_count * index->record_size;
+ records_size = hdr.messages_count * hdr.record_size;
if (map->buffer == NULL) {
map->buffer = buffer_create_dynamic(default_pool,
@@ -367,7 +367,7 @@
return -1;
used_size = hdr->header_size +
- hdr->messages_count * index->record_size;
+ hdr->messages_count * hdr->record_size;
if (map->mmap_size >= used_size && !force) {
map->records_count = hdr->messages_count;
return 1;
@@ -410,27 +410,41 @@
}
struct mail_index_map *
-mail_index_map_to_memory(struct mail_index *index, struct mail_index_map *map)
+mail_index_map_to_memory(struct mail_index_map *map, uint32_t new_record_size)
{
struct mail_index_map *mem_map;
- size_t size;
+ void *src, *dest;
+ size_t size, copy_size;
+ unsigned int i;
if (MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
map->refcount++;
return map;
}
- size = map->records_count * index->record_size;
+ size = map->records_count * new_record_size;
mem_map = i_new(struct mail_index_map, 1);
mem_map->refcount = 1;
mem_map->buffer = buffer_create_dynamic(default_pool, size, (size_t)-1);
- buffer_append(mem_map->buffer, map->records, size);
+ if (map->hdr->record_size == new_record_size)
+ buffer_append(mem_map->buffer, map->records, size);
+ else {
+ copy_size = I_MIN(map->hdr->record_size, new_record_size);
+ src = map->records;
+ for (i = 0; i < map->records_count; i++) {
+ dest = buffer_append_space_unsafe(mem_map->buffer,
+ new_record_size);
+ memcpy(dest, src, copy_size);
+ src = PTR_OFFSET(src, map->hdr->record_size);
+ }
+ }
mem_map->records = buffer_get_modifyable_data(mem_map->buffer, NULL);
mem_map->records_count = map->records_count;
mem_map->hdr_copy = *map->hdr;
+ mem_map->hdr_copy.record_size = new_record_size;
mem_map->hdr = &mem_map->hdr_copy;
return mem_map;
}
@@ -497,15 +511,19 @@
return ret;
}
-int mail_index_write_header(struct mail_index *index,
- const struct mail_index_header *hdr)
+int mail_index_write_base_header(struct mail_index *index,
+ const struct mail_index_header *hdr)
{
+ size_t hdr_size;
+
+ hdr_size = I_MIN(sizeof(*hdr), hdr->base_header_size);
+
if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
- memcpy(index->map->mmap_base, hdr, sizeof(*hdr));
- if (msync(index->map->mmap_base, sizeof(*hdr), MS_SYNC) < 0)
+ memcpy(index->map->mmap_base, hdr, hdr_size);
+ if (msync(index->map->mmap_base, hdr_size, MS_SYNC) < 0)
return mail_index_set_syscall_error(index, "msync()");
} else {
- if (pwrite_full(index->fd, hdr, sizeof(*hdr), 0) < 0) {
+ if (pwrite_full(index->fd, hdr, hdr_size, 0) < 0) {
mail_index_set_syscall_error(index, "pwrite_full()");
return -1;
}
@@ -602,7 +620,7 @@
hdr->minor_version = MAIL_INDEX_MINOR_VERSION;
hdr->base_header_size = sizeof(*hdr);
hdr->header_size = sizeof(*hdr);
- hdr->record_size = index->record_size;
+ hdr->record_size = index->max_record_size;
hdr->keywords_mask_size = sizeof(keywords_mask_t);
#ifndef WORDS_BIGENDIAN
@@ -890,7 +908,7 @@
hdr = *index->hdr;
hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
- if (mail_index_write_header(index, &hdr) == 0) {
+ if (mail_index_write_base_header(index, &hdr) == 0) {
if (fsync(index->fd) < 0)
mail_index_set_syscall_error(index, "fsync()");
}
Index: mail-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -d -r1.119 -r1.120
--- mail-index.h 22 Jun 2004 07:36:33 -0000 1.119
+++ mail-index.h 24 Jun 2004 11:10:41 -0000 1.120
@@ -123,10 +123,6 @@
keywords_mask_t add_keywords;
uint8_t remove_flags;
keywords_mask_t remove_keywords;
-
- /* MAIL_INDEX_SYNC_TYPE_APPEND: */
- const struct mail_index_record *appends;
- size_t appends_count;
};
struct mail_index;
Index: mail-transaction-log.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- mail-transaction-log.c 20 Jun 2004 13:02:08 -0000 1.41
+++ mail-transaction-log.c 24 Jun 2004 11:10:41 -0000 1.42
@@ -874,6 +874,7 @@
struct mail_transaction_log_view *sync_view;
const struct mail_index_record *old, *old_end;
struct mail_index_record *appends, *end, *rec, *dest;
+ const struct mail_transaction_append_header *append_hdr;
const struct mail_transaction_header *hdr;
const void *data;
size_t size;
@@ -883,7 +884,7 @@
if (t->appends == NULL)
return 0;
- record_size = log->index->record_size;
+ record_size = t->append_record_size;
appends = buffer_get_modifyable_data(t->appends, &size);
end = PTR_OFFSET(appends, size);
@@ -905,8 +906,10 @@
MAIL_TRANSACTION_APPEND)
continue;
- old = data;
- old_end = CONST_PTR_OFFSET(old, hdr->size);
+ append_hdr = data;
+
+ old = CONST_PTR_OFFSET(data, sizeof(*append_hdr));
+ old_end = CONST_PTR_OFFSET(data, hdr->size);
while (old != old_end) {
/* appends are sorted */
for (rec = appends; rec != end; ) {
@@ -919,7 +922,7 @@
}
rec = PTR_OFFSET(rec, record_size);
}
- old = CONST_PTR_OFFSET(old, record_size);
+ old = CONST_PTR_OFFSET(old, append_hdr->record_size);
}
}
@@ -1097,7 +1100,15 @@
ret = 0;
if (t->appends != NULL) {
- ret = log_append_buffer(file, t->appends, NULL,
+ struct mail_transaction_append_header hdr;
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.record_size = t->append_record_size;
+
+ hdr_buf = buffer_create_data(pool_datastack_create(),
+ &hdr, sizeof(hdr));
+ buffer_set_used_size(hdr_buf, sizeof(hdr));
+ ret = log_append_buffer(file, t->appends, hdr_buf,
MAIL_TRANSACTION_APPEND,
view->external);
}
Index: mail-transaction-log.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-log.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-transaction-log.h 20 Jun 2004 09:13:14 -0000 1.13
+++ mail-transaction-log.h 24 Jun 2004 11:10:41 -0000 1.14
@@ -75,6 +75,10 @@
unsigned char data[1]; /* variable size */
};
+struct mail_transaction_append_header {
+ uint32_t record_size;
+};
+
struct mail_transaction_log *
mail_transaction_log_open_or_create(struct mail_index *index);
void mail_transaction_log_close(struct mail_transaction_log *log);
Index: mail-transaction-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-util.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-transaction-util.c 20 Jun 2004 09:13:14 -0000 1.13
+++ mail-transaction-util.c 24 Jun 2004 11:10:41 -0000 1.14
@@ -60,23 +60,23 @@
struct mail_transaction_map_functions *map,
void *context)
{
-
int ret = 0;
switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
case MAIL_TRANSACTION_APPEND: {
+ const struct mail_transaction_append_header *append_hdr = data;
const struct mail_index_record *rec, *end;
- uint32_t record_size = index->record_size;
if (map->append == NULL)
break;
+ rec = CONST_PTR_OFFSET(data, sizeof(*append_hdr));
end = CONST_PTR_OFFSET(data, hdr->size);
- for (rec = data; rec != end; ) {
- ret = map->append(rec, context);
+ while (rec != end) {
+ ret = map->append(append_hdr, rec, context);
if (ret <= 0)
break;
- rec = CONST_PTR_OFFSET(rec, record_size);
+ rec = CONST_PTR_OFFSET(rec, append_hdr->record_size);
}
break;
}
Index: mail-transaction-util.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-transaction-util.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-transaction-util.h 20 Jun 2004 09:13:14 -0000 1.7
+++ mail-transaction-util.h 24 Jun 2004 11:10:41 -0000 1.8
@@ -10,7 +10,8 @@
struct mail_transaction_map_functions {
int (*expunge)(const struct mail_transaction_expunge *e, void *context);
- int (*append)(const struct mail_index_record *rec, void *context);
+ int (*append)(const struct mail_transaction_append_header *hdr,
+ const struct mail_index_record *rec, void *context);
int (*flag_update)(const struct mail_transaction_flag_update *u,
void *context);
int (*cache_reset)(const struct mail_transaction_cache_reset *u,
More information about the dovecot-cvs
mailing list