[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-save.c, 1.76,
1.77 mbox-sync-parse.c, 1.36, 1.37 mbox-sync-private.h, 1.46,
1.47 mbox-sync-rewrite.c, 1.43, 1.44 mbox-sync-update.c, 1.29,
1.30 mbox-sync.c, 1.143, 1.144
cras at dovecot.org
cras at dovecot.org
Sun Apr 3 00:09:10 EEST 2005
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index index-mail.c, 1.74,
1.75 index-mail.h, 1.31, 1.32 index-status.c, 1.35,
1.36 index-storage.c, 1.70, 1.71 index-storage.h, 1.89, 1.90
- Next message: [dovecot-cvs] dovecot/src/deliver deliver.c,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/lib-storage/index/mbox
In directory talvi:/tmp/cvs-serv14722/lib-storage/index/mbox
Modified Files:
mbox-save.c mbox-sync-parse.c mbox-sync-private.h
mbox-sync-rewrite.c mbox-sync-update.c mbox-sync.c
Log Message:
Keywords are now stored in X-Keywords headers in mbox. Did several related
API changes to get better performance.
Index: mbox-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-save.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- mbox-save.c 29 Mar 2005 19:27:37 -0000 1.76
+++ mbox-save.c 2 Apr 2005 21:09:07 -0000 1.77
@@ -232,13 +232,21 @@
{
unsigned char space[MBOX_HEADER_PADDING+1 +
sizeof("Content-Length: \n")-1 + MAX_INT_STRLEN];
- unsigned int i;
+ const array_t *keyword_names_list;
+ ARRAY_SET_TYPE(keyword_names_list, const char *);
+ const char *const *keyword_names;
+ unsigned int i, keyword_names_count;
+
+ keyword_names_list = mail_index_get_keywords(ctx->ibox->index);
+ keyword_names = array_get(keyword_names_list, &keyword_names_count);
str_append(ctx->headers, "X-Keywords:");
- /*FIXME:for (i = 0; i < count; i++) {
+ for (i = 0; i < keywords->count; i++) {
+ i_assert(keywords->idx[i] < keyword_names_count);
+
str_append_c(ctx->headers, ' ');
- str_append(ctx->headers, keywords[i]);
- }*/
+ str_append(ctx->headers, keyword_names[keywords->idx[i]]);
+ }
memset(space, ' ', sizeof(space));
str_append_n(ctx->headers, space, sizeof(space));
Index: mbox-sync-parse.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-parse.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- mbox-sync-parse.c 29 Mar 2005 19:27:37 -0000 1.36
+++ mbox-sync-parse.c 2 Apr 2005 21:09:07 -0000 1.37
@@ -107,6 +107,46 @@
return TRUE;
}
+static void
+parse_imap_keywords_list(struct mbox_sync_mail_context *ctx,
+ struct message_header_line *hdr, size_t pos)
+{
+ const char *keyword;
+ size_t keyword_start;
+ unsigned int idx, count;
+
+ count = 0;
+ while (pos < hdr->full_value_len) {
+ if (IS_LWSP_LF(hdr->full_value[pos])) {
+ pos++;
+ continue;
+ }
+
+ /* read the keyword */
+ keyword_start = pos;
+ for (; pos < hdr->full_value_len; pos++) {
+ if (IS_LWSP_LF(hdr->full_value[pos]))
+ break;
+ }
+
+ /* add it to index's keyword list if it's not there already */
+ t_push();
+ keyword = t_strndup(hdr->full_value + keyword_start,
+ pos - keyword_start);
+ (void)mail_index_keyword_lookup(ctx->sync_ctx->ibox->index,
+ keyword, TRUE, &idx);
+ t_pop();
+
+ count++;
+ }
+
+ if (count != array_count(ctx->sync_ctx->ibox->keyword_names)) {
+ /* need to update this list */
+ ctx->update_imapbase_keywords = TRUE;
+ ctx->need_rewrite = TRUE;
+ }
+}
+
static int parse_x_imap_base(struct mbox_sync_mail_context *ctx,
struct message_header_line *hdr)
{
@@ -128,17 +168,16 @@
pos = end - str;
t_pop();
- while (pos < hdr->full_value_len && IS_LWSP_LF(hdr->full_value[pos]))
- pos++;
-
if (uid_validity == 0) {
/* broken */
return FALSE;
}
if (ctx->sync_ctx->base_uid_validity == 0) {
+ /* first time parsing this. save the values. */
ctx->sync_ctx->base_uid_validity = uid_validity;
ctx->sync_ctx->base_uid_last = uid_last;
+
if (ctx->sync_ctx->next_uid-1 <= uid_last)
ctx->sync_ctx->next_uid = uid_last+1;
else {
@@ -156,12 +195,8 @@
ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] = str_len(ctx->header);
ctx->seen_imapbase = TRUE;
- if (pos == hdr->full_value_len)
- return TRUE;
-
- // FIXME: save keywords
-
- parse_trailing_whitespace(ctx, hdr);
+ parse_imap_keywords_list(ctx, hdr, pos);
+ parse_trailing_whitespace(ctx, hdr);
return TRUE;
}
@@ -180,10 +215,73 @@
static int parse_x_keywords(struct mbox_sync_mail_context *ctx,
struct message_header_line *hdr)
{
- // FIXME: parse them
+ array_t ARRAY_DEFINE(keyword_list, unsigned int);
+ string_t *keyword;
+ size_t keyword_start;
+ unsigned int idx;
+ size_t pos;
+
+ if (array_is_created(&ctx->mail.keywords))
+ return FALSE; /* duplicate header, delete */
+
+ /* read keyword indexes to temporary array first */
+ t_push();
+ keyword = t_str_new(128);
+ ARRAY_CREATE(&keyword_list, pool_datastack_create(), unsigned int, 16);
+
+ for (pos = 0; pos < hdr->full_value_len; ) {
+ if (IS_LWSP_LF(hdr->full_value[pos])) {
+ pos++;
+ continue;
+ }
+
+ /* read the keyword string */
+ keyword_start = pos;
+ for (; pos < hdr->full_value_len; pos++) {
+ if (IS_LWSP_LF(hdr->full_value[pos]))
+ break;
+ }
+
+ str_truncate(keyword, 0);
+ str_append_n(keyword, hdr->full_value + keyword_start,
+ pos - keyword_start);
+ if (!mail_index_keyword_lookup(ctx->sync_ctx->ibox->index,
+ str_c(keyword), FALSE, &idx)) {
+ if (ctx->sync_ctx->ibox->mbox_sync_dirty &&
+ !ctx->sync_ctx->dest_first_mail &&
+ !ctx->sync_ctx->seen_first_mail) {
+ /* we'll have to read the X-IMAP header to
+ make sure we have the latest list of
+ keywords */
+ i_assert(!ctx->sync_ctx->sync_restart);
+ ctx->sync_ctx->sync_restart = TRUE;
+ t_pop();
+ return FALSE;
+ }
+
+ /* index is fully up-to-date and the keyword wasn't
+ found. that means the sent mail originally
+ contained X-Keywords header. Delete it. */
+ t_pop();
+ return FALSE;
+ }
+
+ array_append(&keyword_list, &idx, 1);
+ }
+
+ /* once we know how many keywords there are, we can allocate the array
+ from mail_keyword_pool without wasting memory. */
+ if (array_count(&keyword_list) > 0) {
+ ARRAY_CREATE(&ctx->mail.keywords,
+ ctx->sync_ctx->mail_keyword_pool,
+ unsigned int, array_count(&keyword_list));
+ array_append_array(&ctx->mail.keywords, &keyword_list);
+ }
ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
parse_trailing_whitespace(ctx, hdr);
+
+ t_pop();
return TRUE;
}
Index: mbox-sync-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-private.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- mbox-sync-private.h 29 Mar 2005 19:27:37 -0000 1.46
+++ mbox-sync-private.h 2 Apr 2005 21:09:07 -0000 1.47
@@ -42,7 +42,7 @@
uint32_t uid;
uint32_t idx_seq;
uint8_t flags;
- uint32_t keywords_idx; /* +1 */
+ array_t ARRAY_DEFINE(keywords, unsigned int);
uoff_t from_offset;
uoff_t body_size;
@@ -85,6 +85,7 @@
unsigned int recent:1;
unsigned int dirty:1;
unsigned int uid_broken:1;
+ unsigned int update_imapbase_keywords:1;
};
struct mbox_sync_context {
@@ -109,6 +110,8 @@
array_t ARRAY_DEFINE(syncs, struct mail_index_sync_rec);
struct mail_index_sync_rec sync_rec;
+ pool_t mail_keyword_pool;
+
uint32_t prev_msg_uid, next_uid;
uint32_t seq, idx_seq, need_space_seq;
off_t expunged_space, space_diff;
@@ -129,8 +132,7 @@
int mbox_sync_parse_match_mail(struct index_mailbox *ibox,
struct mail_index_view *view, uint32_t seq);
-void mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
- array_t *syncs_arr);
+void mbox_sync_update_header(struct mbox_sync_mail_context *ctx);
void mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
const struct mbox_sync_mail *mail);
int mbox_sync_try_rewrite(struct mbox_sync_mail_context *ctx, off_t move_diff);
@@ -138,11 +140,15 @@
uoff_t end_offset, off_t move_diff, uoff_t extra_space,
uint32_t first_seq, uint32_t last_seq);
-void mbox_sync_apply_index_syncs(array_t *syncs_arr, uint8_t *flags);
+void mbox_sync_apply_index_syncs(struct mbox_sync_context *sync_ctx,
+ struct mbox_sync_mail *mail,
+ int *keywords_changed_r);
int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset);
int mbox_move(struct mbox_sync_context *sync_ctx,
uoff_t dest, uoff_t source, uoff_t size);
void mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
size_t pos, size_t need, size_t have);
+void mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx,
+ size_t size);
#endif
Index: mbox-sync-rewrite.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-rewrite.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mbox-sync-rewrite.c 29 Mar 2005 10:30:20 -0000 1.43
+++ mbox-sync-rewrite.c 2 Apr 2005 21:09:07 -0000 1.44
@@ -73,8 +73,8 @@
return 0;
}
-static void
-mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx, size_t size)
+void mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx,
+ size_t size)
{
size_t data_size, pos, start_pos;
const unsigned char *data;
@@ -322,9 +322,13 @@
}
mbox_sync_parse_next_mail(sync_ctx->input, &mail_ctx);
- if (mails[idx].space != 0)
+ if (mails[idx].space != 0) {
+ if (mails[idx].space < 0) {
+ /* remove all possible spacing before updating */
+ mbox_sync_headers_remove_space(&mail_ctx, (size_t)-1);
+ }
mbox_sync_update_header_from(&mail_ctx, &mails[idx]);
- else {
+ } else {
/* updating might just try to add headers and mess up our
calculations completely. so only add the EOH here. */
if (mail_ctx.have_eoh)
Index: mbox-sync-update.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync-update.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- mbox-sync-update.c 29 Mar 2005 19:27:37 -0000 1.29
+++ mbox-sync-update.c 2 Apr 2005 21:09:07 -0000 1.30
@@ -103,6 +103,68 @@
}
}
+static void keywords_append(struct mbox_sync_context *sync_ctx, string_t *dest,
+ const array_t *keyword_indexes_arr)
+{
+ ARRAY_SET_TYPE(keyword_indexes_arr, unsigned int);
+ const char *const *keyword_names;
+ const unsigned int *keyword_indexes;
+ unsigned int i, idx_count, keywords_count;
+ size_t last_break;
+
+ keyword_names = array_get(sync_ctx->ibox->keyword_names,
+ &keywords_count);
+ keyword_indexes = array_get(keyword_indexes_arr, &idx_count);
+
+ for (i = 0, last_break = 0; i < idx_count; i++) {
+ i_assert(keyword_indexes[i] < keywords_count);
+
+ /* try avoid overly long lines but cutting them
+ every 70 chars or so */
+ if (str_len(dest) - last_break < 70) {
+ if (i > 0)
+ str_append_c(dest, ' ');
+ } else {
+ str_append(dest, "\n\t");
+ last_break = str_len(dest);
+ }
+ str_append(dest, keyword_names[keyword_indexes[i]]);
+ }
+}
+
+static void
+keywords_append_all(struct mbox_sync_mail_context *ctx, string_t *dest)
+{
+ const char *const *names;
+ const unsigned char *p;
+ unsigned int i, count;
+ size_t last_break;
+
+ p = str_data(dest);
+ if (str_len(dest) < 70)
+ last_break = 0;
+ else {
+ /* set last_break to beginning of line */
+ for (last_break = str_len(dest); last_break > 0; last_break--) {
+ if (p[last_break-1] == '\n')
+ break;
+ }
+ }
+
+ names = array_get(ctx->sync_ctx->ibox->keyword_names, &count);
+ for (i = 0; i < count; i++) {
+ /* try avoid overly long lines but cutting them
+ every 70 chars or so */
+ if (str_len(dest) - last_break < 70)
+ str_append_c(dest, ' ');
+ else {
+ str_append(dest, "\n\t");
+ last_break = str_len(dest);
+ }
+ str_append(dest, names[i]);
+ }
+}
+
static void mbox_sync_add_missing_headers(struct mbox_sync_mail_context *ctx)
{
size_t old_hdr_size, new_hdr_size;
@@ -130,7 +192,7 @@
str_printfa(ctx->header, "%u %010u",
ctx->sync_ctx->base_uid_validity,
ctx->sync_ctx->next_uid-1);
- //FIXME:keywords_append(ctx, all_keywords);
+ keywords_append_all(ctx, ctx->header);
str_append_c(ctx->header, '\n');
}
@@ -157,10 +219,12 @@
}
if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1 &&
- ctx->mail.keywords_idx != 0) {
+ array_is_created(&ctx->mail.keywords) &&
+ array_count(&ctx->mail.keywords) > 0) {
str_append(ctx->header, "X-Keywords: ");
ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
- //keywords_append(ctx, ctx->mail.keywords);
+ keywords_append(ctx->sync_ctx, ctx->header,
+ &ctx->mail.keywords);
str_append_c(ctx->header, '\n');
}
@@ -196,14 +260,11 @@
}
}
-static void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
-{
-}
-
static void mbox_sync_update_line(struct mbox_sync_mail_context *ctx,
size_t pos, string_t *new_line)
{
const char *hdr, *p;
+ uoff_t file_pos;
if (ctx->header_first_change > pos)
ctx->header_first_change = pos;
@@ -213,32 +274,61 @@
if (p == NULL) {
/* shouldn't really happen, but allow anyway.. */
- ctx->header_last_change = (size_t)-1;
- str_truncate(ctx->header, pos);
- str_append_str(ctx->header, new_line);
- } else {
- mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
- buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
+ p = hdr + strlen(hdr);
+ }
+
+ file_pos = pos + ctx->hdr_offset;
+ if (ctx->mail.space > 0 && ctx->mail.offset >= file_pos &&
+ ctx->mail.offset < file_pos + (p - hdr)) {
+ /* extra space points to this line. remove it. */
+ ctx->mail.offset = ctx->hdr_offset;
+ ctx->mail.space = 0;
}
+
+ mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
+ buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
+}
+
+static void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
+{
+ string_t *str;
+
+ if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1)
+ return;
+
+ t_push();
+ str = t_str_new(256);
+ keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords);
+ str_append_c(str, '\n');
+ mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_KEYWORDS], str);
+ t_pop();
}
static void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
{
+ struct mbox_sync_context *sync_ctx = ctx->sync_ctx;
string_t *str;
- if (!ctx->sync_ctx->dest_first_mail ||
- ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1 ||
- ctx->sync_ctx->update_base_uid_last == 0 ||
- ctx->sync_ctx->update_base_uid_last < ctx->sync_ctx->base_uid_last)
+ if (!sync_ctx->dest_first_mail ||
+ ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1)
+ return;
+
+ if (sync_ctx->update_base_uid_last <= sync_ctx->base_uid_last)
+ sync_ctx->update_base_uid_last = 0;
+
+ /* see if anything changed */
+ if (!(ctx->update_imapbase_keywords ||
+ sync_ctx->update_base_uid_last != 0))
return;
/* update uid-last field in X-IMAPbase */
t_push();
str = t_str_new(200);
- str_printfa(str, "%u %010u", ctx->sync_ctx->base_uid_validity,
- ctx->sync_ctx->update_base_uid_last);
- //FIXME:keywords_append(ctx, all_keywords);
+ str_printfa(str, "%u %010u", sync_ctx->base_uid_validity,
+ sync_ctx->update_base_uid_last != 0 ?
+ sync_ctx->update_base_uid_last : sync_ctx->base_uid_last);
+ keywords_append_all(ctx, str);
str_append_c(str, '\n');
mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_IMAPBASE], str);
@@ -260,30 +350,24 @@
t_pop();
}
-void mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
- array_t *syncs_arr)
+void mbox_sync_update_header(struct mbox_sync_mail_context *ctx)
{
- ARRAY_SET_TYPE(syncs_arr, struct mail_index_sync_rec);
- const struct mail_index_sync_rec *syncs;
uint8_t old_flags;
- uint32_t old_keywords_idx;
- unsigned int i, count;
+ int keywords_changed;
i_assert(ctx->mail.uid != 0 || ctx->pseudo);
- syncs = array_get(syncs_arr, &count);
old_flags = ctx->mail.flags;
- if (count != 0) {
- old_keywords_idx = ctx->mail.keywords_idx;
- mbox_sync_apply_index_syncs(syncs_arr, &ctx->mail.flags);
+ if (array_count(&ctx->sync_ctx->syncs) > 0) {
+ mbox_sync_apply_index_syncs(ctx->sync_ctx, &ctx->mail,
+ &keywords_changed);
if ((old_flags & XSTATUS_FLAGS_MASK) !=
(ctx->mail.flags & XSTATUS_FLAGS_MASK))
mbox_sync_update_xstatus(ctx);
- /*FIXME:if (memcmp(old_keywords, ctx->mail.keywords,
- INDEX_KEYWORDS_BYTE_COUNT) != 0)
- mbox_sync_update_xkeywords(ctx);*/
+ if (keywords_changed)
+ mbox_sync_update_xkeywords(ctx);
}
if (!ctx->sync_ctx->ibox->keep_recent)
@@ -317,12 +401,30 @@
(mail->flags & XSTATUS_FLAGS_MASK);
mbox_sync_update_xstatus(ctx);
}
- /*FIXME:if (memcmp(ctx->mail.keywords, mail->keywords,
- INDEX_KEYWORDS_BYTE_COUNT) != 0) {
- memcpy(ctx->mail.keywords, mail->keywords,
- INDEX_KEYWORDS_BYTE_COUNT);
+ if (!array_is_created(&mail->keywords) ||
+ array_count(&mail->keywords) == 0) {
+ /* no keywords for this mail */
+ if (array_is_created(&ctx->mail.keywords)) {
+ array_clear(&ctx->mail.keywords);
+ mbox_sync_update_xkeywords(ctx);
+ }
+ } else if (!array_is_created(&ctx->mail.keywords)) {
+ /* adding first keywords */
+ ARRAY_CREATE(&ctx->mail.keywords,
+ ctx->sync_ctx->mail_keyword_pool,
+ unsigned int,
+ array_count(&mail->keywords));
+ array_append_array(&ctx->mail.keywords,
+ &mail->keywords);
mbox_sync_update_xkeywords(ctx);
- }*/
+ } else if (!buffer_cmp(ctx->mail.keywords.buffer,
+ mail->keywords.buffer)) {
+ /* keywords changed. */
+ array_clear(&ctx->mail.keywords);
+ array_append_array(&ctx->mail.keywords,
+ &mail->keywords);
+ mbox_sync_update_xkeywords(ctx);
+ }
i_assert(ctx->mail.uid == 0 || ctx->mail.uid == mail->uid);
ctx->mail.uid = mail->uid;
Index: mbox-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/mbox/mbox-sync.c,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -d -r1.143 -r1.144
--- mbox-sync.c 29 Mar 2005 19:27:37 -0000 1.143
+++ mbox-sync.c 2 Apr 2005 21:09:07 -0000 1.144
@@ -205,16 +205,43 @@
return 0;
}
-void mbox_sync_apply_index_syncs(array_t *syncs_arr, uint8_t *flags)
+void mbox_sync_apply_index_syncs(struct mbox_sync_context *sync_ctx,
+ struct mbox_sync_mail *mail,
+ int *keywords_changed_r)
{
- ARRAY_SET_TYPE(syncs_arr, struct mail_index_sync_rec);
const struct mail_index_sync_rec *syncs;
unsigned int i, count;
- syncs = array_get(syncs_arr, &count);
+ *keywords_changed_r = FALSE;
+
+ syncs = array_get(&sync_ctx->syncs, &count);
for (i = 0; i < count; i++) {
- if (syncs[i].type == MAIL_INDEX_SYNC_TYPE_FLAGS)
- mail_index_sync_flags_apply(&syncs[i], flags);
+ switch (syncs[i].type) {
+ case MAIL_INDEX_SYNC_TYPE_FLAGS:
+ mail_index_sync_flags_apply(&syncs[i], &mail->flags);
+ break;
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE:
+ case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
+ if (!array_is_created(&mail->keywords)) {
+ /* no existing keywords */
+ if (syncs[i].type !=
+ MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD)
+ break;
+
+ /* adding, create the array */
+ ARRAY_CREATE(&mail->keywords,
+ sync_ctx->mail_keyword_pool,
+ unsigned int,
+ I_MIN(10, count - i));
+ }
+ if (mail_index_sync_keywords_apply(&syncs[i],
+ &mail->keywords))
+ *keywords_changed_r = TRUE;
+ break;
+ default:
+ break;
+ }
}
}
@@ -335,12 +362,27 @@
return 0;
}
-static int mbox_sync_update_index(struct mbox_sync_context *sync_ctx,
- struct mbox_sync_mail_context *mail_ctx,
+static void
+mbox_sync_update_index_keywords(struct mbox_sync_mail_context *mail_ctx)
+{
+ struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
+ struct mail_keywords *keywords;
+
+ keywords = !array_is_created(&mail_ctx->mail.keywords) ?
+ mail_index_keywords_create(sync_ctx->t, NULL) :
+ mail_index_keywords_create_from_indexes(sync_ctx->t,
+ &mail_ctx->mail.keywords);
+ mail_index_update_keywords(sync_ctx->t, sync_ctx->idx_seq,
+ MODIFY_REPLACE, keywords);
+ mail_index_keywords_free(keywords);
+}
+
+static int mbox_sync_update_index(struct mbox_sync_mail_context *mail_ctx,
const struct mail_index_record *rec)
{
+ struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
struct mbox_sync_mail *mail = &mail_ctx->mail;
- uint8_t idx_flags, mbox_flags;
+ uint8_t mbox_flags;
mbox_flags = mail->flags & MAIL_FLAGS_MASK;
@@ -354,6 +396,7 @@
mail_index_append(sync_ctx->t, mail->uid, &sync_ctx->idx_seq);
mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
MODIFY_REPLACE, mbox_flags);
+ mbox_sync_update_index_keywords(mail_ctx);
if (sync_ctx->ibox->mbox_save_md5 != 0) {
mail_index_update_ext(sync_ctx->t, sync_ctx->idx_seq,
@@ -364,24 +407,41 @@
/* see if we need to update flags in index file. the flags in
sync records are automatically applied to rec->flags at the
end of index syncing, so calculate those new flags first */
- idx_flags = rec->flags;
- mbox_sync_apply_index_syncs(&sync_ctx->syncs, &idx_flags);
+ struct mbox_sync_mail idx_mail;
+ int keywords_changed;
- if ((idx_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
+ memset(&idx_mail, 0, sizeof(idx_mail));
+ idx_mail.flags = rec->flags;
+
+ /* get old keywords */
+ t_push();
+ ARRAY_CREATE(&idx_mail.keywords, pool_datastack_create(),
+ unsigned int, 32);
+ if (mail_index_lookup_keywords(sync_ctx->sync_view,
+ sync_ctx->idx_seq,
+ &idx_mail.keywords) < 0) {
+ mail_storage_set_index_error(sync_ctx->ibox);
+ t_pop();
+ return -1;
+ }
+ mbox_sync_apply_index_syncs(sync_ctx, &idx_mail,
+ &keywords_changed);
+
+ if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
/* flags are dirty. ignore whatever was in the mbox,
but update recent flag state if needed. */
mbox_flags &= MAIL_RECENT;
- mbox_flags |= idx_flags & ~MAIL_RECENT;
+ mbox_flags |= idx_mail.flags & ~MAIL_RECENT;
} else {
/* keep index's internal flags */
mbox_flags &= MAIL_FLAGS_MASK;
- mbox_flags |= idx_flags & ~MAIL_FLAGS_MASK;
+ mbox_flags |= idx_mail.flags & ~MAIL_FLAGS_MASK;
}
- if ((idx_flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY) ==
+ if ((idx_mail.flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY) ==
(mbox_flags & ~MAIL_INDEX_MAIL_FLAG_DIRTY)) {
/* all flags are same, except possibly dirty flag */
- if (idx_flags != mbox_flags) {
+ if (idx_mail.flags != mbox_flags) {
/* dirty flag state changed */
int dirty = (mbox_flags &
MAIL_INDEX_MAIL_FLAG_DIRTY) != 0;
@@ -390,18 +450,21 @@
dirty ? MODIFY_ADD : MODIFY_REMOVE,
MAIL_INDEX_MAIL_FLAG_DIRTY);
}
- } else if ((idx_flags & ~MAIL_RECENT) !=
+ } else if ((idx_mail.flags & ~MAIL_RECENT) !=
(mbox_flags & ~MAIL_RECENT)) {
/* flags other than MAIL_RECENT have changed */
mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
MODIFY_REPLACE, mbox_flags);
- } else if (((idx_flags ^ mbox_flags) & MAIL_RECENT) != 0) {
+ } else if (((idx_mail.flags ^ mbox_flags) & MAIL_RECENT) != 0) {
/* drop recent flag */
mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
MODIFY_REMOVE, MAIL_RECENT);
}
- // FIXME: keywords
+ if ((idx_mail.flags & MAIL_INDEX_MAIL_FLAG_DIRTY) == 0 &&
+ !array_cmp(&idx_mail.keywords, &mail_ctx->mail.keywords))
+ mbox_sync_update_index_keywords(mail_ctx);
+ t_pop();
}
if (mail_ctx->recent &&
@@ -523,7 +586,7 @@
if (mbox_read_from_line(mail_ctx) < 0)
return -1;
- mbox_sync_update_header(mail_ctx, &sync_ctx->syncs);
+ mbox_sync_update_header(mail_ctx);
ret = mbox_sync_try_rewrite(mail_ctx, move_diff);
if (ret < 0)
return -1;
@@ -546,7 +609,7 @@
array_count(&sync_ctx->syncs) != 0 ||
(mail_ctx->seq == 1 &&
sync_ctx->update_base_uid_last != 0)) {
- mbox_sync_update_header(mail_ctx, &sync_ctx->syncs);
+ mbox_sync_update_header(mail_ctx);
if (sync_ctx->delay_writes) {
/* mark it dirty and do it later */
mail_ctx->dirty = TRUE;
@@ -887,8 +950,7 @@
if (!mail_ctx->pseudo) {
if (!expunged) {
- if (mbox_sync_update_index(sync_ctx, mail_ctx,
- rec) < 0)
+ if (mbox_sync_update_index(mail_ctx, rec) < 0)
return -1;
}
sync_ctx->idx_seq++;
@@ -1424,6 +1486,10 @@
sync_ctx.index_sync_ctx = index_sync_ctx;
sync_ctx.sync_view = sync_view;
sync_ctx.t = mail_index_transaction_begin(sync_view, FALSE, TRUE);
+ sync_ctx.mail_keyword_pool = pool_alloconly_create("keywords", 4096);
+
+ /* make sure we've read the latest keywords in index */
+ (void)mail_index_get_keywords(ibox->index);
ARRAY_CREATE(&sync_ctx.mails, default_pool,
struct mbox_sync_mail, 64);
@@ -1523,6 +1589,7 @@
ret = -1;
}
+ pool_unref(sync_ctx.mail_keyword_pool);
str_free(sync_ctx.header);
str_free(sync_ctx.from_line);
array_free(&sync_ctx.mails);
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index index-mail.c, 1.74,
1.75 index-mail.h, 1.31, 1.32 index-status.c, 1.35,
1.36 index-storage.c, 1.70, 1.71 index-storage.h, 1.89, 1.90
- Next message: [dovecot-cvs] dovecot/src/deliver deliver.c,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list