mail-index-view.c revision 7c5b51bdf43a98e12c654ad437e0b258c5fffbc1
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_clone(struct mail_index_view *dest,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->log_view = mail_transaction_log_view_open(src->index->log);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic void _view_close(struct mail_index_view *view)
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_transaction_log_view_close(view->log_view);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic int mail_index_view_map_protect(struct mail_index_view *view)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* not head mapping, no need to lock */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map_lock_mprotect(view->index, view->map,
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainenint mail_index_view_lock_head(struct mail_index_view *view, int update_index)
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen unsigned int lock_id;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->index->map))
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen if (!mail_index_is_locked(view->index, view->lock_id)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lock_shared(view->index, update_index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map(view->index, FALSE) <= 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* index was rebuilt */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lock_shared(view->index, TRUE, &lock_id) < 0)
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen mail_index_unlock(view->index, view->lock_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* mail_index_lock_shared() may have reopened the file,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen so do this after it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_lock(struct mail_index_view *view)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen return mail_index_view_lock_head(view, FALSE);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view)
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen (void)mail_index_map_lock_mprotect(view->index, view->map,
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen mail_index_unlock(view->index, view->lock_id);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint mail_index_view_is_inconsistent(struct mail_index_view *view)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maps = buffer_get_data(view->map_refs, &size);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (i = 0; i < size; i++) {
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen buffer_create_dynamic(default_pool, 128, (size_t)-1);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen buffer_append(view->map_refs, &map, sizeof(map));
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maps = buffer_get_modifyable_data(view->map_refs, &size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < size; i++)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic uint32_t _view_get_message_count(struct mail_index_view *view)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic int _view_get_header(struct mail_index_view *view,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view->map->hdr->messages_count == view->messages_count)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* messages_count differs, use a modified copy.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen FIXME: so might seen_messages_count, etc. and they're
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen more difficult to fix. maybe grab a copy of the header
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen when opening the view initially?.. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->tmp_hdr_copy.messages_count = view->messages_count;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* look for it in the head mapping */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen // FIXME: we could be skipping more by uid diff
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } while (seq > 0);
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen mail_index_view_ref_map(view, view->index->map);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int _view_lookup_uid(struct mail_index_view *view, uint32_t seq,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen const struct mail_index_record *rec_base, *rec;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uint32_t idx, left_idx, right_idx, record_size;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen i_assert(view->messages_count <= view->map->records_count);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* no messages available */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* we want uid or larger */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* we want uid or smaller */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainenstatic int _view_lookup_uid_range(struct mail_index_view *view,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen *first_seq_r = mail_index_bsearch_uid(view, first_uid, &left_idx, 1);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* optimization - binary lookup only from right side: */
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *last_seq_r = mail_index_bsearch_uid(view, last_uid, &left_idx, -1);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int _view_lookup_first(struct mail_index_view *view,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if ((flags_mask & MAIL_RECENT) != 0 && (flags & MAIL_RECENT) != 0)
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen LOW_UPDATE(view->map->hdr->first_recent_uid_lowwater);
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if ((flags_mask & MAIL_SEEN) != 0 && (flags & MAIL_SEEN) == 0)
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen LOW_UPDATE(view->map->hdr->first_unseen_uid_lowwater);
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if ((flags_mask & MAIL_DELETED) != 0 && (flags & MAIL_DELETED) != 0)
44c5e644cb413a6559bf2d4179cbe48f9a82f366Timo Sirainen LOW_UPDATE(view->map->hdr->first_deleted_uid_lowwater);
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if (mail_index_lookup_uid_range(view, low_uid, low_uid,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_close(struct mail_index_view *view)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenuint32_t mail_index_view_get_message_count(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_get_header(struct mail_index_view *view,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return mail_index_lookup_full(view, seq, &map, rec_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return view->methods.lookup_uid(view, seq, uid_r);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen /* FIXME: do data_id mapping conversion */
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen offset = view->index->extra_records[data_id].offset;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen return view->methods.lookup_uid_range(view, first_uid, last_uid,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return view->methods.lookup_first(view, flags, flags_mask, seq_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return view->methods.lookup_full(view, seq, map_r, rec_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenstatic struct mail_index_view_methods view_methods = {
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index)
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->log_view = mail_transaction_log_view_open(index->log);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->messages_count = view->map->records_count;