mail-index-view.c revision 7797aa2479e99aeb71057b7a2584b2cb72e4d3f8
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "buffer.h"
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include "file-lock.h"
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include "mail-index-view-private.h"
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen#include "mail-transaction-log.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_clone(struct mail_index_view *dest,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_view *src)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(dest, 0, sizeof(dest));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->methods = src->methods;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->index = src->index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->log_view = mail_transaction_log_view_open(src->index->log);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->indexid = src->indexid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->map = src->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->map->refcount++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->messages_count = src->messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->log_file_seq = src->log_file_seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest->log_file_offset = src->log_file_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void _view_close(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_view_unlock(view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_close(view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->log_syncs != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_free(view->log_syncs);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_unmap(view->index, view->map);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen mail_index_view_unref_maps(view);
ad850190d946d34966a56838cfdb216e021b5b5fTimo Sirainen if (view->map_refs != NULL)
ad850190d946d34966a56838cfdb216e021b5b5fTimo Sirainen buffer_free(view->map_refs);
ad850190d946d34966a56838cfdb216e021b5b5fTimo Sirainen i_free(view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mail_index_view_map_protect(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not head mapping, no need to lock */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!view->map_protected) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_map_lock_mprotect(view->index, view->map,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen F_RDLCK) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen view->map_protected = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_lock_head(struct mail_index_view *view, int update_index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen unsigned int lock_id;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->index->map))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
1098fc409a45e7603701dc94635927a673bee0c1Timo 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)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen return -1;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (mail_index_map(view->index, FALSE) <= 0) {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo 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;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (update_index) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (mail_index_lock_shared(view->index, TRUE, &lock_id) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen mail_index_unlock(view->index, view->lock_id);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen view->lock_id = lock_id;
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen }
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen i_assert(view->index->lock_type != F_UNLCK);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen /* mail_index_lock_shared() may have reopened the file,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen so do this after it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->map != view->index->map) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (mail_index_view_map_protect(view) < 0)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return -1;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return 0;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenint mail_index_view_lock(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_is_inconsistent(view))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (view->map != view->index->map) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (mail_index_view_map_protect(view) < 0)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return -1;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return mail_index_view_lock_head(view, FALSE);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (view->map_protected) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen (void)mail_index_map_lock_mprotect(view->index, view->map,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen F_UNLCK);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen view->map_protected = FALSE;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (view->lock_id != 0) {
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen mail_index_unlock(view->index, view->lock_id);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen view->lock_id = 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_is_inconsistent(struct mail_index_view *view)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->index->indexid != view->indexid)
1098fc409a45e7603701dc94635927a673bee0c1Timo 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)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return view->index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen{
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen view->transactions++;
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen}
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen{
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen i_assert(view->transactions > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->transactions--;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_map *map)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
37e6cf44d61a81c6839e3ab76234b54309d8d292Timo Sirainen const struct mail_index_map *const *maps;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen size_t i, size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen if (view->map_refs != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maps = buffer_get_data(view->map_refs, &size);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen size /= sizeof(*maps);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen for (i = 0; i < size; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (maps[i] == map)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen view->map_refs =
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen buffer_create_dynamic(default_pool, 128, (size_t)-1);
56f45b3f3ae20e5c933701f4657dda5ef1916855Timo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map->refcount++;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen buffer_append(view->map_refs, &map, sizeof(map));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen struct mail_index_map **maps;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen size_t i, size;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen if (view->map_refs == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen maps = buffer_get_modifyable_data(view->map_refs, &size);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen size /= sizeof(*maps);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen for (i = 0; i < size; i++)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen mail_index_unmap(view->index, maps[i]);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen buffer_set_used_size(view->map_refs, 0);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen}
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainenstatic uint32_t _view_get_message_count(struct mail_index_view *view)
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen{
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen return view->messages_count;
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen}
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenstatic int _view_get_header(struct mail_index_view *view,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const struct mail_index_header **hdr_r)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen{
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (mail_index_view_lock(view) < 0)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen return -1;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (view->map->hdr->messages_count == view->messages_count)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *hdr_r = view->map->hdr;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen else {
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen /* messages_count differs, use a modified copy.
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen FIXME: so might seen_messages_count, etc. and they're
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen more difficult to fix. maybe grab a copy of the header
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen when opening the view initially?.. */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen view->tmp_hdr_copy = *view->map->hdr;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen view->tmp_hdr_copy.messages_count = view->messages_count;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *hdr_r = &view->tmp_hdr_copy;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_map **map_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_record **rec_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_map *map;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen const struct mail_index_record *rec, *n_rec;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen uint32_t uid;
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen if (mail_index_view_lock(view) < 0)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return -1;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->map == view->index->map) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *map_r = view->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rec_r = rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* look for it in the head mapping */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map = view->index->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen uid = rec->uid;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen if (seq > view->index->hdr->messages_count)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq = view->index->hdr->messages_count;
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen if (seq == 0) {
f519e4c2ad4ef826f1b08f3e0138b9b287a52c80Timo Sirainen *map_r = view->map;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen *rec_r = rec;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen return 0;
d565eaa943f29a49b97230ced57eec40ee65b4f9Timo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen do {
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen // FIXME: we could be skipping more by uid diff
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq--;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen n_rec = MAIL_INDEX_MAP_IDX(map, seq);
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen if (n_rec->uid <= uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen } while (seq > 0);
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen if (n_rec->uid == uid) {
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen mail_index_view_ref_map(view, view->index->map);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen *map_r = view->index->map;
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen *rec_r = n_rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen } else {
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen *map_r = view->map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rec_r = rec;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo 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)
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen{
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_message_count(view));
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (mail_index_view_lock(view) < 0)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return -1;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen return 0;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen}
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainenstatic uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen uint32_t uid, uint32_t *left_idx_p,
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen int nearest_side)
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen{
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen const struct mail_index_record *rec_base, *rec;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen uint32_t idx, left_idx, right_idx, record_size;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen i_assert(view->messages_count <= view->map->records_count);
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen rec_base = view->map->records;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen record_size = view->map->hdr->record_size;
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen idx = left_idx = *left_idx_p;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen right_idx = view->messages_count;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (left_idx < right_idx) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen idx = (left_idx + right_idx) / 2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (rec->uid < uid)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen left_idx = idx+1;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen else if (rec->uid > uid)
a835194f9a9dae88528367a791cbc282589f6c01Timo Sirainen right_idx = idx;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen else
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen break;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (idx == view->messages_count) {
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen /* no messages available */
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen return 0;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen }
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen *left_idx_p = left_idx;
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen if (rec->uid != uid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (nearest_side > 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* we want uid or larger */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return rec->uid > uid ? idx+1 :
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen idx == view->messages_count-1 ? 0 : idx+2;
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen } else {
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen /* we want uid or smaller */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return rec->uid < uid ? idx + 1 : idx;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen }
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen }
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen
69bd816e46fdee6182d0cb2e4c6be32399a555c8Timo Sirainen return idx+1;
69bd816e46fdee6182d0cb2e4c6be32399a555c8Timo Sirainen}
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenstatic int _view_lookup_uid_range(struct mail_index_view *view,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen uint32_t first_uid, uint32_t last_uid,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen{
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen uint32_t left_idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(first_uid > 0);
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen i_assert(first_uid <= last_uid);
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (mail_index_view_lock(view) < 0)
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen return -1;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (last_uid >= view->map->hdr->next_uid) {
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen last_uid = view->map->hdr->next_uid-1;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (first_uid > last_uid) {
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen *first_seq_r = 0;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen *last_seq_r = 0;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen return 0;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen }
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen }
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen left_idx = 0;
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen *first_seq_r = mail_index_bsearch_uid(view, first_uid, &left_idx, 1);
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen if (*first_seq_r == 0 ||
f239eb76f77afcbc0bfc97c9b52b4407d1bc3fe6Timo Sirainen MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *first_seq_r = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *last_seq_r = 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return 0;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (first_uid == last_uid) {
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *last_seq_r = *first_seq_r;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return 0;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen /* optimization - binary lookup only from right side: */
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen *last_seq_r = mail_index_bsearch_uid(view, last_uid, &left_idx, -1);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen i_assert(*last_seq_r >= *first_seq_r);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return 0;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int _view_lookup_first(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_flags flags, uint8_t flags_mask,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen uint32_t *seq_r)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
0cea9b1f4fa0495a48f5f097e40492517d67e1baTimo Sirainen#define LOW_UPDATE(x) \
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
0cea9b1f4fa0495a48f5f097e40492517d67e1baTimo Sirainen const struct mail_index_record *rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq, low_uid = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *seq_r = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen if (mail_index_view_lock(view) < 0)
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen return -1;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if ((flags_mask & MAIL_RECENT) != 0 && (flags & MAIL_RECENT) != 0)
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen LOW_UPDATE(view->map->hdr->first_recent_uid_lowwater);
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen if ((flags_mask & MAIL_SEEN) != 0 && (flags & MAIL_SEEN) == 0)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen LOW_UPDATE(view->map->hdr->first_unseen_uid_lowwater);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if ((flags_mask & MAIL_DELETED) != 0 && (flags & MAIL_DELETED) != 0)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen LOW_UPDATE(view->map->hdr->first_deleted_uid_lowwater);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen if (low_uid == 1)
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen seq = 1;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen else {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (mail_index_lookup_uid_range(view, low_uid, low_uid,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen &seq, &seq) < 0)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen return -1;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (seq == 0)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen return 0;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen }
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen for (; seq <= view->messages_count; seq++) {
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *seq_r = seq;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen break;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainenstatic int _view_lookup_ext(struct mail_index_view *view, uint32_t seq,
6a8a4c9f530668cd8961b73d702856ed94f05f80Timo Sirainen uint32_t ext_id, const void **data_r)
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen{
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen const struct mail_index_ext *ext;
ba482d3624ca4f1b3d638e6e8470ba5134f21493Timo Sirainen const struct mail_index_record *rec;
ba482d3624ca4f1b3d638e6e8470ba5134f21493Timo Sirainen struct mail_index_map *map;
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen uint32_t idx, offset;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen int ret;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (rec == NULL ||
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen !mail_index_map_get_ext_idx(view->map, ext_id, &idx)) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *data_r = NULL;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return ret;
21455709020274a628faa9b9bd7839cb8efe3c73Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen ext = view->map->extensions->data;
21455709020274a628faa9b9bd7839cb8efe3c73Timo Sirainen ext += idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen offset = ext->record_offset;
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen *data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset);
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen return ret;
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainenvoid mail_index_view_close(struct mail_index_view *view)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen view->methods.close(view);
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenuint32_t mail_index_view_get_message_count(struct mail_index_view *view)
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen{
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen return view->messages_count;
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen}
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen
21455709020274a628faa9b9bd7839cb8efe3c73Timo Sirainenint mail_index_get_header(struct mail_index_view *view,
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen const struct mail_index_header **hdr_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen return view->methods.get_header(view, hdr_r);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen}
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen const struct mail_index_record **rec_r)
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen{
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen struct mail_index_map *map;
7981779f9aebd25728d3c26555d598ff842cf2e2Timo Sirainen
7981779f9aebd25728d3c26555d598ff842cf2e2Timo Sirainen return mail_index_lookup_full(view, seq, &map, rec_r);
7981779f9aebd25728d3c26555d598ff842cf2e2Timo Sirainen}
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
6fdf8b5e4e71a69f5974f59eec2b8c19bc421fe2Timo Sirainen struct mail_index_map **map_r,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const struct mail_index_record **rec_r)
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return view->methods.lookup_full(view, seq, map_r, rec_r);
6fdf8b5e4e71a69f5974f59eec2b8c19bc421fe2Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *uid_r)
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return view->methods.lookup_uid(view, seq, uid_r);
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen}
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen uint32_t first_uid, uint32_t last_uid,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
089756ceca55966f1a70e8591f6086026e51015cTimo Sirainen{
089756ceca55966f1a70e8591f6086026e51015cTimo Sirainen return view->methods.lookup_uid_range(view, first_uid, last_uid,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen first_seq_r, last_seq_r);
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen}
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen uint8_t flags_mask, uint32_t *seq_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen return view->methods.lookup_first(view, flags, flags_mask, seq_r);
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen}
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainenint mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
58be9d6bcc3800f5b3d76a064ee767fbe31a5a8aTimo Sirainen uint32_t ext_id, const void **data_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return view->methods.lookup_ext(view, seq, ext_id, data_r);
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainenstatic struct mail_index_view_methods view_methods = {
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen _view_close,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen _view_get_message_count,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen _view_get_header,
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen _view_lookup_full,
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen _view_lookup_uid,
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen _view_lookup_uid_range,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen _view_lookup_first,
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen _view_lookup_ext
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen};
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index)
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen{
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen struct mail_index_view *view;
62cfc346eb7b0a4fd9e1ab6edd63b98711161229Timo Sirainen
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen view = i_new(struct mail_index_view, 1);
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen view->methods = view_methods;
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen view->index = index;
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen view->log_view = mail_transaction_log_view_open(index->log);
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen view->indexid = index->indexid;
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen view->map = index->map;
72cbf33ae81fde08384d30c779ff540752d9256cTimo Sirainen view->map->refcount++;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen view->messages_count = view->map->records_count;
a817fdcc43aedf423e2134091d5f83f91d64bcc9Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_seq = view->map->log_file_seq;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_file_offset = view->map->log_file_offset;
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainen return view;
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainen}
dbd9604da561399cc6255289d5b6f6f662ab2d00Timo Sirainen