diff options
author | Austin Clements <amdragon@mit.edu> | 2010-12-09 01:54:34 -0500 |
---|---|---|
committer | Austin Clements <amdragon@mit.edu> | 2011-03-21 02:45:18 -0400 |
commit | d19c5de17a606e08860a5de951c780038dec2f89 (patch) | |
tree | e6645c7cfe0ebf76021d60a40ec692f37c4295ee /lib/message.cc | |
parent | f271071330fed2947abfa7e9956a85a978924548 (diff) |
Add the tag list to the unified message metadata pass.
Now each caller of notmuch_message_get_tags only gets a new iterator,
instead of a whole new list. In principle this could cause problems
with iterating while modifying tags, but through the magic of talloc
references, we keep the old tag list alive even after the cache in the
message object is invalidated.
This reduces my index search from the 3.102 seconds before the unified
metadata pass to 1.811 seconds (1.7X faster). Combined with the
thread search optimization in b3caef1f0659dac8183441357c8fee500a940889,
that makes this query 2.5X faster than when I started.
Diffstat (limited to 'lib/message.cc')
-rw-r--r-- | lib/message.cc | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/lib/message.cc b/lib/message.cc index 43f8e700..ecda75af 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -32,6 +32,7 @@ struct _notmuch_message { char *message_id; char *thread_id; char *in_reply_to; + notmuch_string_list_t *tag_list; notmuch_string_list_t *filename_term_list; notmuch_string_list_t *filename_list; char *author; @@ -103,6 +104,7 @@ _notmuch_message_create_for_document (const void *talloc_owner, message->message_id = NULL; message->thread_id = NULL; message->in_reply_to = NULL; + message->tag_list = NULL; message->filename_term_list = NULL; message->filename_list = NULL; message->message_file = NULL; @@ -295,6 +297,7 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message) { Xapian::TermIterator i, end; const char *thread_prefix = _find_prefix ("thread"), + *tag_prefix = _find_prefix ("tag"), *id_prefix = _find_prefix ("id"), *filename_prefix = _find_prefix ("file-direntry"), *replyto_prefix = _find_prefix ("replyto"); @@ -313,8 +316,17 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message) message->thread_id = _notmuch_message_get_term (message, i, end, thread_prefix); + /* Get tags */ + assert (strcmp (thread_prefix, tag_prefix) < 0); + if (!message->tag_list) { + message->tag_list = + _notmuch_database_get_terms_with_prefix (message, i, end, + tag_prefix); + _notmuch_string_list_sort (message->tag_list); + } + /* Get id */ - assert (strcmp (thread_prefix, id_prefix) < 0); + assert (strcmp (tag_prefix, id_prefix) < 0); if (!message->message_id) message->message_id = _notmuch_message_get_term (message, i, end, id_prefix); @@ -348,6 +360,11 @@ _notmuch_message_invalidate_metadata (notmuch_message_t *message, message->thread_id = NULL; } + if (strcmp ("tag", prefix_name) == 0) { + talloc_unlink (message, message->tag_list); + message->tag_list = NULL; + } + if (strcmp ("file-direntry", prefix_name) == 0) { talloc_free (message->filename_term_list); talloc_free (message->filename_list); @@ -712,14 +729,20 @@ notmuch_message_get_date (notmuch_message_t *message) notmuch_tags_t * notmuch_message_get_tags (notmuch_message_t *message) { - Xapian::TermIterator i, end; - notmuch_string_list_t *tags; - i = message->doc.termlist_begin(); - end = message->doc.termlist_end(); - tags = _notmuch_database_get_terms_with_prefix (message, i, end, - _find_prefix ("tag")); - _notmuch_string_list_sort (tags); - return _notmuch_tags_create (message, tags); + notmuch_tags_t *tags; + + if (!message->tag_list) + _notmuch_message_ensure_metadata (message); + + tags = _notmuch_tags_create (message, message->tag_list); + /* _notmuch_tags_create steals the reference to the tag_list, but + * in this case it's still used by the message, so we add an + * *additional* talloc reference to the list. As a result, it's + * possible to modify the message tags (which talloc_unlink's the + * current list from the message) while still iterating because + * the iterator will keep the current list alive. */ + talloc_reference (message, message->tag_list); + return tags; } const char * @@ -1287,6 +1310,7 @@ notmuch_message_remove_all_tags (notmuch_message_t *message) if (! message->frozen) _notmuch_message_sync (message); + talloc_free (tags); return NOTMUCH_STATUS_SUCCESS; } |