mail-index-view.c revision e49e973f363a56ad186fce372310d5ec6d83d8fa
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2003-2013 Dovecot authors, see the included COPYING file */
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainenmail_index_view_dup_private(const struct mail_index_view *src)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid mail_index_view_clone(struct mail_index_view *dest,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mail_transaction_log_view_open(src->index->log);
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen dest->inconsistency_id = src->inconsistency_id;
abc79eec93e58e0152cd1d483f37be66c26811b9Timo Sirainen dest->log_file_expunge_seq = src->log_file_expunge_seq;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen dest->log_file_expunge_offset = src->log_file_expunge_offset;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen dest->log_file_head_seq = src->log_file_head_seq;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen dest->log_file_head_offset = src->log_file_head_offset;
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainenvoid mail_index_view_ref(struct mail_index_view *view)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void view_close(struct mail_index_view *view)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mail_transaction_log_view_close(&view->log_view);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenbool mail_index_view_is_inconsistent(struct mail_index_view *view)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen view->index->inconsistency_id != view->inconsistency_id)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenmail_index_view_get_transaction_count(struct mail_index_view *view)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen unsigned int i, count;
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen /* if map is already referenced, do nothing */
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen for (i = 0; i < count; i++) {
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen /* reference the given mapping. the reference is dropped when the view
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen is synchronized or closed. */
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen unsigned int i, count;
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen maps = array_get_modifiable(&view->map_refs, &count);
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen for (i = 0; i < count; i++)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainenstatic uint32_t view_get_messages_count(struct mail_index_view *view)
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainenstatic const struct mail_index_header *
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainenstatic const struct mail_index_record *
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenview_lookup_full(struct mail_index_view *view, uint32_t seq,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_index_map **map_r, bool *expunged_r)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen const struct mail_index_record *rec, *head_rec;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen /* look up the record */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "Corrupted Index file %s: Record [%u].uid=0",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* we'll need to return something so the caller doesn't crash */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* view's mapping is latest. we can use it directly. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* look up the record from head mapping. it may contain some changes.
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen start looking up from the same sequence as in the old view.
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if there are no expunges, it's there. otherwise it's somewhere
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen before (since records can't be inserted).
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen usually there are only a few expunges, so just going downwards from
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen our initial sequence position is probably faster than binary
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (seq > view->index->map->hdr.messages_count)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* everything is expunged from head. use the old record. */
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen } while (seq > 0);
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen /* found it. use it. reference the index mapping so that the
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen returned record doesn't get invalidated after next sync. */
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen mail_index_view_ref_map(view, view->index->map);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* expuned from head. use the old record. */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic void view_lookup_uid(struct mail_index_view *view, uint32_t seq,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainenstatic void view_lookup_seq_range(struct mail_index_view *view,
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen mail_index_map_lookup_seq_range(view->map, first_uid, last_uid,
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainenstatic void view_lookup_first(struct mail_index_view *view,
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen const struct mail_index_header *hdr = &view->map->hdr;
9f10cc61ec303351b43e54155c86699ef53cb8beTimo Sirainen if ((flags_mask & MAIL_SEEN) != 0 && (flags & MAIL_SEEN) == 0)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen if ((flags_mask & MAIL_DELETED) != 0 && (flags & MAIL_DELETED) != 0)
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen if (!mail_index_lookup_seq_range(view, low_uid, hdr->next_uid,
d2c853636ec2d99c9f96da877ff520a3b86a18baTimo Sirainen i_assert(hdr->messages_count <= view->map->rec_map->records_count);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
9f10cc61ec303351b43e54155c86699ef53cb8beTimo Sirainenmail_index_data_lookup_keywords(struct mail_index_map *map,
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen const unsigned char *data,
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen const unsigned int *keyword_idx_map;
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen /* no keywords at all in index */
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen (void)mail_index_ext_get_size(map, map->index->keywords_ext_id,
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen /* keyword_idx_map[] contains file => index keyword mapping */
dd7cbb32412c2f4d2d223af66672535bc1237246Timo Sirainen keyword_idx_map = array_get(&map->keyword_idx_map, &keyword_count);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen for (i = 0; i < record_size; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* first do the quick check to see if there's keywords at all */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* extra bits set in keyword bytes.
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen shouldn't happen, but just ignore. */
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainenstatic void view_lookup_keywords(struct mail_index_view *view, uint32_t seq,
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen mail_index_lookup_ext_full(view, seq, view->index->keywords_ext_id,
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainen mail_index_data_lookup_keywords(map, data, keyword_idx);
57f5683fd9dc9bc79816c418bb30fdbc33b68a8cTimo Sirainenstatic const void *
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainenview_map_lookup_ext_full(struct mail_index_map *map,
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen const struct mail_index_record *rec, uint32_t ext_id)
55a14bce15b9f44441b5f56616d73651a294d770Timo Sirainen if (!mail_index_map_get_ext_idx(map, ext_id, &idx))
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainenview_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
*data_size_r = 0;
return FALSE;
return TRUE;
const struct mail_index_header *
const struct mail_index_record *
const struct mail_index_record *
bool expunged;
return expunged;
const void *data;
const unsigned char *keyword_data;
return *first_seq_r != 0;
return *seq_r != 0;
bool *expunged_r)
*hdr_size_r = 0;
*record_size_r = 0;
*record_align_r = 0;
struct mail_index_view *
return view;
const struct mail_index_ext *
return NULL;