[dovecot-cvs]
dovecot/src/lib-index mail-index-sync-private.h, 1.23,
1.24 mail-index-sync.c, 1.51, 1.52 mail-index-view-sync.c,
1.37, 1.38 mail-index.h, 1.143, 1.144 mail-transaction-util.c,
1.23, 1.24
cras at dovecot.org
cras at dovecot.org
Mon Mar 14 22:48:27 EET 2005
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv19675/lib-index
Modified Files:
mail-index-sync-private.h mail-index-sync.c
mail-index-view-sync.c mail-index.h mail-transaction-util.c
Log Message:
mail_index_sync_next() now returns keyword updates (now only thing left to
do is to fix maildir and mbox syncing to use them).
Index: mail-index-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync-private.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-sync-private.h 12 Mar 2005 18:16:29 -0000 1.23
+++ mail-index-sync-private.h 14 Mar 2005 20:48:25 -0000 1.24
@@ -8,18 +8,14 @@
struct mail_index_view *view;
struct mail_index_transaction *trans;
- const struct mail_transaction_expunge *expunges;
- const struct mail_transaction_flag_update *updates;
- unsigned int expunges_count, updates_count;
-
- uint32_t append_uid_first, append_uid_last;
-
const struct mail_transaction_header *hdr;
const void *data;
- size_t expunge_idx, update_idx;
+ array_t ARRAY_DEFINE(sync_list, struct mail_index_sync_list);
uint32_t next_uid;
+ uint32_t append_uid_first, append_uid_last;
+
unsigned int lock_id;
unsigned int sync_appends:1;
@@ -27,6 +23,12 @@
unsigned int sync_dirty:1;
};
+struct mail_index_sync_list {
+ const array_t *ARRAY_DEFINE(array, struct uid_range *);
+ unsigned int idx;
+ unsigned int keyword_num;
+};
+
struct mail_index_expunge_handler {
mail_index_expunge_handler_t *handler;
void **context;
Index: mail-index-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-sync.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- mail-index-sync.c 12 Mar 2005 18:16:29 -0000 1.51
+++ mail-index-sync.c 14 Mar 2005 20:48:25 -0000 1.52
@@ -11,6 +11,10 @@
#include <stdlib.h>
+struct uid_range {
+ uint32_t uid1, uid2;
+};
+
static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
{
const struct mail_transaction_expunge *e = ctx->data;
@@ -181,6 +185,8 @@
mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx,
int *seen_external_r)
{
+ struct mail_index_sync_list *synclist;
+ unsigned int i, keyword_count;
int ret;
*seen_external_r = FALSE;
@@ -197,6 +203,7 @@
return -1;
}
+ /* read all transactions from log into a transaction in memory */
while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
&ctx->hdr,
&ctx->data, NULL)) > 0) {
@@ -206,18 +213,35 @@
mail_index_sync_add_transaction(ctx);
}
- if (!array_is_created(&ctx->trans->expunges))
- ctx->expunges_count = 0;
- else {
- ctx->expunges = array_get(&ctx->trans->expunges,
- &ctx->expunges_count);
+ /* create an array containing all expunge, flag and keyword update
+ arrays so we can easily go through all of the changes. */
+ keyword_count = !array_is_created(&ctx->trans->keyword_updates) ? 0 :
+ array_count(&ctx->trans->keyword_updates);
+ ARRAY_CREATE(&ctx->sync_list, default_pool,
+ struct mail_index_sync_list, keyword_count + 2);
+
+ if (array_is_created(&ctx->trans->expunges)) {
+ synclist = array_modifyable_append(&ctx->sync_list);
+ synclist->array = &ctx->trans->expunges;
}
- if (!array_is_created(&ctx->trans->updates))
- ctx->updates_count = 0;
- else {
- ctx->updates = array_get(&ctx->trans->updates,
- &ctx->updates_count);
+
+ if (array_is_created(&ctx->trans->updates)) {
+ synclist = array_modifyable_append(&ctx->sync_list);
+ synclist->array = &ctx->trans->updates;
+ }
+
+ /* we must return resets before keyword additions or they get lost */
+ if (array_is_created(&ctx->trans->keyword_resets)) {
+ synclist = array_modifyable_append(&ctx->sync_list);
+ synclist->array = &ctx->trans->keyword_resets;
}
+
+ for (i = 0; i < keyword_count; i++) {
+ synclist = array_modifyable_append(&ctx->sync_list);
+ synclist->array = array_idx(&ctx->trans->keyword_updates, i);
+ synclist->keyword_num = i;
+ }
+
return ret;
}
@@ -406,13 +430,35 @@
rec->remove_flags = update->remove_flags;
}
+static void mail_index_sync_get_keyword_update(struct mail_index_sync_rec *rec,
+ const struct uid_range *range,
+ unsigned int num)
+{
+ rec->type = num % 2 == 0 ?
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD :
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE;
+ rec->uid1 = range->uid1;
+ rec->uid2 = range->uid2;
+ rec->keyword_idx = num / 2;
+}
+
+static void mail_index_sync_get_keyword_reset(struct mail_index_sync_rec *rec,
+ const struct uid_range *range)
+{
+ rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
+ rec->uid1 = range->uid1;
+ rec->uid2 = range->uid2;
+}
+
static int mail_index_sync_rec_check(struct mail_index_view *view,
struct mail_index_sync_rec *rec)
{
switch (rec->type) {
case MAIL_INDEX_SYNC_TYPE_EXPUNGE:
case MAIL_INDEX_SYNC_TYPE_FLAGS:
- case MAIL_INDEX_SYNC_TYPE_KEYWORDS:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
if (rec->uid1 > rec->uid2 || rec->uid1 == 0) {
mail_transaction_log_view_set_corrupted(view->log_view,
"Broken UID range: %u..%u (type 0x%x)",
@@ -429,63 +475,85 @@
int mail_index_sync_next(struct mail_index_sync_ctx *ctx,
struct mail_index_sync_rec *sync_rec)
{
- const struct mail_transaction_expunge *next_exp;
- const struct mail_transaction_flag_update *next_update;
+ struct mail_index_sync_list *sync_list;
+ const struct uid_range *uid_range = NULL;
+ unsigned int i, count, next_i;
+ uint32_t next_found_uid;
- next_exp = ctx->expunge_idx == ctx->expunges_count ? NULL :
- &ctx->expunges[ctx->expunge_idx];
- next_update = ctx->update_idx == ctx->updates_count ? NULL :
- &ctx->updates[ctx->update_idx];
+ next_i = (unsigned int)-1;
+ next_found_uid = (uint32_t)-1;
- if (next_update != NULL &&
- (next_exp == NULL || next_update->uid1 < next_exp->uid1)) {
- mail_index_sync_get_update(sync_rec, next_update);
- if (next_exp != NULL && next_exp->uid1 <= next_update->uid2) {
- /* it's overlapping with next expunge */
- sync_rec->uid2 = next_exp->uid1-1;
- }
+ /* FIXME: replace with a priority queue so we don't have to go
+ through the whole list constantly. and remember to make sure that
+ keyword resets are sent before adds! */
+ sync_list = array_get(&ctx->sync_list, &count);
+ for (i = 0; i < count; i++) {
+ if (!array_is_created(sync_list[i].array) ||
+ sync_list[i].idx == array_count(sync_list[i].array))
+ continue;
- if (sync_rec->uid1 < ctx->next_uid) {
- /* overlapping with previous expunge */
- if (ctx->next_uid > sync_rec->uid2) {
- /* hide this update completely */
- ctx->update_idx++;
- return mail_index_sync_next(ctx, sync_rec);
- }
- sync_rec->uid1 = ctx->next_uid;
+ uid_range = array_idx(sync_list[i].array, sync_list[i].idx);
+ if (uid_range->uid1 == ctx->next_uid) {
+ /* use this one. */
+ break;
+ }
+ if (uid_range->uid1 < next_found_uid) {
+ next_i = i;
+ next_found_uid = uid_range->uid1;
}
-
- i_assert(sync_rec->uid1 <= sync_rec->uid2);
- ctx->update_idx++;
- return mail_index_sync_rec_check(ctx->view, sync_rec);
}
- if (next_exp != NULL) {
- mail_index_sync_get_expunge(sync_rec, next_exp);
- if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
- return -1;
-
- ctx->expunge_idx++;
- ctx->next_uid = next_exp->uid2+1;
- return 1;
+ if (i == count) {
+ if (next_i == (unsigned int)-1) {
+ /* nothing left in sync_list */
+ if (ctx->sync_appends) {
+ ctx->sync_appends = FALSE;
+ sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
+ sync_rec->uid1 = ctx->append_uid_first;
+ sync_rec->uid2 = ctx->append_uid_last;
+ return 1;
+ }
+ return 0;
+ }
+ ctx->next_uid = next_found_uid;
+ i = next_i;
+ uid_range = array_idx(sync_list[i].array, sync_list[i].idx);
}
- if (ctx->sync_appends) {
- ctx->sync_appends = FALSE;
- sync_rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
- sync_rec->uid1 = ctx->append_uid_first;
- sync_rec->uid2 = ctx->append_uid_last;
- return 1;
+ if (sync_list[i].array == &ctx->trans->expunges) {
+ mail_index_sync_get_expunge(sync_rec,
+ (const struct mail_transaction_expunge *)uid_range);
+ } else if (sync_list[i].array == &ctx->trans->updates) {
+ mail_index_sync_get_update(sync_rec,
+ (const struct mail_transaction_flag_update *)uid_range);
+ } else if (sync_list[i].array == &ctx->trans->keyword_resets) {
+ mail_index_sync_get_keyword_reset(sync_rec, uid_range);
+ } else {
+ mail_index_sync_get_keyword_update(sync_rec, uid_range,
+ sync_list[i].keyword_num);
}
+ sync_list[i].idx++;
- return 0;
+ if (mail_index_sync_rec_check(ctx->view, sync_rec) < 0)
+ return -1;
+ return 1;
}
int mail_index_sync_have_more(struct mail_index_sync_ctx *ctx)
{
- return (ctx->update_idx != ctx->updates_count) ||
- (ctx->expunge_idx != ctx->expunges_count) ||
- ctx->sync_appends;
+ struct mail_index_sync_list *sync_list;
+ unsigned int i, count;
+
+ if (ctx->sync_appends)
+ return TRUE;
+
+ sync_list = array_get(&ctx->sync_list, &count);
+ for (i = 0; i < count; i++) {
+ if (array_is_created(sync_list[i].array) &&
+ sync_list[i].idx != array_count(sync_list[i].array))
+ return TRUE;
+ }
+ return FALSE;
}
static void mail_index_sync_end(struct mail_index_sync_ctx *ctx)
Index: mail-index-view-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view-sync.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- mail-index-view-sync.c 12 Mar 2005 12:04:18 -0000 1.37
+++ mail-index-view-sync.c 14 Mar 2005 20:48:25 -0000 1.38
@@ -79,7 +79,8 @@
#define MAIL_INDEX_VIEW_VISIBLE_SYNC_MASK \
(MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
- MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE)
+ MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
+ MAIL_TRANSACTION_KEYWORD_RESET)
int mail_index_view_sync_begin(struct mail_index_view *view,
enum mail_index_sync_type sync_mask,
@@ -297,12 +298,23 @@
}
uids = CONST_PTR_OFFSET(data, ctx->data_offset);
- rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORDS;
+ /* FIXME: this isn't exactly correct.. but no-one cares? */
+ rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
rec->uid1 = uids[0];
rec->uid2 = uids[1];
ctx->data_offset += sizeof(uint32_t) * 2;
break;
}
+ case MAIL_TRANSACTION_KEYWORD_RESET: {
+ const struct mail_transaction_keyword_reset *reset =
+ CONST_PTR_OFFSET(data, ctx->data_offset);
+
+ rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
+ rec->uid1 = reset->uid1;
+ rec->uid2 = reset->uid2;
+ ctx->data_offset += sizeof(*reset);
+ break;
+ }
default:
i_unreached();
}
Index: mail-index.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -d -r1.143 -r1.144
--- mail-index.h 5 Feb 2005 12:01:49 -0000 1.143
+++ mail-index.h 14 Mar 2005 20:48:25 -0000 1.144
@@ -107,10 +107,12 @@
};
enum mail_index_sync_type {
- MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
- MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
- MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
- MAIL_INDEX_SYNC_TYPE_KEYWORDS = 0x08
+ MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
+ MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
+ MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD = 0x08,
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE = 0x10,
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET = 0x20
};
#define MAIL_INDEX_SYNC_MASK_ALL 0xff
@@ -121,6 +123,9 @@
/* MAIL_INDEX_SYNC_TYPE_FLAGS: */
uint8_t add_flags;
uint8_t remove_flags;
+
+ /* MAIL_INDEX_SYNC_TYPE_KEYWORDS: */
+ unsigned int keyword_idx;
};
struct mail_keywords;
Index: mail-transaction-util.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-util.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-transaction-util.c 5 Feb 2005 12:01:49 -0000 1.23
+++ mail-transaction-util.c 14 Mar 2005 20:48:25 -0000 1.24
@@ -19,8 +19,11 @@
sizeof(struct mail_transaction_ext_reset) },
{ MAIL_TRANSACTION_EXT_HDR_UPDATE, 0, 1 },
{ MAIL_TRANSACTION_EXT_REC_UPDATE, 0, 1 },
- { MAIL_TRANSACTION_KEYWORD_UPDATE, MAIL_INDEX_SYNC_TYPE_KEYWORDS, 1 },
- { MAIL_TRANSACTION_KEYWORD_RESET, 0, 1 },
+ { MAIL_TRANSACTION_KEYWORD_UPDATE,
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD |
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE, 1 },
+ { MAIL_TRANSACTION_KEYWORD_RESET,
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET, 1 },
{ 0, 0, 0 }
};
More information about the dovecot-cvs
mailing list