static bool imapc_mail_get_cached_guid(struct mail *_mail) { struct index_mail *imail = (struct index_mail *)_mail; const enum index_cache_field cache_idx = imail->ibox->cache_fields[MAIL_CACHE_GUID].idx; string_t *str; if (imail->data.guid != NULL) { if (mail_cache_field_can_add(_mail->transaction->cache_trans, _mail->seq, cache_idx)) { /* GUID was prefetched - add to cache */ index_mail_cache_add_idx(imail, cache_idx, imail->data.guid, strlen(imail->data.guid)+1); } return TRUE; } str = str_new(imail->mail.data_pool, 64); if (mail_cache_lookup_field(_mail->transaction->cache_view, str, imail->mail.mail.seq, cache_idx) > 0) { imail->data.guid = str_c(str); return TRUE; } return FALSE; }
static int dbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key, enum index_cache_field cache_field, const char **value_r) { struct index_mail *imail = &mail->imail; struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(imail->mail.mail.box); const char *value; string_t *str; uint32_t order; str = str_new(imail->mail.data_pool, 64); if (mail_cache_lookup_field(imail->mail.mail.transaction->cache_view, str, imail->mail.mail.seq, ibox->cache_fields[cache_field].idx) > 0) { if (cache_field == MAIL_CACHE_POP3_ORDER) { i_assert(str_len(str) == sizeof(order)); memcpy(&order, str_data(str), sizeof(order)); str_truncate(str, 0); if (order != 0) str_printfa(str, "%u", order); else { /* order=0 means it doesn't exist. we don't want to return "0" though, because then the mails get ordered to beginning, while nonexistent are supposed to be ordered at the end. */ } } *value_r = str_c(str); return 0; } if (dbox_mail_metadata_get(mail, key, &value) < 0) return -1; if (value == NULL) value = ""; if (cache_field != MAIL_CACHE_POP3_ORDER) { index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx, value, strlen(value)+1); } else { if (str_to_uint(value, &order) < 0) order = 0; index_mail_cache_add_idx(imail, ibox->cache_fields[cache_field].idx, &order, sizeof(order)); } /* don't return pointer to dbox metadata directly, since it may change unexpectedly */ str_truncate(str, 0); str_append(str, value); *value_r = str_c(str); return 0; }
int index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf, unsigned int field_idx) { int ret; ret = mail_cache_lookup_field(mail->trans->cache_view, buf, mail->data.seq, field_idx); if (ret > 0) mail->mail.stats_cache_hit_count++; return ret; }
static int imapc_mail_get_guid(struct mail *_mail, const char **value_r) { struct index_mail *imail = (struct index_mail *)_mail; struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box; const enum index_cache_field cache_idx = imail->ibox->cache_fields[MAIL_CACHE_GUID].idx; string_t *str; if (imail->data.guid != NULL) { *value_r = imail->data.guid; return 0; } str = str_new(imail->mail.data_pool, 64); if (mail_cache_lookup_field(_mail->transaction->cache_view, str, imail->mail.mail.seq, cache_idx) > 0) { *value_r = str_c(str); return 0; } /* GUID not in cache, fetch it */ if (mbox->guid_fetch_field_name != NULL) { if (imapc_mail_fetch(_mail, MAIL_FETCH_GUID) < 0) return -1; if (imail->data.guid == NULL) { (void)imapc_mail_failed(_mail, mbox->guid_fetch_field_name); return -1; } } else { /* use hash of message headers as the GUID */ if (imapc_mail_get_hdr_hash(imail) < 0) return -1; } index_mail_cache_add_idx(imail, cache_idx, imail->data.guid, strlen(imail->data.guid)+1); *value_r = imail->data.guid; return 0; }