[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cyrus-devel
Subject:    Re: index.c API
From:       Bron Gondwana <brong () fastmail ! fm>
Date:       2007-10-31 13:55:28
Message-ID: 20071031135528.GA13450 () brong ! net
[Download RAW message or body]

First Pass: get rid of the macros in index.h

It appears that I really can't do ANYTHING while there are a bunch
of macros which need a few variables set and then go do random
reads directly into memory.  This is also an issue for crc32 checks
before accessing index records later, which is why I chose this
route.


NOTE - this patch isn't tested at all beyond compiling again, it's
very much a work in progress.  It's just an idea of how much is
impacted.

NOTE2 - this patch is highly inefficient in places.  I'm intending
to deal with that by passing the record pointer around where
appropriate rather than just the msgno and fetching the record
again - but I figured it was best to break this up into clear
stages rather than combine it all.


Bron.

["cyrus-index-removeglobals-2.3.10.diff" (text/x-diff)]

Index: cyrus-imapd-2.3.10/imap/imapd.c
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/imapd.c	2007-10-31 09:44:25.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/imapd.c	2007-10-31 09:46:20.000000000 -0400
@@ -2852,8 +2852,8 @@
 	       (mailbox->uidvalidity != url.uidvalidity)) {
 	*parseerr = "Uidvalidity of mailbox has changed";
 	r = IMAP_BADURL;
-    } else if (!url.uid || !(msgno = index_finduid(url.uid)) ||
-	       (index_getuid(msgno) != url.uid)) {
+    } else if (!url.uid || !(msgno = index_finduid(mailbox, url.uid)) ||
+	       (index_getuid(mailbox, msgno) != url.uid)) {
 	*parseerr = "No such message in mailbox";
 	r = IMAP_BADURL;
     } else {
@@ -4814,7 +4814,7 @@
     /* local mailbox */
     if (!(imapd_mailbox->myrights & ACL_EXPUNGE)) r = IMAP_PERMISSION_DENIED;
     else if (sequence) {
-	struct seq_set *seq_set = index_parse_sequence(sequence, 1, NULL);
+	struct seq_set *seq_set = index_parse_sequence(imapd_mailbox, sequence, 1, NULL);
 
 	r = mailbox_expunge(imapd_mailbox, index_expungeuidlist, seq_set, 0);
 	freesequencelist(seq_set);
@@ -7348,7 +7348,7 @@
     case '5': case '6': case '7': case '8': case '9':
     case '*':
 	if (imparse_issequence(criteria.s)) {
-	    appendsequencelist(&searchargs->sequence, criteria.s, 0);
+	    appendsequencelist(imapd_mailbox, &searchargs->sequence, criteria.s, 0);
 	}
 	else goto badcri;
 	break;
@@ -7724,7 +7724,7 @@
 	    if (c != ' ') goto missingarg;
 	    c = getword(imapd_in, &arg);
 	    if (!imparse_issequence(arg.s)) goto badcri;
-	    appendsequencelist(&searchargs->uidsequence, arg.s, 1);
+	    appendsequencelist(imapd_mailbox, &searchargs->uidsequence, arg.s, 1);
 	}
 	else if (!strcmp(criteria.s, "unseen")) {
 	    searchargs->flags |= SEARCH_SEEN_UNSET;
@@ -9669,8 +9669,8 @@
 	    } else if (url.uidvalidity &&
 		       (mailbox->uidvalidity != url.uidvalidity)) {
 		r = IMAP_BADURL;
-	    } else if (!url.uid || !(msgno = index_finduid(url.uid)) ||
-		       (index_getuid(msgno) != url.uid)) {
+	    } else if (!url.uid || !(msgno = index_finduid(mailbox, url.uid)) ||
+		       (index_getuid(mailbox, msgno) != url.uid)) {
 		r = IMAP_BADURL;
 	    } else {
 		r = index_urlfetch(mailbox, msgno, url.section,
Index: cyrus-imapd-2.3.10/imap/imapd.h
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/imapd.h	2007-10-31 09:44:28.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/imapd.h	2007-10-31 09:44:34.000000000 -0400
@@ -269,8 +269,8 @@
 extern int index_checkstate(struct mailbox *mailbox, unsigned indexdate,
 			       unsigned seendate);
 
-extern unsigned index_finduid(unsigned uid);
-extern unsigned index_getuid(unsigned msgno);
+extern unsigned index_finduid(struct mailbox *mailbox, unsigned uid);
+extern unsigned index_getuid(struct mailbox *mailbox, unsigned msgno);
 
 extern mailbox_decideproc_t index_expungeuidlist;
 
Index: cyrus-imapd-2.3.10/imap/index.c
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/index.c	2007-10-31 09:44:26.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/index.c	2007-10-31 09:44:34.000000000 -0400
@@ -142,7 +142,7 @@
 				 int format, unsigned size,
 				 struct strlist *headers,
 				 struct strlist *headers_not);
-static void index_fetchcacheheader(unsigned msgno, struct strlist *headers,
+static void index_fetchcacheheader(struct mailbox *mailbox, unsigned msgno, struct \
strlist *headers,  unsigned start_octet, unsigned octet_count);
 static void index_listflags(struct mailbox *mailbox);
 static void index_fetchflags(struct mailbox *mailbox, unsigned msgno,
@@ -160,7 +160,7 @@
 static int index_searchheader(char *name, char *substr, comp_pat *pat,
 			      struct mapfile *msgfile, int format,
 			      int size);
-static int index_searchcacheheader(unsigned msgno, char *name, char *substr,
+static int index_searchcacheheader(struct mailbox *mailbox, unsigned msgno, char \
*name, char *substr,  comp_pat *pat);
 static index_sequenceproc_t index_copysetup;
 static int _index_search(unsigned **msgno_list, struct mailbox *mailbox,
@@ -174,7 +174,7 @@
 static char *_index_extract_subject(char *s, int *is_refwd);
 static void index_get_ids(MsgData *msgdata,
 			  char *envtokens[], const char *headers);
-static MsgData *index_msgdata_load(unsigned *msgno_list, int n,
+static MsgData *index_msgdata_load(struct mailbox *mailbox, unsigned *msgno_list, \
int n,  struct sortcrit *sortcrit);
 
 static void *index_sort_getnext(MsgData *node);
@@ -187,11 +187,11 @@
 static void index_thread_setnext(Thread *thread, Thread *next);
 static int index_thread_compare(Thread *t1, Thread *t2,
 				struct sortcrit *call_data);
-static void index_thread_orderedsubj(unsigned *msgno_list, int nmsg,
+static void index_thread_orderedsubj(struct mailbox *mailbox, unsigned *msgno_list, \
int nmsg,  int usinguid);
 static void index_thread_sort(Thread *root, struct sortcrit *sortcrit);
 static void index_thread_print(Thread *threads, int usinguid);
-static void index_thread_ref(unsigned *msgno_list, int nmsg, int usinguid);
+static void index_thread_ref(struct mailbox *mailbox, unsigned *msgno_list, int \
nmsg, int usinguid);  
 /* NOTE: Make sure these are listed in CAPABILITY_STRING */
 static const struct thread_algorithm thread_algs[] = {
@@ -313,7 +313,7 @@
 		}
 		
 		nexpunge = 0;
-		while (oldmsgno<=imapd_exists && UID(oldmsgno) < record.uid) {
+		while (oldmsgno<=imapd_exists && index_getuid(mailbox, oldmsgno) < record.uid) {
 		    nexpunge++;
 		    oldmsgno++;
 		}
@@ -398,7 +398,7 @@
     /* If opening mailbox or had an EXPUNGE, find where \Recent starts */
     if (imapd_exists == -1) {
 	imapd_exists = newexists;
-	lastnotrecent = index_finduid(mailbox->recentuid);
+	lastnotrecent = index_finduid(mailbox, mailbox->recentuid);
 	imapd_exists = -1;
     }
     
@@ -415,7 +415,8 @@
 
 	/* Zero out array entry for newly arrived messages */
 	for (i = oldexists+1; i <= newexists; i++) {
-	    flagreport[i] = LAST_UPDATED(i);
+            mailbox_read_index_record(mailbox, i, &record);
+	    flagreport[i] = record.last_updated;
 	    seenflag[i] = 0;
 	}
 
@@ -448,17 +449,18 @@
     }
 
     for (msgno = 1; msgno <= oldexists; msgno++) {
-	if (flagreport[msgno] < LAST_UPDATED(msgno)) {
+        mailbox_read_index_record(mailbox, msgno, &record);
+	if (flagreport[msgno] < record.last_updated) {
 	    for (i = 0; (unsigned) i < VECTOR_SIZE(user_flags); i++) {
-		user_flags[i] = USER_FLAGS(msgno, i);
+		user_flags[i] = record.user_flags[i];
 	    }
-	    index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
-			     LAST_UPDATED(msgno));
+	    index_fetchflags(mailbox, msgno, record.system_flags, user_flags,
+			     record.last_updated);
 	    if ((mailbox->options & OPT_IMAP_CONDSTORE) &&
 		imapd_condstore_client) {
-		prot_printf(imapd_out, " MODSEQ (" MODSEQ_FMT ")", MODSEQ(msgno));
+		prot_printf(imapd_out, " MODSEQ (" MODSEQ_FMT ")", record.modseq);
 	    }
-	    if (usinguid) prot_printf(imapd_out, " UID %u", UID(msgno));
+	    if (usinguid) prot_printf(imapd_out, " UID %u", record.uid);
 	    prot_printf(imapd_out, ")\r\n");
 	}
     }
@@ -473,6 +475,7 @@
 index_check_existing(struct mailbox *mailbox, int usinguid, int checkseen)
 {
     struct stat sbuf;
+    struct index_record record;
     int msgno;
     unsigned i;
     bit32 user_flags[MAX_USER_FLAGS/32];
@@ -501,13 +504,14 @@
         index_checkseen(mailbox, 0, usinguid, imapd_exists);
 
     for (msgno = 1; msgno <= imapd_exists; msgno++) {
-	if (flagreport[msgno] < LAST_UPDATED(msgno)) {
+        mailbox_read_index_record(mailbox, msgno, &record);
+	if (flagreport[msgno] < record.last_updated) {
 	    for (i = 0; i < VECTOR_SIZE(user_flags); i++) {
-		user_flags[i] = USER_FLAGS(msgno, i);
+		user_flags[i] = record.user_flags[i];
 	    }
-	    index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
-			     LAST_UPDATED(msgno));
-	    if (usinguid) prot_printf(imapd_out, " UID %u", UID(msgno));
+	    index_fetchflags(mailbox, msgno, record.system_flags, user_flags,
+			     record.last_updated);
+	    if (usinguid) prot_printf(imapd_out, " UID %u", record.uid);
 	    prot_printf(imapd_out, ")\r\n");
 	}
     }
@@ -541,6 +545,7 @@
     unsigned newnext = 0, newseen = 0;
     int neweof = 0;
     unsigned uid, dirty = 0, i;
+    struct index_record record;
     int msgno;
     bit32 user_flags[MAX_USER_FLAGS/32];
     char *saveseenuids, *save;
@@ -575,7 +580,8 @@
     while (cyrus_isdigit((int) *new)) newnext = newnext * 10 + *new++ - '0';
 
     for (msgno = 1; msgno <= imapd_exists; msgno++) {
-	uid = UID(msgno);
+        mailbox_read_index_record(mailbox, msgno, &record);
+	uid = record.uid;
 	while (oldnext <= uid) {
 	    if (*old != ':' && !oldseen && oldnext == uid) {
 		oldseen = 1;
@@ -617,18 +623,19 @@
 	    if (seenflag[msgno] != newseen) {
 		seenflag[msgno] = newseen;
 		if (!quiet && msgno <= oldexists && oldexists != -1) {
+                    mailbox_read_index_record(mailbox, msgno, &record);
 		    for (i = 0; i < VECTOR_SIZE(user_flags); i++) {
-			user_flags[i] = USER_FLAGS(msgno, i);
+			user_flags[i] = record.user_flags[i];
 		    }
-		    index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), 
-				     user_flags, LAST_UPDATED(msgno));
+		    index_fetchflags(mailbox, msgno, record.system_flags,
+				     user_flags, record.last_updated);
 		    if ((mailbox->options & OPT_IMAP_CONDSTORE) &&
 			imapd_condstore_client) {
 			prot_printf(imapd_out, " MODSEQ (" MODSEQ_FMT ")",
-				    MODSEQ(msgno));
+				    record.modseq);
 		    }
 		    if (usinguid) {
-			prot_printf(imapd_out, " UID %u", UID(msgno));
+			prot_printf(imapd_out, " UID %u", record.uid);
 		    }
 		    prot_printf(imapd_out, ")\r\n");
 		}
@@ -690,7 +697,7 @@
     save = saveseenuids = xmalloc(savealloced);
     *save = '\0';
     for (msgno = 1; msgno <= imapd_exists; msgno++) {
-	uid = UID(msgno);
+	uid = index_getuid(mailbox, msgno);
 	if (seenflag[msgno] != inrange) {
 	    newallseen = 0;
 	    if (inrange) {
@@ -1044,6 +1051,7 @@
 			 struct searchargs *searchargs,
 			 modseq_t *highestmodseq)
 {
+    struct index_record record;
     unsigned msgno;
     struct mapfile msgfile;
     int n = 0;
@@ -1063,17 +1071,18 @@
 
     for (listindex = 0; listindex < listcount; listindex++) {
         msgno = (*msgno_list)[listindex];
+        mailbox_read_index_record(mailbox, msgno, &record);
 	msgfile.base = 0;
 	msgfile.size = 0;
 
 	if (index_search_evaluate(mailbox, searchargs, msgno, &msgfile)) {
 	    (*msgno_list)[n++] = msgno;
-	    if (highestmodseq && (MODSEQ(msgno) > *highestmodseq)) {
-		*highestmodseq = MODSEQ(msgno);
+	    if (highestmodseq && (record.modseq > *highestmodseq)) {
+		*highestmodseq = record.modseq;
 	    }
 	}
 	if (msgfile.base) {
-	    mailbox_unmap_message(mailbox, UID(msgno),
+	    mailbox_unmap_message(mailbox, record.uid,
 				  &msgfile.base, &msgfile.size);
 	}
     }
@@ -1087,8 +1096,10 @@
     return n;
 }
 
-unsigned index_getuid(unsigned msgno) {
-  return UID(msgno);
+unsigned index_getuid(struct mailbox *mailbox, unsigned msgno) {
+  static struct index_record record;
+  mailbox_read_index_record(mailbox, msgno, &record);
+  return record.uid;
 }
 
 /* 'uid_list' is malloc'd string representing the hits from searchargs;
@@ -1107,7 +1118,7 @@
     }
 
     for (i = 0; i < n; i++) {
-	msgno_list[i] = UID(msgno_list[i]);
+	msgno_list[i] = index_getuid(mailbox, msgno_list[i]);
     }
 
     *uid_list = msgno_list;
@@ -1132,7 +1143,7 @@
 
     for (i = 0; i < n; i++)
 	prot_printf(imapd_out, " %u",
-		    usinguid ? UID(msgno_list[i]) : msgno_list[i]);
+		    usinguid ? index_getuid(mailbox, msgno_list[i]) : msgno_list[i]);
 
     if (n) free(msgno_list);
 
@@ -1179,7 +1190,7 @@
 
     if (nmsg) {
 	/* Create/load the msgdata array */
-	freeme = msgdata = index_msgdata_load(msgno_list, nmsg, sortcrit);
+	freeme = msgdata = index_msgdata_load(mailbox, msgno_list, nmsg, sortcrit);
 	free(msgno_list);
 
 	/* Sort the messages based on the given criteria */
@@ -1192,7 +1203,7 @@
 	/* Output the sorted messages */ 
 	while (msgdata) {
 	    prot_printf(imapd_out, " %u",
-			usinguid ? UID(msgdata->msgno) : msgdata->msgno);
+			usinguid ? msgdata->record->uid : msgdata->msgno);
 
 	    /* free contents of the current node */
 	    index_msgdata_free(msgdata);
@@ -1261,7 +1272,7 @@
 
     if (nmsg) {
 	/* Thread messages using given algorithm */
-	(*thread_algs[algorithm].threader)(msgno_list, nmsg, usinguid);
+	(*thread_algs[algorithm].threader)(mailbox, msgno_list, nmsg, usinguid);
 
 	free(msgno_list);
 
@@ -1393,6 +1404,7 @@
 			      unsigned msgno, void *rock)
 {
     struct protstream *pout = (struct protstream *) rock;
+    struct index_record record;
     const char *msg_base = 0;
     unsigned long msg_size = 0;
     bit32 system_flags;
@@ -1402,8 +1414,10 @@
     char datebuf[30];
     char sepchar = '(';
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     /* Open the message file */
-    if (mailbox_map_message(mailbox, UID(msgno), &msg_base, &msg_size)) {
+    if (mailbox_map_message(mailbox, record.uid, &msg_base, &msg_size)) {
 	return IMAP_NO_MSGGONE;
     }
 
@@ -1411,7 +1425,7 @@
     prot_printf(pout, " ");
 
     /* add system flags */
-    system_flags = SYSTEM_FLAGS(msgno);
+    system_flags = record.system_flags;
     if (system_flags & FLAG_ANSWERED) {
 	prot_printf(pout, "%c\\Answered", sepchar);
 	sepchar = ' ';
@@ -1435,7 +1449,7 @@
 
     /* add user flags */
     for (flag = 0; flag < VECTOR_SIZE(user_flags); flag++) {
-	user_flags[flag] = USER_FLAGS(msgno, flag);
+	user_flags[flag] = record.user_flags[flag];
     }
     for (flag = 0; flag < VECTOR_SIZE(mailbox->flagname); flag++) {
 	if ((flag & 31) == 0) {
@@ -1448,16 +1462,16 @@
     }
 
     /* add internal date */
-    cyrus_ctime(INTERNALDATE(msgno), datebuf);
+    cyrus_ctime(record.internaldate, datebuf);
     prot_printf(pout, ") \"%s\" ", datebuf);
 
     /* message literal */
-    index_fetchmsg(msg_base, msg_size, mailbox->format, 0, SIZE(msgno),
+    index_fetchmsg(msg_base, msg_size, mailbox->format, 0, record.size,
 		   0, 0, pout);
 
     /* close the message file */
     if (msg_base) {
-	mailbox_unmap_message(mailbox, UID(msgno), &msg_base, &msg_size);
+	mailbox_unmap_message(mailbox, record.uid, &msg_base, &msg_size);
     }
 
     return 0;
@@ -1483,6 +1497,7 @@
 int statusitems;
 {
     int r;
+    struct index_record record;
     struct seen *status_seendb;
     time_t last_read, last_change = 0;
     unsigned last_uid;
@@ -1517,12 +1532,11 @@
 			"index", mailbox->name);
 
 	    seq_set.len = seq_set.mark = 0;
-	    index_parse_sequence(last_seenuids, 0, &seq_set);
+	    index_parse_sequence(mailbox, last_seenuids, 0, &seq_set);
 
 	    for (msg = 0; msg < mailbox->exists; msg++) {
-		uid = ntohl(*((bit32 *)(base + mailbox->start_offset +
-					msg * mailbox->record_size +
-					OFFSET_UID)));
+                mailbox_read_index_record(mailbox, msg, &record);
+		uid = record.uid;
 		if (uid > last_uid) num_recent++;
 		if ((statusitems & STATUS_UNSEEN) &&
 		    !index_insequence(uid, &seq_set, 1)) num_unseen++;
@@ -1576,14 +1590,14 @@
  * If no message with UID 'uid', returns the message with
  * the higest UID not greater than 'uid'.
  */
-unsigned index_finduid(unsigned uid)
+unsigned index_finduid(struct mailbox *mailbox, unsigned uid)
 {
     unsigned low=1, high=imapd_exists, mid;
     unsigned miduid;
 
     while (low <= high) {
 	mid = (high - low)/2 + low;
-	miduid = UID(mid);
+	miduid = index_getuid(mailbox, mid);
 	if (miduid == uid) {
 	    return mid;
 	}
@@ -1639,17 +1653,17 @@
     /* no messages, no calls. */
     if (!imapd_exists) return 0;
 
-    seq = index_parse_sequence(sequence, usinguid, NULL);
+    seq = index_parse_sequence(mailbox, sequence, usinguid, NULL);
 
     for (i = 0; i < seq->len; i++) {
 	unsigned start = seq->set[i].low;
 	unsigned end = seq->set[i].high;
 
 	if (usinguid) {
-	    j = index_finduid(start);
-	    if (!j || start != UID(j)) j++;
+	    j = index_finduid(mailbox, start);
+	    if (!j || start != index_getuid(mailbox, j)) j++;
 	    start = j;
-	    end = index_finduid(end);
+	    end = index_finduid(mailbox, end);
 	}
 	if (start < 1) start = 1;
 	if (end > (unsigned) imapd_exists) end = imapd_exists;
@@ -2116,9 +2130,10 @@
  * cacheheaders in cyrus.cache
  */
 static void
-index_fetchcacheheader(unsigned msgno, struct strlist *headers,
+index_fetchcacheheader(struct mailbox *mailbox, unsigned msgno, struct strlist \
*headers,  unsigned start_octet, unsigned octet_count)
 {
+    struct index_record record;
     static char *buf;
     static unsigned bufsize;
     const char *cacheitem;
@@ -2126,7 +2141,9 @@
     unsigned crlf_start = 0;
     unsigned crlf_size = 2;
 
-    cacheitem = cache_base + CACHE_OFFSET(msgno);
+    mailbox_read_index_record(mailbox, msgno, &record);
+    
+    cacheitem = cache_base + record.cache_offset;
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -2301,6 +2318,7 @@
 {
     struct fetchargs *fetchargs = (struct fetchargs *)rock;    
     int fetchitems = fetchargs->fetchitems;
+    struct index_record record;
     const char *msg_base = 0;
     unsigned long msg_size = 0;
     struct octetinfo *oi = NULL;
@@ -2314,18 +2332,20 @@
     char respbuf[100];
     int r = 0;
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     /* Check the modseq against changedsince */
     if (fetchargs->changedsince &&
-	MODSEQ(msgno) <= fetchargs->changedsince) {
+	record.modseq <= fetchargs->changedsince) {
 	return 0;
     }
 
     /* Open the message file if we're going to need it */
     if ((fetchitems & (FETCH_HEADER|FETCH_TEXT|FETCH_RFC822)) ||
-	fetchargs->cache_atleast > CACHE_VERSION(msgno) ||
+	fetchargs->cache_atleast > record.cache_version ||
 	fetchargs->binsections || fetchargs->sizesections ||
 	fetchargs->bodysections) {
-	if (mailbox_map_message(mailbox, UID(msgno), &msg_base, &msg_size)) {
+	if (mailbox_map_message(mailbox, record.uid, &msg_base, &msg_size)) {
 	    prot_printf(imapd_out, "* OK ");
 	    prot_printf(imapd_out, error_message(IMAP_NO_MSGGONE), msgno);
 	    prot_printf(imapd_out, "\r\n");
@@ -2342,10 +2362,10 @@
 
     if (fetchitems & FETCH_FLAGS) {
 	for (i = 0; i < VECTOR_SIZE(user_flags); i++) {
-	    user_flags[i] = USER_FLAGS(msgno, i);
+	    user_flags[i] = record.user_flags[i];
 	}
-	index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
-			 LAST_UPDATED(msgno));
+	index_fetchflags(mailbox, msgno, record.system_flags, user_flags,
+			 record.last_updated);
 	sepchar = ' ';
     }
     else if ((fetchitems & ~FETCH_SETSEEN) ||  fetchargs->fsections ||
@@ -2355,11 +2375,11 @@
 	started = 1;
     }
     if (fetchitems & FETCH_UID) {
-	prot_printf(imapd_out, "%cUID %u", sepchar, UID(msgno));
+	prot_printf(imapd_out, "%cUID %u", sepchar, record.uid);
 	sepchar = ' ';
     }
     if (fetchitems & FETCH_INTERNALDATE) {
-	time_t msgdate = INTERNALDATE(msgno);
+	time_t msgdate = record.internaldate;
 	char datebuf[30];
 
 	cyrus_ctime(msgdate, datebuf);
@@ -2370,24 +2390,24 @@
     }
     if (fetchitems & FETCH_MODSEQ) {
 	prot_printf(imapd_out, "%cMODSEQ (" MODSEQ_FMT ")",
-		    sepchar, MODSEQ(msgno));
+		    sepchar, record.modseq);
 	sepchar = ' ';
     }
     if (fetchitems & FETCH_SIZE) {
-	prot_printf(imapd_out, "%cRFC822.SIZE %u", sepchar, SIZE(msgno));
+	prot_printf(imapd_out, "%cRFC822.SIZE %u", sepchar, record.size);
 	sepchar = ' ';
     }
     if (fetchitems & FETCH_ENVELOPE) {
 	prot_printf(imapd_out, "%cENVELOPE ", sepchar);
 	sepchar = ' ';
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	prot_write(imapd_out, cacheitem + CACHE_ITEM_SIZE_SKIP,
 		   CACHE_ITEM_LEN(cacheitem));
     }
     if (fetchitems & FETCH_BODYSTRUCTURE) {
 	prot_printf(imapd_out, "%cBODYSTRUCTURE ", sepchar);
 	sepchar = ' ';
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	prot_write(imapd_out, cacheitem + CACHE_ITEM_SIZE_SKIP,
 		   CACHE_ITEM_LEN(cacheitem));
@@ -2395,7 +2415,7 @@
     if (fetchitems & FETCH_BODY) {
 	prot_printf(imapd_out, "%cBODY ", sepchar);
 	sepchar = ' ';
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	prot_write(imapd_out, cacheitem + CACHE_ITEM_SIZE_SKIP,
@@ -2406,7 +2426,7 @@
 	prot_printf(imapd_out, "%cRFC822.HEADER ", sepchar);
 	sepchar = ' ';
 	index_fetchmsg(msg_base, msg_size, mailbox->format, 0,
-		       HEADER_SIZE(msgno),
+		       record.header_size,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
 		         fetchargs->start_octet : 0,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2416,12 +2436,12 @@
     else if (fetchargs->headers || fetchargs->headers_not) {
 	prot_printf(imapd_out, "%cRFC822.HEADER ", sepchar);
 	sepchar = ' ';
-	if(fetchargs->cache_atleast > CACHE_VERSION(msgno)) {
+	if(fetchargs->cache_atleast > record.cache_version) {
 	    index_fetchheader(msg_base, msg_size, mailbox->format,
-			      HEADER_SIZE(msgno),
+			      record.header_size,
 			      fetchargs->headers, fetchargs->headers_not);
 	} else {
-	    index_fetchcacheheader(msgno, fetchargs->headers, 0, 0);
+	    index_fetchcacheheader(mailbox, msgno, fetchargs->headers, 0, 0);
 	}
     }
 
@@ -2429,7 +2449,7 @@
 	prot_printf(imapd_out, "%cRFC822.TEXT ", sepchar);
 	sepchar = ' ';
 	index_fetchmsg(msg_base, msg_size, mailbox->format,
-		       CONTENT_OFFSET(msgno), SIZE(msgno) - HEADER_SIZE(msgno),
+		       record.cache_offset, record.size - record.header_size,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
 		         fetchargs->start_octet : 0,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2439,7 +2459,7 @@
     if (fetchitems & FETCH_RFC822) {
 	prot_printf(imapd_out, "%cRFC822 ", sepchar);
 	sepchar = ' ';
-	index_fetchmsg(msg_base, msg_size, mailbox->format, 0, SIZE(msgno),
+	index_fetchmsg(msg_base, msg_size, mailbox->format, 0, record.size,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
 		         fetchargs->start_octet : 0,
 		       (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2461,8 +2481,8 @@
 
 	prot_printf(imapd_out, "%s ", fsection->trail);
 
-	if(fetchargs->cache_atleast > CACHE_VERSION(msgno)) {
-	    cacheitem = cache_base + CACHE_OFFSET(msgno);
+	if(fetchargs->cache_atleast > record.cache_version) {
+	    cacheitem = cache_base + record.cache_offset;
 	    cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	    cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	    cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -2475,7 +2495,7 @@
 				  fetchargs->octet_count : oi->octet_count);
 	}
 	else {
-	    index_fetchcacheheader(msgno, fsection->fields,
+	    index_fetchcacheheader(mailbox, msgno, fsection->fields,
 				   (fetchitems & FETCH_IS_PARTIAL) ?
 				     fetchargs->start_octet : oi->start_octet,
 				   (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2491,7 +2511,7 @@
 	snprintf(respbuf+strlen(respbuf), sizeof(respbuf)-strlen(respbuf),
 		 "%cBODY[%s ", sepchar, section->s);
 
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -2499,7 +2519,7 @@
 	oi = section->rock;
 
 	r = index_fetchsection(respbuf, msg_base, msg_size, mailbox->format,
-			       section->s, cacheitem, SIZE(msgno),
+			       section->s, cacheitem, record.size,
 			       (fetchitems & FETCH_IS_PARTIAL) ?
 				 fetchargs->start_octet : oi->start_octet,
 			       (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2515,7 +2535,7 @@
 	snprintf(respbuf+strlen(respbuf), sizeof(respbuf)-strlen(respbuf),
 		 "%cBINARY[%s ", sepchar, section->s);
 
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -2523,7 +2543,7 @@
 	oi = section->rock;
 
 	r = index_fetchsection(respbuf, msg_base, msg_size, mailbox->format,
-			       section->s, cacheitem, SIZE(msgno),
+			       section->s, cacheitem, record.size,
 			       (fetchitems & FETCH_IS_PARTIAL) ?
 				 fetchargs->start_octet : oi->start_octet,
 			       (fetchitems & FETCH_IS_PARTIAL) ?
@@ -2539,13 +2559,13 @@
 	snprintf(respbuf+strlen(respbuf), sizeof(respbuf)-strlen(respbuf),
 		 "%cBINARY.SIZE[%s ", sepchar, section->s);
 
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
 
 	r = index_fetchsection(respbuf, msg_base, msg_size, mailbox->format,
-			       section->s, cacheitem, SIZE(msgno),
+			       section->s, cacheitem, record.size,
 			       fetchargs->start_octet, fetchargs->octet_count);
 	if (!r)	sepchar = ' ';
     }
@@ -2554,7 +2574,7 @@
 	prot_printf(imapd_out, ")\r\n");
     }
     if (msg_base) {
-	mailbox_unmap_message(mailbox, UID(msgno), &msg_base, &msg_size);
+	mailbox_unmap_message(mailbox, record.uid, &msg_base, &msg_size);
     }
     return r;
 }
@@ -2574,6 +2594,7 @@
 		   unsigned long start_octet, unsigned long octet_count,
 		   struct protstream *pout, unsigned long *outsize)
 {
+    struct index_record record;
     const char *msg_base = 0;
     unsigned long msg_size = 0;
     const char *cacheitem;
@@ -2581,19 +2602,21 @@
     unsigned size, offset = 0, skip = 0;;
     int n, r = 0;
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     if (outsize) *outsize = 0;
 
     /* Open the message file */
-    if (mailbox_map_message(mailbox, UID(msgno), &msg_base, &msg_size)) {
+    if (mailbox_map_message(mailbox, record.uid, &msg_base, &msg_size)) {
 	return IMAP_NO_MSGGONE;
     }
 
-    cacheitem = cache_base + CACHE_OFFSET(msgno);
+    cacheitem = cache_base + record.cache_offset;
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
 
-    size = SIZE(msgno);
+    size = record.size;
 
     cacheitem += CACHE_ITEM_SIZE_SKIP;
 
@@ -2692,7 +2715,7 @@
 
   done:
     /* Close the message file */
-    mailbox_unmap_message(mailbox, UID(msgno), &msg_base, &msg_size);
+    mailbox_unmap_message(mailbox, record.uid, &msg_base, &msg_size);
 
     return r;
 }
@@ -2703,10 +2726,13 @@
  */
 static int index_storeseen(struct mailbox *mailbox, unsigned msgno, void *rock)
 {
+    struct index_record record;
     struct storeargs *storeargs = (struct storeargs *)rock;
     int val = (storeargs->operation == STORE_ADD) ? 1 : 0;
     unsigned i;
     bit32 user_flags[MAX_USER_FLAGS/32];
+
+    mailbox_read_index_record(mailbox, msgno, &record);
     
     if (seenflag[msgno] == val) return 0;
     seenflag[msgno] = val;
@@ -2714,12 +2740,12 @@
     if (storeargs->silent) return 0;
 
     for (i=0; i < VECTOR_SIZE(user_flags); i++) {
-	user_flags[i] = USER_FLAGS(msgno, i);
+	user_flags[i] = record.user_flags[i];
     }
-    index_fetchflags(mailbox, msgno, SYSTEM_FLAGS(msgno), user_flags,
-		     LAST_UPDATED(msgno));
+    index_fetchflags(mailbox, msgno, record.system_flags, user_flags,
+		     record.last_updated);
     if (storeargs->usinguid) {
-	prot_printf(imapd_out, " UID %u", UID(msgno));
+	prot_printf(imapd_out, " UID %u", record.uid);
     }
     prot_printf(imapd_out, ")\r\n");
 
@@ -2734,8 +2760,8 @@
 {
     struct storeargs *storeargs = (struct storeargs *)rock;
     unsigned i;
-    struct index_record record;
-    unsigned long uid = UID(msgno);
+    struct index_record baserecord, foundrecord;
+    unsigned int uid;
     unsigned low=1, high=mailbox->exists;
     unsigned mid = 0;
     int r;
@@ -2744,8 +2770,10 @@
     bit32 oldflags;
     int sepchar = '(';
 
+    mailbox_read_index_record(mailbox, msgno, &baserecord);
+
     /* Check the modseq against unchangedsince */
-    if (MODSEQ(msgno) > storeargs->unchangedsince) return 0;
+    if (baserecord.modseq > storeargs->unchangedsince) return 0;
 
     /* Change \Seen flag */
     if (storeargs->operation == STORE_REPLACE && (mailbox->myrights & ACL_SEEN))
@@ -2770,12 +2798,12 @@
 	    mid = (high - low)/2 + low;
 	}
 	firsttry = 0;
-	r = mailbox_read_index_record(mailbox, mid, &record);
+	r = mailbox_read_index_record(mailbox, mid, &foundrecord);
 	if (r) return r;
-	if (record.uid == uid) {
+	if (foundrecord.uid == baserecord.uid) {
 	    break;
 	}
-	else if (record.uid > uid) {
+	else if (foundrecord.uid > baserecord.uid) {
 	    high = mid - 1;
 	}
 	else {
@@ -2795,84 +2823,84 @@
 	/* Fake setting the flags */
 	mid = 0;
 	storeargs->last_found = high;
-	record.system_flags = SYSTEM_FLAGS(msgno);
-	for (i = 0; i < VECTOR_SIZE(record.user_flags); i++) {
-	    record.user_flags[i] = USER_FLAGS(msgno, i);
+	foundrecord.system_flags = baserecord.system_flags;
+	for (i = 0; i < VECTOR_SIZE(foundrecord.user_flags); i++) {
+	    foundrecord.user_flags[i] = baserecord.user_flags[i];
 	}
     }
 
     /* save old */
-    oldflags = record.system_flags;
+    oldflags = foundrecord.system_flags;
 
     if (storeargs->operation == STORE_REPLACE) {
 	if (!(mailbox->myrights & ACL_WRITE)) {
 	    /* ACL_DELETE handled in index_store() */
-	    if ((record.system_flags & FLAG_DELETED) !=
+	    if ((foundrecord.system_flags & FLAG_DELETED) !=
 		(storeargs->system_flags & FLAG_DELETED)) {
 		dirty++;
 	    }
-	    record.system_flags = (record.system_flags&~FLAG_DELETED) |
+	    foundrecord.system_flags = (foundrecord.system_flags&~FLAG_DELETED) |
 	      (storeargs->system_flags&FLAG_DELETED);
 	}
 	else {
 	    if (!(mailbox->myrights & ACL_DELETEMSG)) {
-		if ((record.system_flags & ~FLAG_DELETED) !=
+		if ((foundrecord.system_flags & ~FLAG_DELETED) !=
 		    (storeargs->system_flags & ~FLAG_DELETED)) {
 		    dirty++;
 		}
-		record.system_flags = (record.system_flags&FLAG_DELETED) |
+		foundrecord.system_flags = (foundrecord.system_flags&FLAG_DELETED) |
 		  (storeargs->system_flags&~FLAG_DELETED);
 	    }
 	    else {
-		if (record.system_flags != storeargs->system_flags) dirty++;
-		record.system_flags = storeargs->system_flags;
+		if (foundrecord.system_flags != storeargs->system_flags) dirty++;
+		foundrecord.system_flags = storeargs->system_flags;
 	    }
-	    for (i = 0; i < VECTOR_SIZE(record.user_flags); i++) {
-		if (record.user_flags[i] != storeargs->user_flags[i]) dirty++;
-		record.user_flags[i] = storeargs->user_flags[i];
+	    for (i = 0; i < VECTOR_SIZE(foundrecord.user_flags); i++) {
+		if (foundrecord.user_flags[i] != storeargs->user_flags[i]) dirty++;
+		foundrecord.user_flags[i] = storeargs->user_flags[i];
 	    }
 	}
     }
     else if (storeargs->operation == STORE_ADD) {
-	if (~record.system_flags & storeargs->system_flags) dirty++;
+	if (~foundrecord.system_flags & storeargs->system_flags) dirty++;
 
-	record.system_flags |= storeargs->system_flags;
-	for (i = 0; i < VECTOR_SIZE(record.user_flags); i++) {
-	    if (~record.user_flags[i] & storeargs->user_flags[i]) dirty++;
-	    record.user_flags[i] |= storeargs->user_flags[i];
+	foundrecord.system_flags |= storeargs->system_flags;
+	for (i = 0; i < VECTOR_SIZE(foundrecord.user_flags); i++) {
+	    if (~foundrecord.user_flags[i] & storeargs->user_flags[i]) dirty++;
+	    foundrecord.user_flags[i] |= storeargs->user_flags[i];
 	}
     }
     else {			/* STORE_REMOVE */
-	if (record.system_flags & storeargs->system_flags) dirty++;
+	if (foundrecord.system_flags & storeargs->system_flags) dirty++;
 
 	/* change the individual entry */
-	record.system_flags &= ~storeargs->system_flags;
-	for (i = 0; i < VECTOR_SIZE(record.user_flags); i++) {
-	    if (record.user_flags[i] & storeargs->user_flags[i]) dirty++;
-	    record.user_flags[i] &= ~storeargs->user_flags[i];
+	foundrecord.system_flags &= ~storeargs->system_flags;
+	for (i = 0; i < VECTOR_SIZE(foundrecord.user_flags); i++) {
+	    if (foundrecord.user_flags[i] & storeargs->user_flags[i]) dirty++;
+	    foundrecord.user_flags[i] &= ~storeargs->user_flags[i];
 	}
     }
 
     if (dirty) {
 	if (mailbox->options & OPT_IMAP_CONDSTORE) {
 	    /* bump MODSEQ */
-	    record.modseq = mailbox->highestmodseq + 1;
+	    foundrecord.modseq = mailbox->highestmodseq + 1;
 	}
 
 	/* update totals */
-	if ( (record.system_flags & FLAG_DELETED) && !(oldflags & FLAG_DELETED))
+	if ( (foundrecord.system_flags & FLAG_DELETED) && !(oldflags & FLAG_DELETED))
 	    mailbox->deleted++;
-	if ( !(record.system_flags & FLAG_DELETED) && (oldflags & FLAG_DELETED))
+	if ( !(foundrecord.system_flags & FLAG_DELETED) && (oldflags & FLAG_DELETED))
 	    mailbox->deleted--;
 
-	if ( (record.system_flags & FLAG_ANSWERED) && !(oldflags & FLAG_ANSWERED))
+	if ( (foundrecord.system_flags & FLAG_ANSWERED) && !(oldflags & FLAG_ANSWERED))
 	    mailbox->answered++;
-	if ( !(record.system_flags & FLAG_ANSWERED) && (oldflags & FLAG_ANSWERED))
+	if ( !(foundrecord.system_flags & FLAG_ANSWERED) && (oldflags & FLAG_ANSWERED))
 	    mailbox->answered--;
 
-	if ( (record.system_flags & FLAG_FLAGGED) && !(oldflags & FLAG_FLAGGED))
+	if ( (foundrecord.system_flags & FLAG_FLAGGED) && !(oldflags & FLAG_FLAGGED))
 	    mailbox->flagged++;
-	if ( !(record.system_flags & FLAG_FLAGGED) && (oldflags & FLAG_FLAGGED))
+	if ( !(foundrecord.system_flags & FLAG_FLAGGED) && (oldflags & FLAG_FLAGGED))
 	    mailbox->flagged--;
 
 	/* either a system or user flag changed. need to at least touch acap
@@ -2881,20 +2909,20 @@
 
 	/* If .SILENT, assume client has updated their cache */
 	if (storeargs->silent && 
-	    flagreport[msgno] == record.last_updated) {
+	    flagreport[msgno] == foundrecord.last_updated) {
 	    flagreport[msgno] = 
-		(record.last_updated >= storeargs->update_time) ?
-		record.last_updated + 1 : storeargs->update_time;
+		(foundrecord.last_updated >= storeargs->update_time) ?
+		foundrecord.last_updated + 1 : storeargs->update_time;
 	}
 	
-	record.last_updated =
-	    (record.last_updated >= storeargs->update_time) ?
-	    record.last_updated + 1 : storeargs->update_time;
+	foundrecord.last_updated =
+	    (foundrecord.last_updated >= storeargs->update_time) ?
+	    foundrecord.last_updated + 1 : storeargs->update_time;
     }
     
     if (!storeargs->silent) {
-	index_fetchflags(mailbox, msgno, record.system_flags,
-			 record.user_flags, record.last_updated);
+	index_fetchflags(mailbox, msgno, foundrecord.system_flags,
+			 foundrecord.user_flags, foundrecord.last_updated);
 	sepchar = ' ';
     }
     if ((mailbox->options & OPT_IMAP_CONDSTORE) && imapd_condstore_client) {
@@ -2903,19 +2931,19 @@
 	    prot_printf(imapd_out, "* %u FETCH ", msgno);
 	}
 	prot_printf(imapd_out, "%cMODSEQ (" MODSEQ_FMT ")",
-		    sepchar, record.modseq);
+		    sepchar, foundrecord.modseq);
 	sepchar = ' ';
     }
     if (sepchar != '(') {
 	/* finsh the response if we have one */
 	if (storeargs->usinguid) {
-	    prot_printf(imapd_out, " UID %u", UID(msgno));
+	    prot_printf(imapd_out, " UID %u", baserecord.uid);
 	}
 	prot_printf(imapd_out, ")\r\n");
     }
     
     if (dirty && mid) {
-	r = mailbox_write_index_record(mailbox, mid, &record, 0);
+	r = mailbox_write_index_record(mailbox, mid, &foundrecord, 0);
 	if (r) return r;
     }
     
@@ -2932,6 +2960,7 @@
 				 unsigned msgno,
 				 struct mapfile *msgfile)
 {
+    struct index_record record;
     unsigned i;
     struct strlist *l, *h;
     const char *cacheitem;
@@ -2939,6 +2968,8 @@
     struct searchsub *s;
     struct seq_set *seq;
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     if ((searchargs->flags & SEARCH_RECENT_SET) && msgno <= lastnotrecent) 
 	return 0;
     if ((searchargs->flags & SEARCH_RECENT_UNSET) && msgno > lastnotrecent) 
@@ -2946,27 +2977,27 @@
     if ((searchargs->flags & SEARCH_SEEN_SET) && !seenflag[msgno]) return 0;
     if ((searchargs->flags & SEARCH_SEEN_UNSET) && seenflag[msgno]) return 0;
 
-    if (searchargs->smaller && SIZE(msgno) >= searchargs->smaller) return 0;
-    if (searchargs->larger && SIZE(msgno) <= searchargs->larger) return 0;
+    if (searchargs->smaller && record.size >= searchargs->smaller) return 0;
+    if (searchargs->larger && record.size <= searchargs->larger) return 0;
 
-    if (searchargs->after && (time_t) INTERNALDATE(msgno) < searchargs->after)
+    if (searchargs->after && (time_t) record.internaldate < searchargs->after)
       return 0;
-    if (searchargs->before && (time_t) INTERNALDATE(msgno) > searchargs->before)
+    if (searchargs->before && (time_t) record.internaldate > searchargs->before)
       return 0;
-    if (searchargs->sentafter && (time_t) SENTDATE(msgno) < searchargs->sentafter)
+    if (searchargs->sentafter && (time_t) record.sentdate < searchargs->sentafter)
       return 0;
-    if (searchargs->sentbefore && (time_t) SENTDATE(msgno) > searchargs->sentbefore)
+    if (searchargs->sentbefore && (time_t) record.sentdate > searchargs->sentbefore)
       return 0;
 
-    if (searchargs->modseq && MODSEQ(msgno) < searchargs->modseq) return 0;
+    if (searchargs->modseq && record.modseq < searchargs->modseq) return 0;
 
-    if (~SYSTEM_FLAGS(msgno) & searchargs->system_flags_set) return 0;
-    if (SYSTEM_FLAGS(msgno) & searchargs->system_flags_unset) return 0;
+    if (~(record.system_flags) & searchargs->system_flags_set) return 0;
+    if (record.system_flags & searchargs->system_flags_unset) return 0;
 	
     for (i = 0; i < VECTOR_SIZE(searchargs->user_flags_set); i++) {
-	if (~USER_FLAGS(msgno,i) & searchargs->user_flags_set[i])
+	if (~(record.user_flags[i]) & searchargs->user_flags_set[i])
 	  return 0;
-	if (USER_FLAGS(msgno,i) & searchargs->user_flags_unset[i])
+	if (record.user_flags[i] & searchargs->user_flags_unset[i])
 	  return 0;
     }
 
@@ -2974,13 +3005,13 @@
 	if (!index_insequence(msgno, seq, 1)) return 0;
     }
     for (seq = searchargs->uidsequence; seq; seq = seq->next) {
-	if (!index_insequence(UID(msgno), seq, 1)) return 0;
+	if (!index_insequence(record.uid, seq, 1)) return 0;
     }
 
     if (searchargs->from || searchargs->to || searchargs->cc ||
 	searchargs->bcc || searchargs->subject || searchargs->messageid) {
 
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cachelen = CACHE_ITEM_LEN(cacheitem);
 
 	if (searchargs->messageid) {
@@ -3092,9 +3123,9 @@
     }
 
     if (searchargs->body || searchargs->text ||
-	searchargs->cache_atleast > CACHE_VERSION(msgno)) {
+	searchargs->cache_atleast > record.cache_version) {
 	if (! msgfile->size) { /* Map the message in if we haven't before */
-	    if (mailbox_map_message(mailbox, UID(msgno),
+	    if (mailbox_map_message(mailbox, record.uid,
 				    &msgfile->base, &msgfile->size)) {
 		return 0;
 	    }
@@ -3103,10 +3134,10 @@
 	h = searchargs->header_name;
 	for (l = searchargs->header; l; (l = l->next), (h = h->next)) {
 	    if (!index_searchheader(h->s, l->s, l->p, msgfile, mailbox->format,
-				    HEADER_SIZE(msgno))) return 0;
+				    record.header_size)) return 0;
 	}
 
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -3123,7 +3154,7 @@
     else if (searchargs->header_name) {
 	h = searchargs->header_name;
 	for (l = searchargs->header; l; (l = l->next), (h = h->next)) {
-	    if (!index_searchcacheheader(msgno, h->s, l->s, l->p)) return 0;
+	    if (!index_searchcacheheader(mailbox, msgno, h->s, l->s, l->p)) return 0;
 	}
     }
 
@@ -3227,10 +3258,11 @@
 /*
  * Search named cached header of a message for a substring
  */
-static int index_searchcacheheader(unsigned msgno,
+static int index_searchcacheheader(struct mailbox *mailbox, unsigned msgno,
 				   char *name, char *substr,
 				   comp_pat *pat)
 {
+    struct index_record record;
     char *q;
     static struct strlist header;
     static char *buf;
@@ -3239,7 +3271,9 @@
     unsigned size;
     int r;
 
-    cacheitem = cache_base + CACHE_OFFSET(msgno);
+    mailbox_read_index_record(mailbox, msgno, &record);
+
+    cacheitem = cache_base + record.cache_offset;
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -3350,39 +3384,41 @@
                          index_search_text_receiver_t receiver,
                          void* rock) {
   int i;
+  struct index_record record;
 
   /* Send the converted text of every message out to the receiver. */
   for (i = 1; i <= imapd_exists; i++) {
     const char *cacheitem;
-    int uid = UID(i);
+    
+    mailbox_read_index_record(mailbox, i, &record);
 
-    cacheitem = cache_base + CACHE_OFFSET(i);
+    cacheitem = cache_base + record.cache_offset;
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
 
-    index_getsearchtextmsg(mailbox, uid, receiver, rock, cacheitem);
+    index_getsearchtextmsg(mailbox, record.uid, receiver, rock, cacheitem);
     
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip section */
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip cacheheaders */
 
-    receiver(uid, SEARCHINDEX_PART_FROM, SEARCHINDEX_CMD_STUFFPART,
+    receiver(record.uid, SEARCHINDEX_PART_FROM, SEARCHINDEX_CMD_STUFFPART,
              cacheitem + 4, CACHE_ITEM_LEN(cacheitem), rock);
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip from */
 
-    receiver(uid, SEARCHINDEX_PART_TO, SEARCHINDEX_CMD_STUFFPART,
+    receiver(record.uid, SEARCHINDEX_PART_TO, SEARCHINDEX_CMD_STUFFPART,
              cacheitem + 4, CACHE_ITEM_LEN(cacheitem), rock);
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip to */
 
-    receiver(uid, SEARCHINDEX_PART_CC, SEARCHINDEX_CMD_STUFFPART,
+    receiver(record.uid, SEARCHINDEX_PART_CC, SEARCHINDEX_CMD_STUFFPART,
              cacheitem + 4, CACHE_ITEM_LEN(cacheitem), rock);
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip cc */
 
-    receiver(uid, SEARCHINDEX_PART_BCC, SEARCHINDEX_CMD_STUFFPART,
+    receiver(record.uid, SEARCHINDEX_PART_BCC, SEARCHINDEX_CMD_STUFFPART,
              cacheitem + 4, CACHE_ITEM_LEN(cacheitem), rock);
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bcc */
 
-    receiver(uid, SEARCHINDEX_PART_SUBJECT, SEARCHINDEX_CMD_STUFFPART,
+    receiver(record.uid, SEARCHINDEX_PART_SUBJECT, SEARCHINDEX_CMD_STUFFPART,
              cacheitem + 4, CACHE_ITEM_LEN(cacheitem), rock);
     cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip subject */
   }
@@ -3398,11 +3434,14 @@
 unsigned msgno;
 void *rock;
 {
+    struct index_record record;
     struct copyargs *copyargs = (struct copyargs *)rock;
     int flag = 0;
     unsigned userflag;
     bit32 flagmask = 0;
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     if (copyargs->nummsg == copyargs->msgalloc) {
 	copyargs->msgalloc += COPYARGSGROW;
 	copyargs->copymsg = (struct copymsg *)
@@ -3410,36 +3449,34 @@
 		   copyargs->msgalloc * sizeof(struct copymsg));
     }
 
-    copyargs->copymsg[copyargs->nummsg].uid = UID(msgno);
-    copyargs->copymsg[copyargs->nummsg].internaldate = INTERNALDATE(msgno);
-    copyargs->copymsg[copyargs->nummsg].sentdate = SENTDATE(msgno);
-    copyargs->copymsg[copyargs->nummsg].size = SIZE(msgno);
-    copyargs->copymsg[copyargs->nummsg].header_size = HEADER_SIZE(msgno);
-    copyargs->copymsg[copyargs->nummsg].content_lines = CONTENT_LINES(msgno);
-    copyargs->copymsg[copyargs->nummsg].cache_version = CACHE_VERSION(msgno);
-    copyargs->copymsg[copyargs->nummsg].cache_begin = cache_base + \
                CACHE_OFFSET(msgno);
-    message_guid_import(&copyargs->copymsg[copyargs->nummsg].guid,
-                        (unsigned char *) /* YYY */
-                        INDEC_OFFSET(msgno)+OFFSET_MESSAGE_GUID);
+    copyargs->copymsg[copyargs->nummsg].uid = record.uid;
+    copyargs->copymsg[copyargs->nummsg].internaldate = record.internaldate;
+    copyargs->copymsg[copyargs->nummsg].sentdate = record.sentdate;
+    copyargs->copymsg[copyargs->nummsg].size = record.size;
+    copyargs->copymsg[copyargs->nummsg].header_size = record.header_size;
+    copyargs->copymsg[copyargs->nummsg].content_lines = record.content_lines;
+    copyargs->copymsg[copyargs->nummsg].cache_version = record.cache_version;
+    copyargs->copymsg[copyargs->nummsg].cache_begin = cache_base + \
record.cache_offset; +    \
message_guid_copy(&copyargs->copymsg[copyargs->nummsg].guid, &record.guid);  
     if (mailbox->format != MAILBOX_FORMAT_NORMAL) {
 	/* Force copy and re-parse of message */
 	copyargs->copymsg[copyargs->nummsg].cache_len = 0;
     }
     else if (msgno < (unsigned) imapd_exists) {
-	copyargs->copymsg[copyargs->nummsg].cache_len =
-	  CACHE_OFFSET(msgno+1) - CACHE_OFFSET(msgno);
+        /* XXX - interface should be changed to user a proper parsed cache record */
+	copyargs->copymsg[copyargs->nummsg].cache_len = mailbox_cache_size(mailbox, msgno);
     }
     else {
-	copyargs->copymsg[copyargs->nummsg].cache_len =
-	  cache_end - CACHE_OFFSET(msgno);
+        /* XXX - interface should be changed to user a proper parsed cache record */
+	copyargs->copymsg[copyargs->nummsg].cache_len = cache_end - record.cache_offset;
     }
     copyargs->copymsg[copyargs->nummsg].seen = seenflag[msgno];
-    copyargs->copymsg[copyargs->nummsg].system_flags = SYSTEM_FLAGS(msgno);
+    copyargs->copymsg[copyargs->nummsg].system_flags = record.system_flags;
 
     for (userflag = 0; userflag < MAX_USER_FLAGS; userflag++) {
 	if ((userflag & 31) == 0) {
-	    flagmask = USER_FLAGS(msgno,userflag/32);
+	    flagmask = record.user_flags[userflag/32];
 	}
 	if (!mailbox->flagname[userflag] && (flagmask & (1<<(userflag&31)))) {
 	    mailbox_read_header(mailbox);
@@ -3450,7 +3487,7 @@
 
     for (userflag = 0; userflag < MAX_USER_FLAGS; userflag++) {
 	if ((userflag & 31) == 0) {
-	    flagmask = USER_FLAGS(msgno,userflag/32);
+	    flagmask = record.user_flags[userflag/32];
 	}
 	if (mailbox->flagname[userflag] && (flagmask & (1<<(userflag&31)))) {
 	    copyargs->copymsg[copyargs->nummsg].flag[flag++] =
@@ -3472,7 +3509,7 @@
  */
 #define ANNOTGROWSIZE	10
 
-static MsgData *index_msgdata_load(unsigned *msgno_list, int n,
+static MsgData *index_msgdata_load(struct mailbox *mailbox, unsigned *msgno_list, \
int n,  struct sortcrit *sortcrit)
 {
     MsgData *md, *cur;
@@ -3495,6 +3532,8 @@
     for (i = 0, cur = md; i < n; i++, cur = cur->next) {
 	/* set msgno */
 	cur->msgno = msgno_list[i];
+        cur->record = xmalloc(sizeof(struct index_record));
+        mailbox_read_index_record(mailbox, cur->msgno, cur->record);
 
 	/* set pointer to next node */
 	cur->next = (i+1 < n ? cur+1 : NULL);
@@ -3512,7 +3551,7 @@
 		!did_cache) {
 
 		/* fetch cached info */
-		env = cache_base + CACHE_OFFSET(cur->msgno);
+		env = cache_base + cur->record->cache_offset;
 		cacheitem = CACHE_ITEM_NEXT(env); /* bodystructure */
 		cacheitem = CACHE_ITEM_NEXT(cacheitem); /* body */
 		cacheitem = CACHE_ITEM_NEXT(cacheitem); /* section */
@@ -4039,14 +4078,14 @@
 	    ret = numcmp(md1->msgno, md2->msgno);
 	    break;
 	case SORT_ARRIVAL:
-	    ret = numcmp(INTERNALDATE(md1->msgno), INTERNALDATE(md2->msgno));
+	    ret = numcmp(md1->record->internaldate, md2->record->internaldate);
 	    break;
 	case SORT_CC:
 	    ret = strcmp(md1->cc, md2->cc);
 	    break;
 	case SORT_DATE: {
-	    time_t d1 = md1->date ? md1->date : (time_t) INTERNALDATE(md1->msgno);
-	    time_t d2 = md2->date ? md2->date : (time_t) INTERNALDATE(md2->msgno);
+	    time_t d1 = md1->date ? md1->date : (time_t) md1->record->internaldate;
+	    time_t d2 = md2->date ? md2->date : (time_t) md2->record->internaldate;
 	    ret = numcmp(d1, d2);
 	    break;
 	}
@@ -4054,7 +4093,7 @@
 	    ret = strcmp(md1->from, md2->from);
 	    break;
 	case SORT_SIZE:
-	    ret = numcmp(SIZE(md1->msgno), SIZE(md2->msgno));
+	    ret = numcmp(md1->record->size, md2->record->size);
 	    break;
 	case SORT_SUBJECT:
 	    ret = strcmp(md1->xsubj, md2->xsubj);
@@ -4067,7 +4106,7 @@
 	    ann++;
 	    break;
 	case SORT_MODSEQ:
-	    ret = numcmp(MODSEQ(md1->msgno), MODSEQ(md2->msgno));
+	    ret = numcmp(md1->record->modseq, md2->record->modseq);
 	    break;
 	}
     } while (!ret && sortcrit[i++].key != SORT_SEQUENCE);
@@ -4085,6 +4124,7 @@
 
     if (!md)
 	return;
+    FREE(md->record);
     FREE(md->cc);
     FREE(md->from);
     FREE(md->to);
@@ -4155,7 +4195,7 @@
 /*
  * Thread a list of messages using the ORDEREDSUBJECT algorithm.
  */
-static void index_thread_orderedsubj(unsigned *msgno_list, int nmsg,
+static void index_thread_orderedsubj(struct mailbox *mailbox, unsigned *msgno_list, \
int nmsg,  int usinguid)
 {
     MsgData *msgdata, *freeme;
@@ -4167,7 +4207,7 @@
     Thread *head, *newnode, *cur, *parent, *last;
 
     /* Create/load the msgdata array */
-    freeme = msgdata = index_msgdata_load(msgno_list, nmsg, sortcrit);
+    freeme = msgdata = index_msgdata_load(mailbox, msgno_list, nmsg, sortcrit);
 
     /* Sort messages by subject and date */
     msgdata = lsort(msgdata,
@@ -4256,7 +4296,7 @@
 	 */
 	if (thread->msgdata) {
 	    prot_printf(imapd_out, "%u",
-			usinguid ? UID(thread->msgdata->msgno) :
+			usinguid ? thread->msgdata->record->uid :
 			thread->msgdata->msgno);
 
 	    /* if we have a child, print the parent-child separator */
@@ -4277,7 +4317,7 @@
 	    /* otherwise print the only child */
 	    else {
 		prot_printf(imapd_out, "%u",
-			    usinguid ? UID(child->msgdata->msgno) :
+			    usinguid ? child->msgdata->record->uid :
 			    child->msgdata->msgno);
 
 		/* if we have a child, print the parent-child separator */
@@ -4828,7 +4868,7 @@
  * Guts of the REFERENCES algorithms.  Behavior is tweaked with loadcrit[],
  * searchproc() and sortcrit[].
  */
-static void _index_thread_ref(unsigned *msgno_list, int nmsg,
+static void _index_thread_ref(struct mailbox *mailbox, unsigned *msgno_list, int \
nmsg,  struct sortcrit loadcrit[],
 			      int (*searchproc) (MsgData *),
 			      struct sortcrit sortcrit[], int usinguid)
@@ -4840,7 +4880,7 @@
     struct rootset rootset;
 
     /* Create/load the msgdata array */
-    freeme = msgdata = index_msgdata_load(msgno_list, nmsg, loadcrit);
+    freeme = msgdata = index_msgdata_load(mailbox, msgno_list, nmsg, loadcrit);
 
     /* calculate the sum of the number of references for all messages */
     for (md = msgdata, tref = 0; md; md = md->next)
@@ -4914,7 +4954,7 @@
 /*
  * Thread a list of messages using the REFERENCES algorithm.
  */
-static void index_thread_ref(unsigned *msgno_list, int nmsg, int usinguid)
+static void index_thread_ref(struct mailbox *mailbox, unsigned *msgno_list, int \
nmsg, int usinguid)  {
     struct sortcrit loadcrit[] = {{ LOAD_IDS,      0, {{NULL,NULL}} },
 				  { SORT_SUBJECT,  0, {{NULL,NULL}} },
@@ -4923,22 +4963,25 @@
     struct sortcrit sortcrit[] = {{ SORT_DATE,     0, {{NULL,NULL}} },
 				  { SORT_SEQUENCE, 0, {{NULL,NULL}} }};
 
-    _index_thread_ref(msgno_list, nmsg, loadcrit, NULL, sortcrit, usinguid);
+    _index_thread_ref(mailbox, msgno_list, nmsg, loadcrit, NULL, sortcrit, \
usinguid);  }
 
 /*
  * NNTP specific stuff.
  */
-char *index_get_msgid(struct mailbox *mailbox __attribute__((unused)),
+char *index_get_msgid(struct mailbox *mailbox,
 		      unsigned msgno)
 {
+    struct index_record record;
     const char *cacheitem;
     int cachelen;
     char *env;
     char *envtokens[NUMENVTOKENS];
     char *msgid;
 
-    cacheitem = cache_base + CACHE_OFFSET(msgno);
+    mailbox_read_index_record(mailbox, msgno, &record);
+
+    cacheitem = cache_base + record.cache_offset;
     cachelen = CACHE_ITEM_LEN(cacheitem);
 
     /* get msgid out of the envelope
@@ -5023,6 +5066,7 @@
 extern struct nntp_overview *index_overview(struct mailbox *mailbox,
 					    unsigned msgno)
 {
+    struct index_record record;
     static struct nntp_overview over;
     static char *env = NULL, *from = NULL, *hdr = NULL;
     static int envsize = 0, fromsize = 0, hdrsize = 0;
@@ -5031,7 +5075,8 @@
     char *envtokens[NUMENVTOKENS];
     struct address addr = { NULL, NULL, NULL, NULL, NULL, NULL };
 
-    cacheitem = cache_base + CACHE_OFFSET(msgno); /* envelope */
+    mailbox_read_index_record(mailbox, msgno, &record);
+    cacheitem = cache_base + record.cache_offset; /* envelope */
 
     /* make a working copy of envelope; strip outer ()'s */
     /* -2 -> don't include the size of the outer parens */
@@ -5060,8 +5105,8 @@
 
     parse_cached_envelope(env, envtokens, VECTOR_SIZE(envtokens));
 
-    over.uid = UID(msgno);
-    over.bytes = SIZE(msgno);
+    over.uid = record.uid;
+    over.bytes = record.size;
     over.lines = index_getlines(mailbox, msgno);
     over.date = envtokens[ENV_DATE];
     over.msgid = envtokens[ENV_MSGID];
@@ -5105,6 +5150,7 @@
 extern char *index_getheader(struct mailbox *mailbox, unsigned msgno,
 			     char *hdr)
 {
+    struct index_record record;
     static const char *msg_base = 0;
     static unsigned long msg_size = 0;
     struct strlist headers = { NULL, NULL, NULL, NULL };
@@ -5122,10 +5168,12 @@
 	msg_size = 0;
     }
 
+    mailbox_read_index_record(mailbox, msgno, &record);
+
     /* see if the header is cached */
     if (mailbox_cached_header(hdr) != BIT32_MAX) {
 	/* cached header */
-	cacheitem = cache_base + CACHE_OFFSET(msgno);
+	cacheitem = cache_base + record.cache_offset;
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip envelope */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip bodystructure */
 	cacheitem = CACHE_ITEM_NEXT(cacheitem); /* skip body */
@@ -5144,11 +5192,11 @@
     }
     else {
 	/* uncached header */
-	if (mailbox_map_message(mailbox, UID(msgno), &msg_base, &msg_size))
+	if (mailbox_map_message(mailbox, record.uid, &msg_base, &msg_size))
 	    return NULL;
 
 	buf = index_readheader(msg_base, msg_size, mailbox->format, 0,
-			       HEADER_SIZE(msgno));
+			       record.header_size);
     }
 
     index_pruneheader(buf, &headers, NULL);
@@ -5161,32 +5209,32 @@
     return buf;
 }
 
-extern unsigned long index_getsize(struct mailbox *mailbox __attribute__((unused)),
+extern unsigned long index_getsize(struct mailbox *mailbox,
 				   unsigned msgno)
 {
-    return SIZE(msgno);
+    static struct index_record record;
+    mailbox_read_index_record(mailbox, msgno, &record);
+    return record.size;
 }
 
 extern unsigned long index_getlines(struct mailbox *mailbox, unsigned msgno)
 {
-    unsigned long lines = CONTENT_LINES(msgno);
+    struct index_record record;
+
+    mailbox_read_index_record(mailbox, msgno, &record);
+    unsigned long lines = record.content_lines;
 
     if (lines == BIT32_MAX) {
 	int r;
 	char fname[MAX_MAILBOX_PATH+1];
 	FILE *msgfile;
 	char buf[4096];
-	struct index_record record;
 
 	lines = 0;
 
 	r = mailbox_lock_index(mailbox);
 	if (r) return lines;
 
-	/* get the existing record */
-	r = mailbox_read_index_record(mailbox, msgno, &record);
-	if (r) goto done;
-
 	/* Open the message file */
 	strlcpy(fname, mailbox->path, sizeof(fname));
 	strlcat(fname, "/", sizeof(fname));
@@ -5250,8 +5298,8 @@
 /*
  * Parse a sequence into an array of sorted & merged ranges.
  */
-struct seq_set *index_parse_sequence(const char *sequence, int usinguid,
-				     struct seq_set *set)
+struct seq_set *index_parse_sequence(struct mailbox *mailbox, const char *sequence,
+                                     int usinguid, struct seq_set *set)
 {
     unsigned i, j, start, end, *num;
 
@@ -5264,7 +5312,7 @@
 	    *num = (*num)*10 + *sequence - '0';
 	}
 	else if (*sequence == '*') {
-	    *num = usinguid ? UID(imapd_exists) : (unsigned) imapd_exists;
+	    *num = usinguid ? index_getuid(mailbox, imapd_exists) : (unsigned) \
imapd_exists;  }
 	else if (*sequence == ':') {
 	    num = &end;
@@ -5353,13 +5401,13 @@
     }
 }
 
-void appendsequencelist(struct seq_set **l, char *sequence, int usinguid)
+void appendsequencelist(struct mailbox *mailbox, struct seq_set **l, char *sequence, \
int usinguid)  {
     struct seq_set **tail = l;
 
     while (*tail) tail = &(*tail)->next;
 
-    *tail = index_parse_sequence(sequence, usinguid, NULL);
+    *tail = index_parse_sequence(mailbox, sequence, usinguid, NULL);
 }
 
 void freesequencelist(struct seq_set *l)
Index: cyrus-imapd-2.3.10/imap/index.h
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/index.h	2007-10-31 09:44:24.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/index.h	2007-10-31 09:44:34.000000000 -0400
@@ -66,27 +66,6 @@
 #include "mailbox.h" /* for bit32 */
 #include "message_guid.h"
 
-/* Access macros for the memory-mapped index file data */
-#define INDEC_OFFSET(msgno) (index_base+start_offset+(((msgno)-1)*record_size))
-#define UID(msgno) ntohl(*((bit32 *)(INDEC_OFFSET(msgno)+OFFSET_UID)))
-#define INTERNALDATE(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_INTERNALDATE)))
-#define SENTDATE(msgno) ntohl(*((bit32 *)(INDEC_OFFSET(msgno)+OFFSET_SENTDATE)))
-#define SIZE(msgno) ntohl(*((bit32 *)(INDEC_OFFSET(msgno)+OFFSET_SIZE)))
-#define HEADER_SIZE(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_HEADER_SIZE)))
-#define CONTENT_OFFSET(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_CONTENT_OFFSET)))
-#define CACHE_OFFSET(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_CACHE_OFFSET)))
-#define LAST_UPDATED(msgno) ((time_t)ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_LAST_UPDATED))))
-#define SYSTEM_FLAGS(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_SYSTEM_FLAGS)))
-#define USER_FLAGS(msgno,i) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_USER_FLAGS+((i)*4))))
-#define CONTENT_LINES(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_CONTENT_LINES)))
-#define CACHE_VERSION(msgno) ntohl(*((bit32 \
                *)(INDEC_OFFSET(msgno)+OFFSET_CACHE_VERSION)))
-#ifdef HAVE_LONG_LONG_INT
-#define MODSEQ(msgno) ntohll(*((bit64 *)(INDEC_OFFSET(msgno)+OFFSET_MODSEQ_64)))
-#else
-#define MODSEQ(msgno) ntohl(*((bit32 *)(INDEC_OFFSET(msgno)+OFFSET_MODSEQ)))
-#endif
-#define GUID(msgno) message_guid_import(NULL, (unsigned char \
                *)(INDEC_OFFSET(msgno)+OFFSET_MESSAGE_GUID))
-
 /* Access assistance macros for memory-mapped cache file data */
 /* CACHE_ITEM_BIT32: Convert to host byte order */
 /* CACHE_ITEM_LEN: Get the length out */
@@ -149,6 +128,7 @@
     char **annot;		/* array of annotation attribute values
 				   (stored in order of sortcrit) */
     int nannot;			/* number of annotation values */
+    struct index_record *record;
     struct msgdata *next;
 } MsgData;
 
@@ -166,7 +146,7 @@
 
 struct thread_algorithm {
     char *alg_name;
-    void (*threader)(unsigned *msgno_list, int nmsg, int usinguid);
+    void (*threader)(struct mailbox *mailbox, unsigned *msgno_list, int nmsg, int \
usinguid);  };
 
 struct nntp_overview {
@@ -194,8 +174,8 @@
 };
 
 extern void index_operatemailbox(struct mailbox *mailbox);
-extern unsigned index_finduid(unsigned uid);
-extern unsigned index_getuid(unsigned msgno);
+extern unsigned index_finduid(struct mailbox *mailbox, unsigned uid);
+extern unsigned index_getuid(struct mailbox *mailbox, unsigned msgno);
 extern int index_urlfetch(struct mailbox *mailbox, unsigned msgno,
 			  const char *section,
 			  unsigned long start_octet, unsigned long octet_count,
@@ -210,10 +190,12 @@
 extern int index_copy_remote(struct mailbox *mailbox, char *sequence, 
 			     int usinguid, struct protstream *pout);
 
-void appendsequencelist(struct seq_set **l, char *sequence, int usinguid);
+void appendsequencelist(struct mailbox *mailbox, struct seq_set **l,
+			char *sequence, int usinguid);
 void freesequencelist(struct seq_set *l);
 
-extern struct seq_set *index_parse_sequence(const char *sequence, int usinguid,
+extern struct seq_set *index_parse_sequence(struct mailbox *mailbox,
+					    const char *sequence, int usinguid, 
 					    struct seq_set *set);
 
 #endif /* INDEX_H */
Index: cyrus-imapd-2.3.10/imap/search_engines.c
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/search_engines.c	2007-10-31 09:44:29.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/search_engines.c	2007-10-31 09:44:34.000000000 -0400
@@ -114,8 +114,8 @@
   }
   
   /* now we need to convert the UID to the message sequence number */
-  index = index_finduid(doc_UID);
-  if (index < 1 || index > imapd_exists || doc_UID != (int) index_getuid(index)) {
+  index = index_finduid(r->mailbox, doc_UID);
+  if (index < 1 || index > imapd_exists || doc_UID != (int) index_getuid(r->mailbox, \
index)) {  return -1;
   }
 
Index: cyrus-imapd-2.3.10/imap/chk_cyrus.c
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/chk_cyrus.c	2007-10-31 09:44:25.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/chk_cyrus.c	2007-10-31 09:44:34.000000000 -0400
@@ -172,11 +172,12 @@
     } else {
 	for(i=1;i<=exists;i++) {
 	    char filebuf[1024];
+            unsigned int uid = ntohl(*((bit32 *)(start_offset+(record_size * \
(i-1))+OFFSET_UID)));  
 	    /* xxx check for monotonic increasing UIDs in the index file */
 	    /* xxx check for nonnegative UIDs in the index file */
 	    
-	    snprintf(filebuf, sizeof(filebuf), "%s/%d.", path, UID(i));
+	    snprintf(filebuf, sizeof(filebuf), "%s/%d.", path, uid);
 	    if(stat(filebuf, &sbuf) == -1) {
 		fprintf(stderr, " -> %s missing\n", filebuf);
 		printf("%s\n",filebuf);
Index: cyrus-imapd-2.3.10/imap/mbexamine.c
===================================================================
--- cyrus-imapd-2.3.10.orig/imap/mbexamine.c	2007-10-31 09:44:28.000000000 -0400
+++ cyrus-imapd-2.3.10/imap/mbexamine.c	2007-10-31 09:44:34.000000000 -0400
@@ -206,8 +206,7 @@
     int flag = 0;
     char ext_name_buf[MAX_MAILBOX_PATH+1];
     struct mailbox mailbox;
-    const char *index_base;
-    long int start_offset, record_size;
+    struct index_record record;
     
     signals_poll();
 
@@ -308,52 +307,50 @@
     }
 
     printf("\n Message Info:\n");
-
-    index_base = mailbox.index_base;
-    start_offset = mailbox.start_offset;
-    record_size = mailbox.record_size;
     
     for(i=1; i<=mailbox.exists; i++) {
 	const char *cacheitem;
 	int j;
 
+        mailbox_read_index_record(&mailbox, i, &record);
+
 	if(wantvalue) {
 	    if(!wantuid) {
 		if(i != wantvalue) continue;
 	    } else {
-		if(UID(i) != wantvalue) continue;
+		if(record.uid != wantvalue) continue;
 	    }
 	    flag = 1;
 	}
 
 	printf("%06d> UID:%08d   INT_DATE:%d SENTDATE:%d SIZE:%-6d\n",
-	       i, UID(i), INTERNALDATE(i), SENTDATE(i),
-	       SIZE(i));
+	       i, record.uid, record.internaldate, record.sentdate,
+               record.size);
 	printf("      > HDRSIZE:%-6d LASTUPD :%ld SYSFLAGS:%08X",
-	       HEADER_SIZE(i), LAST_UPDATED(i), SYSTEM_FLAGS(i));
+	       record.header_size, record.last_updated, record.system_flags);
 	if (mailbox.minor_version >= 5)
-	    printf("   LINES:%-6d\n", CONTENT_LINES(i));
+	    printf("   LINES:%-6d\n", record.content_lines);
 
 	if (mailbox.minor_version >= 6)
-	    printf("      > CACHEVER:%-2d", CACHE_VERSION(i));
+	    printf("      > CACHEVER:%-2d", record.cache_version);
 
 	if (mailbox.minor_version >= 7) {
-	    printf(" GUID: %s", message_guid_encode(GUID(i)));
+	    printf(" GUID: %s", message_guid_encode(&record.guid));
 	}
 
 	if (mailbox.minor_version >= 8) {
-	    printf(" MODSEQ:" MODSEQ_FMT, MODSEQ(i));
+	    printf(" MODSEQ:" MODSEQ_FMT, record.modseq);
 	}
 
 	printf("\n");
 
 	printf("      > USERFLAGS:");
 	for(j=(MAX_USER_FLAGS/32)-1; j>=0; j--) {
-	    printf(" %08X", USER_FLAGS(i,j));
+	    printf(" %08X", record.user_flags[j]);
 	}
 	printf("\n");
 
-	cacheitem = mailbox.cache_base + CACHE_OFFSET(i);
+	cacheitem = mailbox.cache_base + record.cache_offset;
 	
 	printf(" Envel>{%d}%s\n", CACHE_ITEM_LEN(cacheitem),
 	       cacheitem + CACHE_ITEM_SIZE_SKIP);



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic