char *message_id;
char *thread_id;
char *in_reply_to;
+ notmuch_string_list_t *filename_term_list;
notmuch_string_list_t *filename_list;
char *author;
notmuch_message_file_t *message_file;
message->message_id = NULL;
message->thread_id = NULL;
message->in_reply_to = NULL;
+ message->filename_term_list = NULL;
message->filename_list = NULL;
message->message_file = NULL;
message->author = NULL;
Xapian::TermIterator i, end;
const char *thread_prefix = _find_prefix ("thread"),
*id_prefix = _find_prefix ("id"),
+ *filename_prefix = _find_prefix ("file-direntry"),
*replyto_prefix = _find_prefix ("replyto");
/* We do this all in a single pass because Xapian decompresses the
message->message_id =
_notmuch_message_get_term (message, i, end, id_prefix);
+ /* Get filename list. Here we get only the terms. We lazily
+ * expand them to full file names when needed in
+ * _notmuch_message_ensure_filename_list. */
+ assert (strcmp (id_prefix, filename_prefix) < 0);
+ if (!message->filename_term_list && !message->filename_list)
+ message->filename_term_list =
+ _notmuch_database_get_terms_with_prefix (message, i, end,
+ filename_prefix);
+
/* Get reply to */
- assert (strcmp (id_prefix, replyto_prefix) < 0);
+ assert (strcmp (filename_prefix, replyto_prefix) < 0);
if (!message->in_reply_to)
message->in_reply_to =
_notmuch_message_get_term (message, i, end, replyto_prefix);
message->thread_id = NULL;
}
+ if (strcmp ("file-direntry", prefix_name) == 0) {
+ talloc_free (message->filename_term_list);
+ talloc_free (message->filename_list);
+ message->filename_term_list = message->filename_list = NULL;
+ }
+
if (strcmp ("replyto", prefix_name) == 0) {
talloc_free (message->in_reply_to);
message->in_reply_to = NULL;
if (filename == NULL)
INTERNAL_ERROR ("Message filename cannot be NULL.");
- if (message->filename_list) {
- talloc_free (message->filename_list);
- message->filename_list = NULL;
- }
-
relative = _notmuch_database_relative_path (message->notmuch, filename);
status = _notmuch_database_split_path (local, relative, &directory, NULL);
notmuch_status_t status;
Xapian::TermIterator i, last;
- if (message->filename_list) {
- talloc_free (message->filename_list);
- message->filename_list = NULL;
- }
-
status = _notmuch_database_filename_to_direntry (local, message->notmuch,
filename, &direntry);
if (status)
static void
_notmuch_message_ensure_filename_list (notmuch_message_t *message)
{
- const char *prefix = _find_prefix ("file-direntry");
- int prefix_len = strlen (prefix);
- Xapian::TermIterator i;
+ notmuch_string_node_t *node;
if (message->filename_list)
return;
- message->filename_list = _notmuch_string_list_create (message);
+ if (!message->filename_term_list)
+ _notmuch_message_ensure_metadata (message);
- i = message->doc.termlist_begin ();
- i.skip_to (prefix);
+ message->filename_list = _notmuch_string_list_create (message);
+ node = message->filename_term_list->head;
- if (i == message->doc.termlist_end () ||
- strncmp ((*i).c_str (), prefix, prefix_len))
- {
+ if (!node) {
/* A message document created by an old version of notmuch
* (prior to rename support) will have the filename in the
* data of the document rather than as a file-direntry term.
return;
}
- for (; i != message->doc.termlist_end (); i++) {
+ for (; node; node = node->next) {
void *local = talloc_new (message);
const char *db_path, *directory, *basename, *filename;
char *colon, *direntry = NULL;
unsigned int directory_id;
- /* Terminate loop at first term without desired prefix. */
- if (strncmp ((*i).c_str (), prefix, prefix_len))
- break;
-
- direntry = talloc_strdup (local, (*i).c_str ());
-
- direntry += prefix_len;
+ direntry = node->string;
directory_id = strtol (direntry, &colon, 10);
talloc_free (local);
}
+
+ talloc_free (message->filename_term_list);
+ message->filename_term_list = NULL;
}
const char *