mail-index-view.c revision ff7257145f317d6ca44a9402427bb74c34b999a9
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_clone(struct mail_index_view *dest,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct mail_index_view *src)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen memset(dest, 0, sizeof(dest));
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen dest->refcount = 1;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen dest->v = src->v;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->index = src->index;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen if (src->log_view != NULL) {
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen dest->log_view =
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen mail_transaction_log_view_open(src->index->log);
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->indexid = src->indexid;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->map = src->map;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen if (dest->map != NULL)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen dest->map->refcount++;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen dest->hdr = src->hdr;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen dest->broken_counters = src->broken_counters;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->log_file_seq = src->log_file_seq;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->log_file_offset = src->log_file_offset;
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen i_array_init(&dest->module_contexts,
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen I_MIN(5, mail_index_module_register.id));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenvoid mail_index_view_ref(struct mail_index_view *view)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->refcount++;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic void _view_close(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_assert(view->refcount == 0);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_view_unlock(view);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_transaction_log_view_close(&view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen if (array_is_created(&view->syncs_done))
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen array_free(&view->syncs_done);
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen if (array_is_created(&view->syncs_hidden))
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen array_free(&view->syncs_hidden);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_index_unmap(view->index, &view->map);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (array_is_created(&view->map_refs)) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen mail_index_view_unref_maps(view);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen array_free(&view->map_refs);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen }
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen array_free(&view->module_contexts);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#ifdef DEBUG
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainenstatic void mail_index_view_check_nextuid(struct mail_index_view *view)
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen{
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen struct mail_index_record *rec;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen if (view->hdr.messages_count == 0)
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen return;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, view->hdr.messages_count-1);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen i_assert(rec->uid < view->hdr.next_uid);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen}
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#endif
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenint mail_index_view_lock_head(struct mail_index_view *view, bool update_index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen unsigned int lock_id;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#ifdef DEBUG
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen mail_index_view_check_nextuid(view);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#endif
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen if (mail_index_view_is_inconsistent(view))
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen return -1;
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->index->map))
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen return 0;
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_index_is_locked(view->index, view->lock_id)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lock_shared(view->index, update_index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &view->lock_id) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map(view->index, FALSE) <= 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen if (view->index->indexid != view->indexid) {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* index was rebuilt */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view->inconsistent = TRUE;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return -1;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen } else if (update_index) {
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen if (mail_index_lock_shared(view->index, TRUE, &lock_id) < 0)
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen return -1;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen mail_index_unlock(view->index, view->lock_id);
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen view->lock_id = lock_id;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen i_assert(view->index->lock_type != F_UNLCK);
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainenint mail_index_view_lock(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
eaa36e8058dd6ca4f729f4d0667f8be9912ab473Timo Sirainen if (view->map != view->index->map) {
eaa36e8058dd6ca4f729f4d0667f8be9912ab473Timo Sirainen /* not head mapping, no need to lock */
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen if (mail_index_view_is_inconsistent(view))
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen return -1;
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#ifdef DEBUG
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen mail_index_view_check_nextuid(view);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#endif
eaa36e8058dd6ca4f729f4d0667f8be9912ab473Timo Sirainen return 0;
eaa36e8058dd6ca4f729f4d0667f8be9912ab473Timo Sirainen }
eaa36e8058dd6ca4f729f4d0667f8be9912ab473Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen return mail_index_view_lock_head(view, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#ifdef DEBUG
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen mail_index_view_check_nextuid(view);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen#endif
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen if (view->lock_id != 0 && view->transactions == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_unlock(view->index, view->lock_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->lock_id = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_view_is_inconsistent(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (view->index->indexid != view->indexid)
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return view->inconsistent;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return view->index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->transactions++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->transactions > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->transactions--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct mail_index_map *map)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen struct mail_index_map *const *maps;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen unsigned int i, count;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (array_is_created(&view->map_refs)) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen maps = array_get(&view->map_refs, &count);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen /* if map is already referenced, do nothing */
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen for (i = 0; i < count; i++) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (maps[i] == map)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen } else {
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_array_init(&view->map_refs, 4);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* reference the given mapping. the reference is dropped when the view
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen is synchronized or closed. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen map->refcount++;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen array_append(&view->map_refs, &map, 1);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_index_map **maps;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen unsigned int i, count;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (!array_is_created(&view->map_refs))
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen maps = array_get_modifiable(&view->map_refs, &count);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen for (i = 0; i < count; i++)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_index_unmap(view->index, &maps[i]);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen array_clear(&view->map_refs);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenstatic uint32_t _view_get_messages_count(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen return view->hdr.messages_count;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainenstatic const struct mail_index_header *
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen_view_get_header(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen if (view->broken_counters)
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen mail_index_view_recalc_counters(view);
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen return &view->hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mail_index_map **map_r,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct mail_index_record **rec_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_map *map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen const struct mail_index_record *rec, *head_rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (mail_index_view_lock(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* look up the record */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen if (rec->uid == 0) {
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen mail_index_set_error(view->index, "Corrupted Index file %s: "
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen "Record [%u].uid=0", view->index->filepath, seq);
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen mail_index_mark_corrupted(view->index);
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen return -1;
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->map == view->index->map) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* view's mapping is latest. we can use it directly. */
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen *map_r = view->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rec_r = rec;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* look up the record from head mapping. it may contain some changes. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* start looking up from the same sequence as in the old view.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if there are no expunges, it's there. otherwise it's somewhere
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen before (since records can't be inserted).
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen usually there are only a few expunges, so just going downwards from
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen our initial sequence position is probably faster than binary
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen search. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq > view->index->hdr->messages_count)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq = view->index->hdr->messages_count;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (seq == 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* everything is expunged from head. use the old record. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen *map_r = view->map;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen *rec_r = rec;
5529671faac3c5672a948be93091056736c7afffTimo Sirainen return 0;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen map = view->index->map;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen do {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen seq--;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen head_rec = MAIL_INDEX_MAP_IDX(map, seq);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (head_rec->uid <= rec->uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen } while (seq > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (head_rec->uid == rec->uid) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* found it. use it. reference the index mapping so that the
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen returned record doesn't get invalidated after next sync. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen mail_index_view_ref_map(view, view->index->map);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen *map_r = view->index->map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen *rec_r = head_rec;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen return 1;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen } else {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* expuned from head. use the old record. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen *map_r = view->map;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen *rec_r = rec;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen return 0;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int _view_lookup_uid(struct mail_index_view *view, uint32_t seq,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t *uid_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (mail_index_view_lock(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen uint32_t uid, uint32_t left_idx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int nearest_side)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen const struct mail_index_record *rec_base, *rec;
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen uint32_t idx, right_idx, record_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen i_assert(view->hdr.messages_count <= view->map->records_count);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen if (uid == 1) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen /* optimization: the message can be only the first one */
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen return 1;
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen }
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen rec_base = view->map->records;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen record_size = view->map->hdr.record_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen idx = left_idx;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen right_idx = view->hdr.messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (left_idx < right_idx) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen idx = (left_idx + right_idx) / 2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (rec->uid < uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen left_idx = idx+1;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen else if (rec->uid > uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen right_idx = idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen i_assert(idx < view->hdr.messages_count);
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (rec->uid != uid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (nearest_side > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we want uid or larger */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen return rec->uid > uid ? idx+1 :
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen idx == view->hdr.messages_count-1 ? 0 : idx+2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we want uid or smaller */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen return rec->uid < uid ? idx + 1 : idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return idx+1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int _view_lookup_uid_range(struct mail_index_view *view,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t first_uid, uint32_t last_uid,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(first_uid > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(first_uid <= last_uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (mail_index_view_lock(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen if (view->hdr.messages_count == 0) {
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen *first_seq_r = *last_seq_r = 0;
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen return 0;
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen }
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen *first_seq_r = mail_index_bsearch_uid(view, first_uid, 0, 1);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen if (*first_seq_r == 0 ||
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen *first_seq_r = *last_seq_r = 0;
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen return 0;
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen }
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen if (last_uid >= view->map->hdr.next_uid-1) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen /* we want the last message */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen last_uid = view->map->hdr.next_uid-1;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen if (first_uid > last_uid) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen *first_seq_r = *last_seq_r = 0;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen return 0;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen *last_seq_r = view->hdr.messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen if (first_uid == last_uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *last_seq_r = *first_seq_r;
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen else {
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen /* optimization - binary lookup only from right side: */
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen *last_seq_r = mail_index_bsearch_uid(view, last_uid,
e107b65e7d36ae18571de61a4dbd8609b2883a21Timo Sirainen *first_seq_r - 1, -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(*last_seq_r >= *first_seq_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int _view_lookup_first(struct mail_index_view *view,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen enum mail_flags flags, uint8_t flags_mask,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t *seq_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define LOW_UPDATE(x) \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_record *rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq, low_uid = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *seq_r = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen if (mail_index_view_lock(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags_mask & MAIL_RECENT) != 0 && (flags & MAIL_RECENT) != 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen LOW_UPDATE(view->map->hdr.first_recent_uid_lowwater);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags_mask & MAIL_SEEN) != 0 && (flags & MAIL_SEEN) == 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen LOW_UPDATE(view->map->hdr.first_unseen_uid_lowwater);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags_mask & MAIL_DELETED) != 0 && (flags & MAIL_DELETED) != 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen LOW_UPDATE(view->map->hdr.first_deleted_uid_lowwater);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (low_uid == 1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup_uid_range(view, low_uid, low_uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &seq, &seq) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen i_assert(view->hdr.messages_count <= view->map->records_count);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen for (; seq <= view->hdr.messages_count; seq++) {
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *seq_r = seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int _view_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void **data_r)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen const struct mail_index_ext *ext;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const struct mail_index_record *rec;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint32_t idx, offset;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen int ret;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if ((ret = mail_index_lookup_full(view, seq, map_r, &rec)) < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return -1;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (rec == NULL || !mail_index_map_get_ext_idx(*map_r, ext_id, &idx)) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen *data_r = NULL;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return ret;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen ext = array_idx(&(*map_r)->extensions, idx);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen offset = ext->record_offset;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen *data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return ret;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int _view_get_header_ext(struct mail_index_view *view,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_map *map, uint32_t ext_id,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void **data_r, size_t *data_size_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const struct mail_index_ext *ext;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t idx;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* if we have a mapping, the view where it's from is already locked */
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (map == NULL) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* no mapping given, use head mapping */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen map = view->index->map;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (!mail_index_map_get_ext_idx(map, ext_id, &idx)) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* extension doesn't exist in this index file */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen *data_r = NULL;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen *data_size_r = 0;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return 0;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen ext = array_idx(&map->extensions, idx);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen *data_r = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *data_size_r = ext->hdr_size;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_view_close(struct mail_index_view **_view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_index_view *view = *_view;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_view = NULL;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (--view->refcount > 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen i_assert(view->transactions == 0);
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen mail_index_view_unlock(view);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen view->v.close(view);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenuint32_t mail_index_view_get_messages_count(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.get_messages_count(view);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainenconst struct mail_index_header *
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainenmail_index_get_header(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.get_header(view);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct mail_index_record **rec_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mail_index_map *map;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return mail_index_lookup_full(view, seq, &map, rec_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_map **map_r,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const struct mail_index_record **rec_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_full(view, seq, map_r, rec_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenint mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct mail_index_map *map;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const void *data;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen const unsigned char *keyword_data;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const unsigned int *keyword_idx_map;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unsigned int i, j, keyword_count, index_idx;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t ext_id, idx;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen uint16_t record_size;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen int ret;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_clear(keyword_idx);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* get the keywords data. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ext_id = view->index->keywords_ext_id;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ret = mail_index_lookup_ext_full(view, seq, ext_id, &map, &data);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (ret < 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return -1;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (data == NULL) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* no keywords at all in index */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return ret;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen (void)mail_index_ext_get_size(view, ext_id, map, NULL,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen &record_size, NULL);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* keyword_idx_map[] contains file => index keyword mapping */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (!array_is_created(&map->keyword_idx_map)) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keyword_idx_map = NULL;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keyword_count = 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen } else {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keyword_idx_map = array_get(&map->keyword_idx_map,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen &keyword_count);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen keyword_data = data;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen for (i = 0, idx = 0; i < record_size; i++) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* first do the quick check to see if there's keywords at all */
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (keyword_data[i] == 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen continue;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen idx = i * CHAR_BIT;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen for (j = 0; j < CHAR_BIT; j++, idx++) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if ((keyword_data[i] & (1 << j)) == 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen continue;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (idx >= keyword_count) {
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen /* keyword header was updated, parse it again
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen it so we know what this keyword is called */
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen if (mail_index_map_parse_keywords(view->index,
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen map) < 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return -1;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (!array_is_created(&map->keyword_idx_map))
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return ret;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* pointer may have changed. update it. */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keyword_idx_map =
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_get(&map->keyword_idx_map,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen &keyword_count);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (idx >= keyword_count) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* extra bits set in keyword bytes.
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen shouldn't happen, but just ignore. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen break;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen index_idx = keyword_idx_map[idx];
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_append(keyword_idx, &index_idx, 1);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return ret;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint32_t *uid_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_uid(view, seq, uid_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t first_uid, uint32_t last_uid,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_uid_range(view, first_uid, last_uid,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen first_seq_r, last_seq_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen uint8_t flags_mask, uint32_t *seq_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_first(view, flags, flags_mask, seq_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenint mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen uint32_t ext_id, const void **data_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_map *map;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_ext_full(view, seq, ext_id, &map, data_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void **data_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.lookup_ext_full(view, seq, ext_id, map_r, data_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_get_header_ext(struct mail_index_view *view, uint32_t ext_id,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void **data_r, size_t *data_size_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.get_header_ext(view, NULL, ext_id, data_r, data_size_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_map_get_header_ext(struct mail_index_view *view,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_map *map, uint32_t ext_id,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void **data_r, size_t *data_size_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen return view->v.get_header_ext(view, map, ext_id, data_r, data_size_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainenint mail_index_ext_get_size(struct mail_index_view *view __attr_unused__,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen uint32_t ext_id, struct mail_index_map *map,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen uint32_t *hdr_size_r, uint16_t *record_size_r,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen uint16_t *record_align_r)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen{
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen const struct mail_index_ext *ext;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen uint32_t idx;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen i_assert(map != NULL);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (!mail_index_map_get_ext_idx(map, ext_id, &idx)) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen /* extension doesn't exist in this index file */
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (hdr_size_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *hdr_size_r = 0;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (record_size_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *record_size_r = 0;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (record_align_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *record_align_r = 0;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen return 0;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen }
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen ext = array_idx(&map->extensions, idx);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (hdr_size_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *hdr_size_r = ext->hdr_size;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (record_size_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *record_size_r = ext->record_size;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen if (record_align_r != NULL)
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *record_align_r = ext->record_align;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen return 0;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen}
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenstatic struct mail_index_view_vfuncs view_vfuncs = {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_close,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen _view_get_messages_count,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_get_header,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_full,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_uid,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_uid_range,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen _view_lookup_first,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen _view_lookup_ext_full,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen _view_get_header_ext
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen};
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mail_index_view *view;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
cdb3c8e1054f4ea382bb6c1557fd28d067f90e5eTimo Sirainen i_assert(index->map != NULL);
cdb3c8e1054f4ea382bb6c1557fd28d067f90e5eTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view = i_new(struct mail_index_view, 1);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->refcount = 1;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen view->v = view_vfuncs;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->index = index;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->log_view = mail_transaction_log_view_open(index->log);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->indexid = index->indexid;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->map = index->map;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->map->refcount++;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->hdr = view->map->hdr;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->log_file_seq = view->map->hdr.log_file_seq;
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen view->log_file_offset =
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen I_MIN(view->map->hdr.log_file_int_offset,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->map->hdr.log_file_ext_offset);
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen i_array_init(&view->module_contexts,
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen I_MIN(5, mail_index_module_register.id));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return view;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenconst struct mail_index_ext *
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t idx;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (!mail_index_map_get_ext_idx(view->map, ext_id, &idx))
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen return array_idx(&view->map->extensions, idx);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}