mail-index-view.c revision 7c5b51bdf43a98e12c654ad437e0b258c5fffbc1
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "file-lock.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{
75e8db37023fde9ac15550bf426be8719d94a821Timo Sirainen memset(dest, 0, sizeof(dest));
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen dest->methods = src->methods;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen dest->index = src->index;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->log_view = mail_transaction_log_view_open(src->index->log);
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen dest->indexid = src->indexid;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen dest->map = src->map;
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen dest->map->refcount++;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->messages_count = src->messages_count;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
e627cdc5ef30d87959f9510832427e33a2f1d84aTimo Sirainen dest->log_file_seq = src->log_file_seq;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen dest->log_file_offset = src->log_file_offset;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen}
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic void _view_close(struct mail_index_view *view)
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen{
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_index_view_unlock(view);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_transaction_log_view_close(view->log_view);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen if (view->log_syncs != NULL)
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen buffer_free(view->log_syncs);
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen mail_index_unmap(view->index, view->map);
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen mail_index_view_unref_maps(view);
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen if (view->map_refs != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_free(view->map_refs);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(view);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic int mail_index_view_map_protect(struct mail_index_view *view)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* not head mapping, no need to lock */
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if (!view->map_protected) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map_lock_mprotect(view->index, view->map,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen F_RDLCK) < 0)
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen return -1;
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen view->map_protected = TRUE;
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainenint mail_index_view_lock_head(struct mail_index_view *view, int update_index)
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen{
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen unsigned int lock_id;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->index->map))
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen return 0;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen
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 &view->lock_id) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map(view->index, FALSE) <= 0) {
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen view->inconsistent = TRUE;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen return -1;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->index->indexid != view->indexid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* index was rebuilt */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (update_index) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lock_shared(view->index, TRUE, &lock_id) < 0)
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen return -1;
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen mail_index_unlock(view->index, view->lock_id);
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen view->lock_id = lock_id;
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen }
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen i_assert(view->index->lock_type != F_UNLCK);
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* mail_index_lock_shared() may have reopened the file,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen so do this after it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->map != view->index->map) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_map_protect(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_lock(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (mail_index_view_is_inconsistent(view))
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (view->map != view->index->map) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if (mail_index_view_map_protect(view) < 0)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return -1;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen return 0;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen return mail_index_view_lock_head(view, FALSE);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (view->map_protected) {
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen (void)mail_index_map_lock_mprotect(view->index, view->map,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen F_UNLCK);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen view->map_protected = FALSE;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (view->lock_id != 0) {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen mail_index_unlock(view->index, view->lock_id);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen view->lock_id = 0;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint mail_index_view_is_inconsistent(struct mail_index_view *view)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (view->index->indexid != view->indexid)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen view->inconsistent = TRUE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return view->inconsistent;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view)
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return view->index;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->transactions++;
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen{
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen i_assert(view->transactions > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen view->transactions--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct mail_index_map *map)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_map *const *maps;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen size_t i, size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view->map_refs != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maps = buffer_get_data(view->map_refs, &size);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen size /= sizeof(*maps);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (i = 0; i < size; i++) {
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (maps[i] == map)
24ec3e51a1bd7aaf09c92a7ff7498e225796d7e0Timo Sirainen return;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen }
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen } else {
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen view->map_refs =
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen buffer_create_dynamic(default_pool, 128, (size_t)-1);
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen }
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen map->refcount++;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen buffer_append(view->map_refs, &map, sizeof(map));
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen{
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen struct mail_index_map **maps;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t i, size;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (view->map_refs == NULL)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maps = buffer_get_modifyable_data(view->map_refs, &size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size /= sizeof(*maps);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < size; i++)
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen mail_index_unmap(view->index, maps[i]);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen buffer_set_used_size(view->map_refs, 0);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen}
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic uint32_t _view_get_message_count(struct mail_index_view *view)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen{
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen return view->messages_count;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen}
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic int _view_get_header(struct mail_index_view *view,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const struct mail_index_header **hdr_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (mail_index_view_lock(view) < 0)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen return -1;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view->map->hdr->messages_count == view->messages_count)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen *hdr_r = view->map->hdr;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen else {
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?.. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->tmp_hdr_copy = *view->map->hdr;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->tmp_hdr_copy.messages_count = view->messages_count;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen *hdr_r = &view->tmp_hdr_copy;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen return 0;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenstatic int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen struct mail_index_map **map_r,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen const struct mail_index_record **rec_r)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen struct mail_index_map *map;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const struct mail_index_record *rec, *n_rec;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen uint32_t uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if (mail_index_view_lock(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (view->map == view->index->map) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *map_r = view->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rec_r = rec;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen return 1;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen }
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen return -1;
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* look for it in the head mapping */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map = view->index->map;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen uid = rec->uid;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if (seq > view->index->hdr->messages_count)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq = view->index->hdr->messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq == 0) {
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen *map_r = view->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rec_r = rec;
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen do {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen // FIXME: we could be skipping more by uid diff
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen seq--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen n_rec = MAIL_INDEX_MAP_IDX(map, seq);
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen if (n_rec->uid <= uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } while (seq > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (n_rec->uid == uid) {
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen mail_index_view_ref_map(view, view->index->map);
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen *map_r = view->index->map;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen *rec_r = n_rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen *map_r = view->map;
f7992ce3ff735b8eb2f59b07f1d565dafcc0452eTimo Sirainen *rec_r = rec;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int _view_lookup_uid(struct mail_index_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *uid_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (mail_index_view_lock(view) < 0)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return -1;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return 0;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen}
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uint32_t uid, uint32_t *left_idx_p,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen int nearest_side)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen{
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen const struct mail_index_record *rec_base, *rec;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uint32_t idx, left_idx, right_idx, record_size;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen i_assert(view->messages_count <= view->map->records_count);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen rec_base = view->map->records;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen record_size = view->map->hdr->record_size;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen idx = left_idx = *left_idx_p;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen right_idx = view->messages_count;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen while (left_idx < right_idx) {
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen idx = (left_idx + right_idx) / 2;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (rec->uid < uid)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen left_idx = idx+1;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen else if (rec->uid > uid)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen right_idx = idx;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen else
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen break;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (idx == view->messages_count) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* no messages available */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return 0;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen *left_idx_p = left_idx;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (rec->uid != uid) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen if (nearest_side > 0) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* we want uid or larger */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return rec->uid > uid ? idx+1 :
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen idx == view->messages_count-1 ? 0 : idx+2;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen } else {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen /* we want uid or smaller */
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return rec->uid < uid ? idx + 1 : idx;
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen }
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen return idx+1;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen}
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainenstatic int _view_lookup_uid_range(struct mail_index_view *view,
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen uint32_t first_uid, uint32_t last_uid,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen{
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen uint32_t left_idx;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen i_assert(first_uid > 0);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen i_assert(first_uid <= last_uid);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (mail_index_view_lock(view) < 0)
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return -1;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (last_uid >= view->map->hdr->next_uid) {
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen last_uid = view->map->hdr->next_uid-1;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen if (first_uid > last_uid) {
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen *first_seq_r = 0;
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen *last_seq_r = 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return 0;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen }
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen }
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen left_idx = 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen *first_seq_r = mail_index_bsearch_uid(view, first_uid, &left_idx, 1);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (*first_seq_r == 0 ||
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen *first_seq_r = 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen *last_seq_r = 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return 0;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen }
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen if (first_uid == last_uid) {
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen *last_seq_r = *first_seq_r;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* optimization - binary lookup only from right side: */
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen *last_seq_r = mail_index_bsearch_uid(view, last_uid, &left_idx, -1);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen i_assert(*last_seq_r >= *first_seq_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int _view_lookup_first(struct mail_index_view *view,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen enum mail_flags flags, uint8_t flags_mask,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t *seq_r)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen#define LOW_UPDATE(x) \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const struct mail_index_record *rec;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen uint32_t seq, low_uid = 1;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *seq_r = 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_index_view_lock(view) < 0)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen return -1;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
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
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if (low_uid == 1)
44c5e644cb413a6559bf2d4179cbe48f9a82f366Timo Sirainen seq = 1;
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen else {
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen if (mail_index_lookup_uid_range(view, low_uid, low_uid,
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen &seq, &seq) < 0)
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen return -1;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (seq == 0)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen for (; seq <= view->messages_count; seq++) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen *seq_r = seq;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen break;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen return 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid mail_index_view_close(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen view->methods.close(view);
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenuint32_t mail_index_view_get_message_count(struct mail_index_view *view)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return view->messages_count;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_get_header(struct mail_index_view *view,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const struct mail_index_header **hdr_r)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return view->methods.get_header(view, hdr_r);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const struct mail_index_record **rec_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mail_index_map *map;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return mail_index_lookup_full(view, seq, &map, rec_r);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint32_t *uid_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return view->methods.lookup_uid(view, seq, uid_r);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen}
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint32_t data_id, const void **data_r)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen{
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const struct mail_index_record *rec;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen struct mail_index_map *map;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen uint32_t offset;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen int ret;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen return -1;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen if (rec == NULL) {
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen *data_r = NULL;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen return ret;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen }
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen /* FIXME: do data_id mapping conversion */
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen offset = view->index->extra_records[data_id].offset;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen *data_r = CONST_PTR_OFFSET(rec, offset);
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen return ret;
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen}
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen uint32_t first_uid, uint32_t last_uid,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen{
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen return view->methods.lookup_uid_range(view, first_uid, last_uid,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen first_seq_r, last_seq_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen}
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen uint8_t flags_mask, uint32_t *seq_r)
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen{
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return view->methods.lookup_first(view, flags, flags_mask, seq_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen}
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen struct mail_index_map **map_r,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen const struct mail_index_record **rec_r)
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen{
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen return view->methods.lookup_full(view, seq, map_r, rec_r);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen}
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenstatic struct mail_index_view_methods view_methods = {
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen _view_close,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen _view_get_message_count,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen _view_get_header,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_full,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen _view_lookup_uid,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_uid_range,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen _view_lookup_first
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen};
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen struct mail_index_view *view;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view = i_new(struct mail_index_view, 1);
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->methods = view_methods;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->index = index;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->log_view = mail_transaction_log_view_open(index->log);
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->indexid = index->indexid;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->map = index->map;
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen view->map->refcount++;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen view->messages_count = view->map->records_count;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen view->log_file_seq = view->map->log_file_seq;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen view->log_file_offset = view->map->log_file_offset;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen return view;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen