Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 0B066431FB6 for ; Thu, 9 Dec 2010 13:05:38 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZSHQ38EDw+G4 for ; Thu, 9 Dec 2010 13:05:37 -0800 (PST) Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU [18.9.25.15]) by olra.theworths.org (Postfix) with ESMTP id 7B43C431FB5 for ; Thu, 9 Dec 2010 13:05:37 -0800 (PST) X-AuditID: 1209190f-b7c1dae000000a2b-6d-4d014374b292 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) by dmz-mailsec-scanner-4.mit.edu (Symantec Brightmail Gateway) with SMTP id DB.E2.02603.473410D4; Thu, 9 Dec 2010 16:00:36 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id oB9L0awt030973; Thu, 9 Dec 2010 16:00:36 -0500 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id oB9L0YMl010121 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Thu, 9 Dec 2010 16:00:35 -0500 (EST) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.72) (envelope-from ) id 1PQnbO-0007Hy-Pf; Thu, 09 Dec 2010 16:00:34 -0500 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH 5/5] Add the tag list to the unified message metadata pass. Date: Thu, 9 Dec 2010 15:59:56 -0500 Message-Id: <1291928396-27937-6-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1291928396-27937-1-git-send-email-amdragon@mit.edu> References: <1291928396-27937-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: AAAAARbjX5o= Cc: Austin Clements X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Dec 2010 21:05:38 -0000 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. --- lib/message.cc | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/message.cc b/lib/message.cc index adb205f..cc75a71 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; @@ -102,6 +103,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; @@ -293,6 +295,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"); @@ -311,6 +314,13 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message) message->thread_id = _notmuch_message_get_term (message, i, end, thread_prefix); + /* Get tags */ + if (!message->tag_list) { + message->tag_list = + _notmuch_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); if (!message->message_id) @@ -345,6 +355,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); @@ -645,14 +660,14 @@ 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_get_terms_with_prefix (message, i, end, - _find_prefix ("tag")); - _notmuch_string_list_sort (tags); - return _notmuch_tags_create (message, tags, TRUE); + if (!message->tag_list) + _notmuch_message_ensure_metadata (message); + + /* We tell the iterator to add a talloc reference to the + * underlying list, rather than stealing it. As a result, it's + * possible to modify the message tags while iterating because + * the iterator will keep the current list alive. */ + return _notmuch_tags_create (message, message->tag_list, FALSE); } const char * @@ -1210,6 +1225,7 @@ notmuch_message_remove_all_tags (notmuch_message_t *message) if (! message->frozen) _notmuch_message_sync (message); + talloc_free (tags); return NOTMUCH_STATUS_SUCCESS; } -- 1.7.2.3