Skip to content

Commit

Permalink
mailbox.c: add BASECID to v20 index record
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed Jan 21, 2025
1 parent e45ff88 commit 33bef57
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 18 deletions.
1 change: 0 additions & 1 deletion cunit/annotate.testc
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,6 @@ static void test_msg_copy(void)
buf_printf(&path2, "%s/data/uuid/%c/%c/%s/cyrus.annotations", DBDIR,
u2[0], u2[1], u2);
CU_ASSERT_EQUAL(fexists(buf_cstring(&path1)), 0);
CU_ASSERT_EQUAL(fexists(buf_cstring(&path2)), 0);
mailbox_close(&mailbox1);

/* copy MBOXNAME1,1 -> MBOXNAME2,1 */
Expand Down
2 changes: 2 additions & 0 deletions cunit/mailbox.testc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ static void test_aligned_record_offsets(void)
* not need to care about that. Instead, keep this list sorted
* alphabetically by the OFFSET_... name, for ease of maintenance.
*/
CU_ASSERT_EQUAL(0, OFFSET_BASECID % alignof(r.basecid));
CU_ASSERT_EQUAL(0, OFFSET_CACHE_CRC % alignof(r.cache_crc));
CU_ASSERT_EQUAL(0, OFFSET_CACHE_OFFSET % alignof(XXX_CACHE32_TYPE));
CU_ASSERT_EQUAL(0, OFFSET_CACHE_VERSION % alignof(XXX_CACHE32_TYPE));
Expand Down Expand Up @@ -243,6 +244,7 @@ static void test_unique_record_offsets(void)
/* Keep this sorted alphabetically by the OFFSET_... name, for ease of
* maintenance. We'll qsort it into the order the test needs shortly.
*/
OFFSET(OFFSET_BASECID, sizeof(r.basecid)),
OFFSET(OFFSET_CACHE_CRC, sizeof(r.cache_crc)),
OFFSET(OFFSET_CACHE_OFFSET, sizeof(XXX_CACHE32_TYPE)),
OFFSET(OFFSET_CACHE_VERSION, sizeof(XXX_CACHE32_TYPE)),
Expand Down
1 change: 1 addition & 0 deletions imap/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,7 @@ static const annotate_entrydesc_t message_builtin_entries[] =
},
{
/* we use 'basethrid' to support split threads */
/* prior to version 20, there was no storage for basethrid, so it became an annotation */
IMAP_ANNOT_NS "basethrid",
ATTRIB_TYPE_STRING,
BACKEND_ONLY,
Expand Down
31 changes: 20 additions & 11 deletions imap/mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,7 @@ static int mailbox_buf_to_index_record(const char *buf, int version,
record->gmtime = ntohll(*((bit64 *)(buf+OFFSET_GMTIME)));
record->last_updated = ntohll(*((bit64 *)(buf+OFFSET_LAST_UPDATED)));
record->savedate = ntohll(*((bit64 *)(buf+OFFSET_SAVEDATE)));
record->basecid = ntohll(*(bit64 *)(buf+OFFSET_BASECID));

offset_cache_crc = OFFSET_CACHE_CRC;
offset_record_crc = OFFSET_RECORD_CRC;
Expand Down Expand Up @@ -2206,18 +2207,20 @@ static int _store_change(struct mailbox *mailbox, struct index_record *record, i
free(c_env);
}

annotate_state_t *astate = NULL;
int r = mailbox_get_annotate_state(mailbox, record->uid, &astate);
if (r) return r;
if (mailbox->i.minor_version < 20) {
annotate_state_t *astate = NULL;
int r = mailbox_get_annotate_state(mailbox, record->uid, &astate);
if (r) return r;

struct buf annotval = BUF_INITIALIZER;
if (record->cid && record->basecid && record->basecid != record->cid)
buf_printf(&annotval, CONV_FMT, record->basecid);
struct buf annotval = BUF_INITIALIZER;
if (record->cid && record->basecid && record->basecid != record->cid)
buf_printf(&annotval, CONV_FMT, record->basecid);

r = annotate_state_writesilent(astate, IMAP_ANNOT_NS "basethrid", "", &annotval);
buf_free(&annotval);
r = annotate_state_writesilent(astate, IMAP_ANNOT_NS "basethrid", "", &annotval);
buf_free(&annotval);

if (r) return r;
if (r) return r;
}

return 0;
}
Expand Down Expand Up @@ -3306,6 +3309,12 @@ static bit32 mailbox_index_record_to_buf(struct index_record *record,
*((bit64 *)(buf+OFFSET_LAST_UPDATED)) = htonll(record->last_updated);
*((bit64 *)(buf+OFFSET_SAVEDATE)) = htonll(record->savedate);

if (!(record->internal_flags & FLAG_INTERNAL_SPLITCONVERSATION) ||
record->basecid == record->cid) {
record->basecid = NULLCONVERSATION;
}
*((bit64 *)(buf+OFFSET_BASECID)) = htonll(record->basecid);

offset_cache_crc = OFFSET_CACHE_CRC;
offset_record_crc = OFFSET_RECORD_CRC;

Expand Down Expand Up @@ -5055,8 +5064,8 @@ static int mailbox_repack_setup(struct mailbox *mailbox, int version,
break;
case 20:
repack->newmailbox.i.start_offset = 160;
/* version 20 grew size and time fields to 64-bits */
repack->newmailbox.i.record_size = 136;
/* version 20 grew size and time fields to 64-bits, and added basecid */
repack->newmailbox.i.record_size = 144;
break;
default:
fatal("index version not supported", EX_SOFTWARE);
Expand Down
9 changes: 5 additions & 4 deletions imap/mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ struct index_record {
uint16_t cache_version;
struct message_guid guid;
modseq_t modseq;
bit64 cid;
modseq_t createdmodseq;
bit64 cid;
bit64 basecid;
bit32 cache_crc;

/* metadata */
uint32_t recno;
unsigned silentupdate:1;
unsigned ignorelimits:1;
bit64 basecid;
struct cacherecord crec;
};

Expand Down Expand Up @@ -411,8 +411,9 @@ struct mailbox_iter;
#define OFFSET_GMTIME 104 /* grew to 64-bit in v20 */
#define OFFSET_LAST_UPDATED 112 /* grew to 64-bit in v20 */
#define OFFSET_SAVEDATE 120 /* added in v15 */
#define OFFSET_CACHE_CRC 128 /* CRC32 of cache record */
#define OFFSET_RECORD_CRC 132
#define OFFSET_BASECID 128 /* base conversation id, added in v20 */
#define OFFSET_CACHE_CRC 136 /* CRC32 of cache record */
#define OFFSET_RECORD_CRC 140

#define PRE20_OFFSET_INTERNALDATE 4
#define PRE20_OFFSET_SENTDATE 8
Expand Down
6 changes: 5 additions & 1 deletion imap/mbexamine.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,11 @@ static int do_examine(struct findall_data *data, void *rock)
}

if (mailbox->i.minor_version >= 13) {
printf(" THRID: " CONV_FMT, record->cid);
printf(" CID: " CONV_FMT, record->cid);
}

if (mailbox->i.minor_version >= 20) {
printf(" BASECID: " CONV_FMT, record->basecid);
}

printf("\n");
Expand Down
4 changes: 3 additions & 1 deletion perl/imap/Cyrus/IndexFile.pm
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ SKIPPED VERSION 11 - Fastmail internal only
13: GmTime time_t 8
14: LastUpdated time_t 8
15: SaveDate time_t 8
11: BaseCID hex 8
16: CacheCRC int32 4
17: RecordCRC int32 4
Expand Down Expand Up @@ -1307,7 +1308,7 @@ QuotaExpungedUsed int64 8
ChangesEpoch int32 4
HeaderCrc int32 4
EOF
RecordSize => 136, # defined in file too, check it!
RecordSize => 144, # defined in file too, check it!
_make_fields('Record', <<EOF),
Uid int32 4
CacheOffset int32 4
Expand All @@ -1325,6 +1326,7 @@ CreatedModseq int64 8
GmTime time64 8
LastUpdated time64 8
SaveDate time64 8
BaseCID hex 8
CacheCrc int32 4
RecordCrc int32 4
EOF
Expand Down

0 comments on commit 33bef57

Please sign in to comment.