mail-index-view.c revision 6d25922a089626f5535d51358e33d3337783a410
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "lib.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "array.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "buffer.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-index-view-private.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#include "mail-transaction-log.h"
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_index_view_clone(struct mail_index_view *dest,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_view *src)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen memset(dest, 0, sizeof(dest));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->refcount = 1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->v = src->v;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen dest->index = src->index;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (src->log_view != NULL) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->log_view =
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_transaction_log_view_open(src->index->log);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->indexid = src->indexid;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->map = src->map;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen if (dest->map != NULL)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->map->refcount++;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->hdr = src->hdr;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen dest->broken_counters = src->broken_counters;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->log_file_seq = src->log_file_seq;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen dest->log_file_offset = src->log_file_offset;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_index_view_ref(struct mail_index_view *view)
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->refcount++;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainenstatic void _view_close(struct mail_index_view *view)
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen{
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen i_assert(view->refcount == 0);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen mail_index_view_unlock(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_transaction_log_view_close(&view->log_view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (array_is_created(&view->syncs_done))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_free(&view->syncs_done);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (array_is_created(&view->syncs_hidden))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_free(&view->syncs_hidden);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_unmap(view->index, &view->map);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (array_is_created(&view->map_refs)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_view_unref_maps(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_free(&view->map_refs);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_free(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#ifdef DEBUG
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic void mail_index_view_check_nextuid(struct mail_index_view *view)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_index_record *rec;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->hdr.messages_count == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, view->hdr.messages_count-1);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(rec->uid < view->hdr.next_uid);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#endif
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_index_view_lock_head(struct mail_index_view *view, bool update_index)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen unsigned int lock_id;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#ifdef DEBUG
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_view_check_nextuid(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#endif
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_is_inconsistent(view))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (MAIL_INDEX_MAP_IS_IN_MEMORY(view->index->map))
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (!mail_index_is_locked(view->index, view->lock_id)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_lock_shared(view->index, update_index,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &view->lock_id) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_map(view->index, FALSE) <= 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->inconsistent = TRUE;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->index->indexid != view->indexid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* index was rebuilt */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->inconsistent = TRUE;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else if (update_index) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_lock_shared(view->index, TRUE, &lock_id) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_unlock(view->index, view->lock_id);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->lock_id = lock_id;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(view->index->lock_type != F_UNLCK);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_index_view_lock(struct mail_index_view *view)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen if (view->map != view->index->map) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* not head mapping, no need to lock */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_is_inconsistent(view))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen#ifdef DEBUG
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen mail_index_view_check_nextuid(view);
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen#endif
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen return 0;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen }
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen return mail_index_view_lock_head(view, FALSE);
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#ifdef DEBUG
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_view_check_nextuid(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen#endif
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->lock_id != 0 && view->transactions == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_unlock(view->index, view->lock_id);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->lock_id = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenbool mail_index_view_is_inconsistent(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->index->indexid != view->indexid)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->inconsistent = TRUE;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->inconsistent;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->index;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->transactions++;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view)
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen{
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen i_assert(view->transactions > 0);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen view->transactions--;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen}
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainenstatic void mail_index_view_ref_map(struct mail_index_view *view,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen struct mail_index_map *map)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen struct mail_index_map *const *maps;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen unsigned int i, count;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen if (array_is_created(&view->map_refs)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen maps = array_get(&view->map_refs, &count);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* if map is already referenced, do nothing */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (i = 0; i < count; i++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (maps[i] == map)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_array_init(&view->map_refs, 4);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* reference the given mapping. the reference is dropped when the view
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen is synchronized or closed. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen map->refcount++;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_append(&view->map_refs, &map, 1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_index_view_unref_maps(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_index_map **maps;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen unsigned int i, count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (!array_is_created(&view->map_refs))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen maps = array_get_modifiable(&view->map_refs, &count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (i = 0; i < count; i++)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_unmap(view->index, &maps[i]);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_clear(&view->map_refs);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic uint32_t _view_get_messages_count(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->hdr.messages_count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic const struct mail_index_header *
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen_view_get_header(struct mail_index_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->broken_counters)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_view_recalc_counters(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return &view->hdr;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int _view_lookup_full(struct mail_index_view *view, uint32_t seq,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_index_map **map_r,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_record **rec_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_index_map *map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_record *rec, *head_rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_lock(view) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* look up the record */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (rec->uid == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_set_error(view->index, "Corrupted Index file %s: "
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "Record [%u].uid=0", view->index->filepath, seq);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_mark_corrupted(view->index);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->map == view->index->map) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* view's mapping is latest. we can use it directly. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *map_r = view->map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *rec_r = rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* look up the record from head mapping. it may contain some changes. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* start looking up from the same sequence as in the old view.
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if there are no expunges, it's there. otherwise it's somewhere
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen before (since records can't be inserted).
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen usually there are only a few expunges, so just going downwards from
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen our initial sequence position is probably faster than binary
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen search. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (seq > view->index->hdr->messages_count)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen seq = view->index->hdr->messages_count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (seq == 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* everything is expunged from head. use the old record. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *map_r = view->map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *rec_r = rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen map = view->index->map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen do {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen seq--;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen head_rec = MAIL_INDEX_MAP_IDX(map, seq);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (head_rec->uid <= rec->uid)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } while (seq > 0);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (head_rec->uid == rec->uid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* found it. use it. reference the index mapping so that the
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen returned record doesn't get invalidated after next sync. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen mail_index_view_ref_map(view, view->index->map);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *map_r = view->index->map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *rec_r = head_rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* expuned from head. use the old record. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *map_r = view->map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *rec_r = rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int _view_lookup_uid(struct mail_index_view *view, uint32_t seq,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t *uid_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_lock(view) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *uid_r = MAIL_INDEX_MAP_IDX(view->map, seq-1)->uid;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic uint32_t mail_index_bsearch_uid(struct mail_index_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t uid, uint32_t left_idx,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen int nearest_side)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_record *rec_base, *rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t idx, right_idx, record_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(view->hdr.messages_count <= view->map->records_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (uid == 1) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* optimization: the message can be only the first one */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->hdr.messages_count == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen rec_base = view->map->records;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen record_size = view->map->hdr.record_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen idx = left_idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen right_idx = view->hdr.messages_count;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen while (left_idx < right_idx) {
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen idx = (left_idx + right_idx) / 2;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (rec->uid < uid)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen left_idx = idx+1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else if (rec->uid > uid)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen right_idx = idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen else
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (idx == view->hdr.messages_count) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* left_idx was initially messages_count */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (idx == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen idx--;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen rec = CONST_PTR_OFFSET(rec_base, idx * record_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (rec->uid != uid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (nearest_side > 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we want uid or larger */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return rec->uid > uid ? idx+1 :
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen idx == view->hdr.messages_count-1 ? 0 : idx+2;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we want uid or smaller */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return rec->uid < uid ? idx + 1 : idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return idx+1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int _view_lookup_uid_range(struct mail_index_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t first_uid, uint32_t last_uid,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen i_assert(first_uid > 0);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(first_uid <= last_uid);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_view_lock(view) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *first_seq_r = mail_index_bsearch_uid(view, first_uid, 0, 1);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen if (*first_seq_r == 0 ||
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen MAIL_INDEX_MAP_IDX(view->map, *first_seq_r-1)->uid > last_uid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *first_seq_r = *last_seq_r = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen }
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (last_uid >= view->map->hdr.next_uid-1) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we want the last message */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen last_uid = view->map->hdr.next_uid-1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (first_uid > last_uid) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *first_seq_r = *last_seq_r = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *last_seq_r = view->hdr.messages_count;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (first_uid == last_uid) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *last_seq_r = *first_seq_r;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen return 0;
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen }
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen /* optimization - binary lookup only from right side: */
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen *last_seq_r = mail_index_bsearch_uid(view, last_uid,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *first_seq_r + 1, -1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(*last_seq_r >= *first_seq_r);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int _view_lookup_first(struct mail_index_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen enum mail_flags flags, uint8_t flags_mask,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t *seq_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#define LOW_UPDATE(x) \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen STMT_START { if ((x) > low_uid) low_uid = x; } STMT_END
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_index_record *rec;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t seq, low_uid = 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *seq_r = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_view_lock(view) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((flags_mask & MAIL_RECENT) != 0 && (flags & MAIL_RECENT) != 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen LOW_UPDATE(view->map->hdr.first_recent_uid_lowwater);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((flags_mask & MAIL_SEEN) != 0 && (flags & MAIL_SEEN) == 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen LOW_UPDATE(view->map->hdr.first_unseen_uid_lowwater);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((flags_mask & MAIL_DELETED) != 0 && (flags & MAIL_DELETED) != 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen LOW_UPDATE(view->map->hdr.first_deleted_uid_lowwater);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (low_uid == 1)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen seq = 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen else {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_lookup_uid_range(view, low_uid, low_uid,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen &seq, &seq) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (seq == 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(view->hdr.messages_count <= view->map->records_count);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen for (; seq <= view->hdr.messages_count; seq++) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((rec->flags & flags_mask) == (uint8_t)flags) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *seq_r = seq;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen break;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstatic int _view_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen const void **data_r)
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen{
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen const struct mail_index_ext *ext;
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen const struct mail_index_record *rec;
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen uint32_t idx, offset;
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen int ret;
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((ret = mail_index_lookup_full(view, seq, map_r, &rec)) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (rec == NULL || !mail_index_map_get_ext_idx(*map_r, ext_id, &idx)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *data_r = NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return ret;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ext = array_idx(&(*map_r)->extensions, idx);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen offset = ext->record_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *data_r = offset == 0 ? NULL : CONST_PTR_OFFSET(rec, offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic int _view_get_header_ext(struct mail_index_view *view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_map *map, uint32_t ext_id,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void **data_r, size_t *data_size_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const struct mail_index_ext *ext;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t idx;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* if we have a mapping, the view where it's from is already locked */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (map == NULL) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* no mapping given, use head mapping */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_view_lock_head(view, FALSE) < 0)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map = view->index->map;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (!mail_index_map_get_ext_idx(map, ext_id, &idx)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* extension doesn't exist in this index file */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *data_r = NULL;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *data_size_r = 0;
347acd14d8da653ce3757b3e29981326502bed6bTimo Sirainen return 0;
347acd14d8da653ce3757b3e29981326502bed6bTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ext = array_idx(&map->extensions, idx);
8cd0a1a2200e65cd134d03fe3f93ec02f1746359Timo Sirainen *data_r = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *data_size_r = ext->hdr_size;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_index_view_close(struct mail_index_view **_view)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_view *view = *_view;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *_view = NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (--view->refcount > 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen i_assert(view->transactions == 0);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen mail_index_view_unlock(view);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen view->v.close(view);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen}
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenuint32_t mail_index_view_get_messages_count(struct mail_index_view *view)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->v.get_messages_count(view);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenconst struct mail_index_header *
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenmail_index_get_header(struct mail_index_view *view)
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen{
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen return view->v.get_header(view);
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen}
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen
51b979b6414b940f04677a7e2d064be119345954Timo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen const struct mail_index_record **rec_r)
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen{
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen struct mail_index_map *map;
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen return mail_index_lookup_full(view, seq, &map, rec_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen struct mail_index_map **map_r,
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen const struct mail_index_record **rec_r)
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen{
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen return view->v.lookup_full(view, seq, map_r, rec_r);
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen}
629600d9a85e8025c15a5eaeb80329e116e022c9Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_map *map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const void *data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const unsigned char *keyword_data;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const unsigned int *keyword_idx_map;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen unsigned int i, j, keyword_count, index_idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t ext_id, idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint16_t record_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen int ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_clear(keyword_idx);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* get the keywords data. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ext_id = view->index->keywords_ext_id;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret = mail_index_lookup_ext_full(view, seq, ext_id, &map, &data);
9716b2665ee3938d3dfe64bda44d7c3ae3b55d30Timo Sirainen if (ret < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (data == NULL) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* no keywords at all in index */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen (void)mail_index_ext_get_size(view, ext_id, map, NULL,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &record_size, NULL);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* keyword_idx_map[] contains file => index keyword mapping */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (!array_is_created(&map->keyword_idx_map)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen keyword_idx_map = NULL;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen keyword_count = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen keyword_idx_map = array_get(&map->keyword_idx_map,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &keyword_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen keyword_data = data;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen for (i = 0, idx = 0; i < record_size; i++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* first do the quick check to see if there's keywords at all */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (keyword_data[i] == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen continue;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen idx = i * CHAR_BIT;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (j = 0; j < CHAR_BIT; j++, idx++) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((keyword_data[i] & (1 << j)) == 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen continue;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (idx >= keyword_count) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* keyword header was updated, parse it again
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen it so we know what this keyword is called */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (mail_index_map_parse_keywords(view->index,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen map) < 0)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return -1;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (!array_is_created(&map->keyword_idx_map))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* pointer may have changed. update it. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen keyword_idx_map =
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_get(&map->keyword_idx_map,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen &keyword_count);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (idx >= keyword_count) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* extra bits set in keyword bytes.
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen shouldn't happen, but just ignore. */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen break;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen index_idx = keyword_idx_map[idx];
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen array_append(keyword_idx, &index_idx, 1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return ret;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t *uid_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->v.lookup_uid(view, seq, uid_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t first_uid, uint32_t last_uid,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return view->v.lookup_uid_range(view, first_uid, last_uid,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen first_seq_r, last_seq_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint8_t flags_mask, uint32_t *seq_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->v.lookup_first(view, flags, flags_mask, seq_r);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t ext_id, const void **data_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_map *map;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return view->v.lookup_ext_full(view, seq, ext_id, &map, data_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void **data_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return view->v.lookup_ext_full(view, seq, ext_id, map_r, data_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_get_header_ext(struct mail_index_view *view, uint32_t ext_id,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void **data_r, size_t *data_size_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return view->v.get_header_ext(view, NULL, ext_id, data_r, data_size_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_map_get_header_ext(struct mail_index_view *view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_map *map, uint32_t ext_id,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const void **data_r, size_t *data_size_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return view->v.get_header_ext(view, map, ext_id, data_r, data_size_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_index_ext_get_size(struct mail_index_view *view __attr_unused__,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t ext_id, struct mail_index_map *map,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t *hdr_size_r, uint16_t *record_size_r,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint16_t *record_align_r)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_index_ext *ext;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(map != NULL);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (!mail_index_map_get_ext_idx(map, ext_id, &idx)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* extension doesn't exist in this index file */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (hdr_size_r != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *hdr_size_r = 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (record_size_r != NULL)
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen *record_size_r = 0;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen if (record_align_r != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *record_align_r = 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ext = array_idx(&map->extensions, idx);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (hdr_size_r != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *hdr_size_r = ext->hdr_size;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (record_size_r != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *record_size_r = ext->record_size;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (record_align_r != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen *record_align_r = ext->record_align;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic struct mail_index_view_vfuncs view_vfuncs = {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen _view_close,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen _view_get_messages_count,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen _view_get_header,
f87702d8d147f66d3fb6c41e5695c67f6d00612eTimo Sirainen _view_lookup_full,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen _view_lookup_uid,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen _view_lookup_uid_range,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen _view_lookup_first,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen _view_lookup_ext_full,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen _view_get_header_ext
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen};
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen{
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_index_view *view;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(index->map != NULL);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view = i_new(struct mail_index_view, 1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->refcount = 1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->v = view_vfuncs;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->index = index;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_view = mail_transaction_log_view_open(index->log);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
8bae533c96e129dca8ee7b494d7de5aeb4a043a2Timo Sirainen view->indexid = index->indexid;
8bae533c96e129dca8ee7b494d7de5aeb4a043a2Timo Sirainen view->map = index->map;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->refcount++;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->hdr = view->map->hdr;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_file_seq = view->map->hdr.log_file_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_file_offset =
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen I_MIN(view->map->hdr.log_file_int_offset,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->map->hdr.log_file_ext_offset);
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen return view;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenconst struct mail_index_ext *
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t idx;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (!mail_index_map_get_ext_idx(view->map, ext_id, &idx))
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return 0;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen return array_idx(&view->map->extensions, idx);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen}
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen