Skip to content

Commit

Permalink
jmap_mail.c: use nanosecond-based JMAPIDs as EMAILIDs
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed Jan 17, 2025
1 parent 674018b commit a9f64c9
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ sub test_email_set_guidsearch_updated_internaldate
xlog "Append blob of message A via IMAP";
$imap->append('INBOX', $emailBlobA) || die $@;

$res = $imap->fetch('3', "(emailid)");
my $emailIdC = $res->{3}{emailid}[0];

xlog $self, "run incremental squatter";
$self->{instance}->run_command({cyrus => 1}, 'squatter', '-i');

Expand All @@ -132,5 +135,5 @@ sub test_email_set_guidsearch_updated_internaldate
}, 'R1'],
], $using);
$self->assert_equals(JSON::true, $res->[0][1]{performance}{details}{isGuidSearch});
$self->assert_deep_equals([$emailIdB, $emailIdA], $res->[0][1]{ids});
$self->assert_deep_equals([$emailIdB, $emailIdC], $res->[0][1]{ids});
}
8 changes: 5 additions & 3 deletions imap/caldav_alarm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,8 @@ static int find_scheduled_email(const char *emailid,
struct conversations_state *cstate = NULL;
int r;

if (emailid[0] != 'M' || strlen(emailid) != 25) {
if (emailid[0] != JMAP_EMAILID_PREFIX ||
strlen(emailid) != JMAP_EMAILID_SIZE - 1) {
return IMAP_NOTFOUND;
}

Expand All @@ -1612,8 +1613,9 @@ static int find_scheduled_email(const char *emailid,
return r;
}

const char *guid = emailid + 1;
r = conversations_guid_foreach(cstate, guid, find_sched_cb, frock);
char guid[2*MESSAGE_GUID_SIZE+1];
r = conversations_lookup_jmapid(cstate, emailid + 1, guid);
if (!r) r = conversations_guid_foreach(cstate, guid, find_sched_cb, frock);
conversations_commit(&cstate);

if (r == IMAP_OK_COMPLETED) r = 0;
Expand Down
26 changes: 26 additions & 0 deletions imap/conversations.c
Original file line number Diff line number Diff line change
Expand Up @@ -3333,4 +3333,30 @@ EXPORTED int conversations_zero_modseq(struct conversations_state *state)
return r;
}

EXPORTED int conversations_lookup_jmapid(struct conversations_state *state,
const char *jidrep, char guidrep[])
{
char key[CONV_JMAPID_SIZE+2] = "J";
size_t datalen = 0;
const char *data;
int r;

if (strlen(jidrep) != CONV_JMAPID_SIZE)
return CYRUSDB_NOTFOUND;

strcat(key, jidrep);

r = cyrusdb_fetch(state->db, key, CONV_JMAPID_SIZE+1,
&data, &datalen, &state->txn);
if (r) return r;

if (datalen != 2*MESSAGE_GUID_SIZE)
return CYRUSDB_NOTFOUND;

strncpy(guidrep, data, datalen);
guidrep[datalen] = '\0';

return 0;
}

#undef DB
6 changes: 6 additions & 0 deletions imap/conversations.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ extern int conversations_guid_cid_lookup(struct conversations_state *state,
strcmpsafe(conv_guidrec_uniqueid(rec), mailbox_uniqueid(mbox)) : \
strcmpsafe(conv_guidrec_mboxname(rec), mailbox_name(mbox)) \
)

/* J record items */
#define CONV_JMAPID_SIZE 11 // 64-bits base64-encoded w/o padding
extern int conversations_lookup_jmapid(struct conversations_state *state,
const char *jidrep, char guidrep[]);

/* F record items */
extern int conversation_getstatus(struct conversations_state *state,
const char *mailbox,
Expand Down
17 changes: 12 additions & 5 deletions imap/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -4537,11 +4537,11 @@ static int index_fetchreply(struct index_state *state, uint32_t msgno,
sepchar = ' ';
}
if (fetchitems & FETCH_EMAILID) {
char emailid[26];
emailid[0] = 'M';
memcpy(emailid+1, message_guid_encode(&record.guid), 24);
emailid[25] = '\0';
prot_printf(state->out, "%cEMAILID (%s)", sepchar, emailid);
struct buf emailid = BUF_INITIALIZER;
buf_putc(&emailid, 'S');
NANOSEC_TO_JMAPID(&emailid, TIMESPEC_TO_NANOSEC(&record.internaldate));
prot_printf(state->out, "%cEMAILID (%s)", sepchar, buf_cstring(&emailid));
buf_free(&emailid);
sepchar = ' ';
}
if ((fetchitems & FETCH_CID) &&
Expand Down Expand Up @@ -6848,6 +6848,13 @@ static int index_sort_compare(MsgData *md1, MsgData *md2,
case SORT_GUID:
ret = message_guid_cmp(&md1->guid, &md2->guid);
break;
case SORT_EMAILID:
// EMAILIDs are an ASCII-order encoding of
// (INT_MAX - nano_internaldate),
// so the reverse order of nano_internaldate
ret = numcmp(TIMESPEC_TO_NANOSEC(&md2->internaldate),
TIMESPEC_TO_NANOSEC(&md1->internaldate));
break;
}
} while (!ret && sortcrit[i++].key != SORT_SEQUENCE);

Expand Down
4 changes: 3 additions & 1 deletion imap/jmap_blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,10 +804,12 @@ static int jmap_blob_lookup(jmap_req_t *req)

/* Read message record */
struct message_guid guid;
struct timespec internaldate;
bit64 cid = 0;
msgrecord_t *mr = NULL;
r = msgrecord_find(mbox, getblob->uid, &mr);
if (!r) r = msgrecord_get_guid(mr, &guid);
if (!r) r = msgrecord_get_internaldate(mr, &internaldate);
if (!r) r = msgrecord_get_cid(mr, &cid);
msgrecord_unref(&mr);
if (r) {
Expand Down Expand Up @@ -848,7 +850,7 @@ static int jmap_blob_lookup(jmap_req_t *req)

case DATATYPE_EMAIL: {
char emailid[JMAP_EMAILID_SIZE];
jmap_set_emailid(&guid, emailid);
jmap_set_emailid_ts(&internaldate, emailid);
strarray_add(ids, emailid);
break;
}
Expand Down
Loading

0 comments on commit a9f64c9

Please sign in to comment.