dovecot-1.2: mail_get_flags/keywords() now returns updated value...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Dec 14 07:21:17 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/7b16388a3bb0
changeset: 8549:7b16388a3bb0
user: Timo Sirainen <tss at iki.fi>
date: Sun Dec 14 07:19:48 2008 +0200
description:
mail_get_flags/keywords() now returns updated values if they've been changed within transaction.
diffstat:
9 files changed, 277 insertions(+), 141 deletions(-)
src/lib-index/mail-index-dummy-view.c | 1
src/lib-index/mail-index-transaction-private.h | 6
src/lib-index/mail-index-transaction-view.c | 113 +++++++++++
src/lib-index/mail-index-transaction.c | 15 -
src/lib-index/mail-index-view-private.h | 2
src/lib-index/mail-index-view.c | 239 ++++++++++++------------
src/lib-storage/index/index-mail.c | 35 ++-
src/lib-storage/index/index-mail.h | 1
src/plugins/virtual/virtual-mail.c | 6
diffs (truncated from 622 to 300 lines):
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-dummy-view.c
--- a/src/lib-index/mail-index-dummy-view.c Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-dummy-view.c Sun Dec 14 07:19:48 2008 +0200
@@ -29,6 +29,7 @@ static struct mail_index_view_vfuncs dum
NULL,
NULL,
NULL,
+ NULL,
NULL
};
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-transaction-private.h Sun Dec 14 07:19:48 2008 +0200
@@ -100,6 +100,12 @@ void mail_index_transaction_convert_to_u
void mail_index_transaction_convert_to_uids(struct mail_index_transaction *t);
void mail_index_transaction_check_conflicts(struct mail_index_transaction *t);
+unsigned int
+mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
+ unsigned int left_idx,
+ unsigned int right_idx,
+ uint32_t seq);
+
bool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array,
uint32_t seq, unsigned int *idx_r);
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-transaction-view.c
--- a/src/lib-index/mail-index-transaction-view.c Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-transaction-view.c Sun Dec 14 07:19:48 2008 +0200
@@ -15,8 +15,12 @@ struct mail_index_view_transaction {
struct mail_index_map *lookup_map;
struct mail_index_header hdr;
+
buffer_t *lookup_return_data;
uint32_t lookup_prev_seq;
+
+ unsigned int recs_count;
+ struct mail_index_record *recs;
};
static void tview_close(struct mail_index_view *view)
@@ -29,6 +33,7 @@ static void tview_close(struct mail_inde
mail_index_unmap(&tview->lookup_map);
if (tview->lookup_return_data != NULL)
buffer_free(&tview->lookup_return_data);
+ i_free(tview->recs);
tview->super->close(view);
mail_index_transaction_unref(&t);
@@ -62,6 +67,42 @@ tview_get_header(struct mail_index_view
hdr = &tview->hdr;
}
return hdr;
+}
+
+static const struct mail_index_record *
+tview_apply_flag_updates(struct mail_index_view_transaction *tview,
+ const struct mail_index_record *rec, uint32_t seq)
+{
+ struct mail_index_transaction *t = tview->t;
+ const struct mail_transaction_flag_update *updates;
+ unsigned int idx, count;
+
+ /* see if there are any flag updates */
+ if (seq < t->min_flagupdate_seq || seq > t->max_flagupdate_seq ||
+ !array_is_created(&t->updates))
+ return rec;
+
+ updates = array_get(&t->updates, &count);
+ idx = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
+ if (seq < updates[idx].uid1 || seq > updates[idx].uid2)
+ return rec;
+
+ /* yes, we have flag updates. since we can't modify rec directly and
+ we want to be able to handle multiple mail_index_lookup() calls
+ without the second one overriding the first one's data, we'll
+ create a records array and return data from there */
+ if (tview->recs == NULL) {
+ tview->recs_count = t->first_new_seq;
+ tview->recs = i_new(struct mail_index_record,
+ tview->recs_count);
+ }
+ i_assert(tview->recs_count == t->first_new_seq);
+ i_assert(seq > 0 && seq <= tview->recs_count);
+
+ tview->recs[seq-1] = *rec;
+ tview->recs[seq-1].flags |= updates[idx].add_flags;
+ tview->recs[seq-1].flags &= ~updates[idx].remove_flags;
+ return &tview->recs[seq-1];
}
static const struct mail_index_record *
@@ -81,8 +122,8 @@ tview_lookup_full(struct mail_index_view
}
rec = tview->super->lookup_full(view, seq, map_r, expunged_r);
-
- /* if we're expunged within this transaction, return 0 */
+ rec = tview_apply_flag_updates(tview, rec, seq);
+
if (array_is_created(&tview->t->expunges) &&
seq_range_exists(&tview->t->expunges, seq))
*expunged_r = TRUE;
@@ -187,6 +228,73 @@ static void tview_lookup_first(struct ma
*seq_r = seq;
break;
}
+ }
+}
+
+static void keyword_index_add(ARRAY_TYPE(keyword_indexes) *keywords,
+ unsigned int idx)
+{
+ const unsigned int *indexes;
+ unsigned int i, count;
+
+ indexes = array_get(keywords, &count);
+ for (i = 0; i < count; i++) {
+ if (indexes[i] == idx)
+ return;
+ }
+ array_append(keywords, &idx, 1);
+}
+
+static void keyword_index_remove(ARRAY_TYPE(keyword_indexes) *keywords,
+ unsigned int idx)
+{
+ const unsigned int *indexes;
+ unsigned int i, count;
+
+ indexes = array_get(keywords, &count);
+ for (i = 0; i < count; i++) {
+ if (indexes[i] == idx) {
+ array_delete(keywords, i, 1);
+ break;
+ }
+ }
+}
+
+static void tview_lookup_keywords(struct mail_index_view *view, uint32_t seq,
+ ARRAY_TYPE(keyword_indexes) *keyword_idx)
+{
+ struct mail_index_view_transaction *tview =
+ (struct mail_index_view_transaction *)view;
+ struct mail_index_transaction *t = tview->t;
+ const struct mail_index_transaction_keyword_update *updates;
+ unsigned int i, count;
+
+ tview->super->lookup_keywords(view, seq, keyword_idx);
+
+ if (seq < t->min_flagupdate_seq || seq > t->max_flagupdate_seq) {
+ /* no keyword updates for this sequence */
+ return;
+ }
+
+ /* apply any keyword updates in this transaction */
+ if (array_is_created(&t->keyword_resets)) {
+ if (seq_range_exists(&t->keyword_resets, seq))
+ array_clear(keyword_idx);
+ }
+
+ if (array_is_created(&t->keyword_updates))
+ updates = array_get(&t->keyword_updates, &count);
+ else {
+ updates = NULL;
+ count = 0;
+ }
+ for (i = 0; i < count; i++) {
+ if (array_is_created(&updates[i].add_seq) &&
+ seq_range_exists(&updates[i].add_seq, seq))
+ keyword_index_add(keyword_idx, i);
+ else if (array_is_created(&updates[i].remove_seq) &&
+ seq_range_exists(&updates[i].remove_seq, seq))
+ keyword_index_remove(keyword_idx, i);
}
}
@@ -336,6 +444,7 @@ static struct mail_index_view_vfuncs tra
tview_lookup_uid,
tview_lookup_seq_range,
tview_lookup_first,
+ tview_lookup_keywords,
tview_lookup_ext_full,
tview_get_header_ext,
tview_ext_get_reset_id
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-transaction.c Sun Dec 14 07:19:48 2008 +0200
@@ -805,10 +805,11 @@ mail_transaction_update_want_add(struct
return FALSE;
}
-static uint32_t
-mail_index_find_update_insert_pos(struct mail_index_transaction *t,
- unsigned int left_idx, unsigned int right_idx,
- uint32_t seq)
+unsigned int
+mail_index_transaction_get_flag_update_pos(struct mail_index_transaction *t,
+ unsigned int left_idx,
+ unsigned int right_idx,
+ uint32_t seq)
{
const struct mail_transaction_flag_update *updates;
unsigned int idx, count;
@@ -1038,8 +1039,8 @@ void mail_index_update_flags_range(struc
first_idx = 0;
count = t->last_update_idx + 1;
}
- idx = mail_index_find_update_insert_pos(t, first_idx, count,
- u.uid1);
+ idx = mail_index_transaction_get_flag_update_pos(t, first_idx,
+ count, u.uid1);
mail_index_insert_flag_update(t, u, idx);
}
}
@@ -1567,7 +1568,7 @@ mail_index_update_cancel(struct mail_ind
return ret;
updates = array_get_modifiable(&t->updates, &count);
- i = mail_index_find_update_insert_pos(t, 0, count, seq);
+ i = mail_index_transaction_get_flag_update_pos(t, 0, count, seq);
if (i < count && updates[i].uid1 <= seq && updates[i].uid2 >= seq) {
/* exists */
ret = TRUE;
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-view-private.h
--- a/src/lib-index/mail-index-view-private.h Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-view-private.h Sun Dec 14 07:19:48 2008 +0200
@@ -26,6 +26,8 @@ struct mail_index_view_vfuncs {
void (*lookup_first)(struct mail_index_view *view,
enum mail_flags flags, uint8_t flags_mask,
uint32_t *seq_r);
+ void (*lookup_keywords)(struct mail_index_view *view, uint32_t seq,
+ ARRAY_TYPE(keyword_indexes) *keyword_idx);
void (*lookup_ext_full)(struct mail_index_view *view, uint32_t seq,
uint32_t ext_id, struct mail_index_map **map_r,
const void **data_r, bool *expunged_r);
diff -r 6a6a3bfea547 -r 7b16388a3bb0 src/lib-index/mail-index-view.c
--- a/src/lib-index/mail-index-view.c Sun Dec 14 06:51:04 2008 +0200
+++ b/src/lib-index/mail-index-view.c Sun Dec 14 07:19:48 2008 +0200
@@ -333,116 +333,6 @@ static void view_lookup_first(struct mai
}
static void
-view_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
- uint32_t ext_id, struct mail_index_map **map_r,
- const void **data_r, bool *expunged_r)
-{
- const struct mail_index_ext *ext;
- const struct mail_index_record *rec;
- uint32_t idx, offset;
-
- rec = view->v.lookup_full(view, seq, map_r, expunged_r);
- if (!mail_index_map_get_ext_idx(*map_r, ext_id, &idx)) {
- *data_r = NULL;
- return;
- }
-
- ext = array_idx(&(*map_r)->extensions, idx);
- offset = ext->record_offset;
-
- *data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset);
-}
-
-static void view_get_header_ext(struct mail_index_view *view,
- struct mail_index_map *map, uint32_t ext_id,
- const void **data_r, size_t *data_size_r)
-{
- const struct mail_index_ext *ext;
- uint32_t idx;
-
- if (map == NULL) {
- /* no mapping given, use head mapping */
- map = view->index->map;
- }
-
- if (!mail_index_map_get_ext_idx(map, ext_id, &idx)) {
- /* extension doesn't exist in this index file */
- *data_r = NULL;
- *data_size_r = 0;
- return;
- }
-
- ext = array_idx(&map->extensions, idx);
- *data_r = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
- *data_size_r = ext->hdr_size;
-}
-
-static bool view_ext_get_reset_id(struct mail_index_view *view ATTR_UNUSED,
- struct mail_index_map *map,
- uint32_t ext_id, uint32_t *reset_id_r)
-{
- const struct mail_index_ext *ext;
- uint32_t idx;
-
- if (!mail_index_map_get_ext_idx(map, ext_id, &idx))
- return FALSE;
-
- ext = array_idx(&map->extensions, idx);
More information about the dovecot-cvs
mailing list