mail-index-modseq.c revision 5f5870385cff47efd2f58e7892f251cf13761528
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* must be in the same order as enum mail_flags */
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen /* indexes use enum modseq_metadata_idx */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen ARRAY_DEFINE(metadata_modseqs, struct metadata_modseqs);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenvoid mail_index_modseq_init(struct mail_index *index)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen mail_index_ext_register(index, MAIL_INDEX_MODSEQ_EXT_NAME,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic uint64_t mail_index_modseq_get_head(struct mail_index *index)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen I_MAX(index->log->head->sync_highest_modseq, 1);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenvoid mail_index_modseq_enable(struct mail_index *index)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen if (!mail_index_map_get_ext_idx(index->map, index->modseq_ext_id,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen /* modseqs not enabled to the index yet, add them. */
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen trans = mail_index_transaction_begin(view, 0);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen hdr.highest_modseq = mail_index_modseq_get_head(index);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen mail_index_update_header_ext(trans, index->modseq_ext_id,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen /* commit also refreshes the index, which syncs the modseqs */
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen /* get the modseq extension to index map */
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen /* didn't work for some reason */
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainenmail_index_map_get_modseq_header(struct mail_index_map *map)
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainen if (!mail_index_map_get_ext_idx(map, map->index->modseq_ext_id, &idx))
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainen if (ext->hdr_size != sizeof(struct mail_index_modseq_header))
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainen return CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenuint64_t mail_index_map_modseq_get_highest(struct mail_index_map *map)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen const struct mail_index_modseq_header *modseq_hdr;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen modseq_hdr = mail_index_map_get_modseq_header(map);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if (modseq_hdr != NULL && modseq_hdr->highest_modseq != 0)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* fallback to returning the log head. if modseqs aren't
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen enabled, we return 0. */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenuint64_t mail_index_modseq_get_highest(struct mail_index_view *view)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen return mail_index_map_modseq_get_highest(view->map);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainenmail_index_map_modseq(struct mail_index_view *view)
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen struct mail_index_map_modseq *mmap = view->map->rec_map->modseq;
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen /* don't start tracking until we've seen modseq extension intro */
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen if (!mail_index_map_get_ext_idx(view->map, view->index->modseq_ext_id,
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen mmap = i_new(struct mail_index_map_modseq, 1);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenuint64_t mail_index_modseq_lookup(struct mail_index_view *view, uint32_t seq)
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen struct mail_index_map_modseq *mmap = mail_index_map_modseq(view);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen return mail_index_modseq_get_head(view->index);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen rec = mail_index_lookup_full(view, seq, &map);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen if (!mail_index_map_get_ext_idx(map, view->index->modseq_ext_id,
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen /* not enabled yet */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen return mail_index_modseq_get_head(view->index);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen ext = array_idx(&map->extensions, ext_map_idx);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen modseqp = CONST_PTR_OFFSET(rec, ext->record_offset);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen /* If we're here because we just enabled modseqs, we'll return
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen the same modseq (initial highestmodseq) for all messages.
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen The next sync will change these zeros to initial
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen highestmodseq or higher.
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen If we're here because a message got appended but modseq
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen wasn't set (older Dovecot?), we'll again use the current
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen highest modseq. This isn't exactly correct, but it gets
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen fixed after the next sync and this situation shouldn't
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen normally happen anyway. */
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainenint mail_index_modseq_set(struct mail_index_view *view,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct mail_index_map_modseq *mmap = mail_index_map_modseq(view);
7a87427770874f38d1d299635b37d699f9772860Timo Sirainen if (!mail_index_map_get_ext_idx(view->map, view->index->modseq_ext_id,
static uint64_t
unsigned int count;
for (i = 0; i < METADATA_MODSEQ_IDX_KEYWORD_START; i++) {
if (highest_modseq == 0) {
return highest_modseq;
unsigned int i, metadata_idx;
if (highest_modseq == 0) {
return highest_modseq;
&ext_map_idx))
return FALSE;
return TRUE;
const void *tdata)
unsigned int i, count;
case MAIL_TRANSACTION_APPEND: {
for (i = 0; i < count; i++) {
seq1);
case MAIL_TRANSACTION_FLAG_UPDATE: {
sizeof(struct mail_transaction_flag_update));
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
unsigned int seqset_offset;
sizeof(struct mail_transaction_keyword_reset));
for (i = 0; i < count; i++) {
const void *tdata;
bool reset;
int ret;
&ext_map_idx))
i_unreached();
if (ret <= 0) {
&reset);
if (ret > 0) {
T_BEGIN {
tdata);
} T_END;
struct mail_index_modseq_sync *
return ctx;
&ext_map_idx))
seq1--;
for (i = 0; i < METADATA_MODSEQ_IDX_KEYWORD_START; i++) {
unsigned int keyword_idx,
unsigned int i, count;
struct mail_index_map_modseq *
unsigned int i, count;
for (i = 0; i < count; i++) {
return new_mmap;
return FALSE;