[PATCH 06/11] lib: store thread recipients in thread structure
authorJameson Graef Rollins <jrollins@finestructure.net>
Mon, 20 Aug 2012 01:52:45 +0000 (18:52 +1700)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:49:09 +0000 (09:49 -0800)
ab/fe9007f70870451f24061a2d10185430979706 [new file with mode: 0644]

diff --git a/ab/fe9007f70870451f24061a2d10185430979706 b/ab/fe9007f70870451f24061a2d10185430979706
new file mode 100644 (file)
index 0000000..d929757
--- /dev/null
@@ -0,0 +1,312 @@
+Return-Path: <jrollins@finestructure.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id D7801431FBD\r
+       for <notmuch@notmuchmail.org>; Sun, 19 Aug 2012 18:53:14 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -2.3\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id 1prNKKMgMWAR for <notmuch@notmuchmail.org>;\r
+       Sun, 19 Aug 2012 18:53:12 -0700 (PDT)\r
+Received: from outgoing-mail.its.caltech.edu (outgoing-mail.its.caltech.edu\r
+       [131.215.239.19])\r
+       by olra.theworths.org (Postfix) with ESMTP id 87E6E431FC2\r
+       for <notmuch@notmuchmail.org>; Sun, 19 Aug 2012 18:53:08 -0700 (PDT)\r
+Received: from fire-doxen.imss.caltech.edu (localhost [127.0.0.1])\r
+       by fire-doxen-postvirus (Postfix) with ESMTP id C92ED2E50D7B\r
+       for <notmuch@notmuchmail.org>; Sun, 19 Aug 2012 18:53:07 -0700 (PDT)\r
+X-Spam-Scanned: at Caltech-IMSS on fire-doxen by amavisd-new\r
+Received: from finestructure.net (unknown [76.89.192.57])\r
+       (Authenticated sender: jrollins)\r
+       by fire-doxen-submit (Postfix) with ESMTP id 9ED252E50D80\r
+       for <notmuch@notmuchmail.org>; Sun, 19 Aug 2012 18:53:05 -0700 (PDT)\r
+Received: by finestructure.net (Postfix, from userid 1000)\r
+       id D6FE893E; Sun, 19 Aug 2012 18:53:03 -0700 (PDT)\r
+From: Jameson Graef Rollins <jrollins@finestructure.net>\r
+To: Notmuch Mail <notmuch@notmuchmail.org>\r
+Subject: [PATCH 06/11] lib: store thread recipients in thread structure\r
+Date: Sun, 19 Aug 2012 18:52:45 -0700\r
+Message-Id: <1345427570-26518-7-git-send-email-jrollins@finestructure.net>\r
+X-Mailer: git-send-email 1.7.10.4\r
+In-Reply-To: <1345427570-26518-6-git-send-email-jrollins@finestructure.net>\r
+References: <1345427570-26518-1-git-send-email-jrollins@finestructure.net>\r
+       <1345427570-26518-2-git-send-email-jrollins@finestructure.net>\r
+       <1345427570-26518-3-git-send-email-jrollins@finestructure.net>\r
+       <1345427570-26518-4-git-send-email-jrollins@finestructure.net>\r
+       <1345427570-26518-5-git-send-email-jrollins@finestructure.net>\r
+       <1345427570-26518-6-git-send-email-jrollins@finestructure.net>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Mon, 20 Aug 2012 01:53:15 -0000\r
+\r
+This utilizes the new thread addresses struct to store thread\r
+recipients, again in parallel to authors.\r
+\r
+Since message recipients are not stored in the database, including\r
+recipients in the thread structure exacts a significant overhead as\r
+the recipients are retrieved from the original message files.  Because\r
+of this, a new boolean argument, include_recipients, is added to the\r
+necessary functions (_notmuch_thread_create, _thread_add_message and\r
+_thread_add_matched_message) that controls whether the recipients are\r
+fetched and included.  If message recipients are ever stored in the\r
+database this new argument could probably be removed.\r
+---\r
+ lib/notmuch-private.h |    3 +-\r
+ lib/notmuch.h         |   14 +++++++++\r
+ lib/query.cc          |    3 +-\r
+ lib/thread.cc         |   77 +++++++++++++++++++++++++++++++++++++------------\r
+ 4 files changed, 76 insertions(+), 21 deletions(-)\r
+\r
+diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
+index 27a41b6..32d1523 100644\r
+--- a/lib/notmuch-private.h\r
++++ b/lib/notmuch-private.h\r
+@@ -232,7 +232,8 @@ _notmuch_thread_create (void *ctx,\r
+                       unsigned int seed_doc_id,\r
+                       notmuch_doc_id_set_t *match_set,\r
+                       notmuch_string_list_t *excluded_terms,\r
+-                      notmuch_sort_t sort);\r
++                      notmuch_sort_t sort,\r
++                      notmuch_bool_t include_recipients);\r
\r
+ /* message.cc */\r
\r
+diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+index 6acd38d..f9e71c1 100644\r
+--- a/lib/notmuch.h\r
++++ b/lib/notmuch.h\r
+@@ -759,6 +759,20 @@ notmuch_thread_get_matched_messages (notmuch_thread_t *thread);\r
+ const char *\r
+ notmuch_thread_get_authors (notmuch_thread_t *thread);\r
\r
++/* Get the recipients of 'thread'\r
++ *\r
++ * The returned string is a comma-separated list of the names of the\r
++ * recipients of mail messages in the query results that belong to this\r
++ * thread.\r
++ *\r
++ * The returned string belongs to 'thread' and as such, should not be\r
++ * modified by the caller and will only be valid for as long as the\r
++ * thread is valid, (which is until notmuch_thread_destroy or until\r
++ * the query from which it derived is destroyed).\r
++ */\r
++const char *\r
++notmuch_thread_get_recipients (notmuch_thread_t *thread);\r
++\r
+ /* Get the subject of 'thread'\r
+  *\r
+  * The subject is taken from the first message (according to the query\r
+diff --git a/lib/query.cc b/lib/query.cc\r
+index e9c1a2d..54833a7 100644\r
+--- a/lib/query.cc\r
++++ b/lib/query.cc\r
+@@ -486,7 +486,8 @@ notmuch_threads_get (notmuch_threads_t *threads)\r
+                                  doc_id,\r
+                                  &threads->match_set,\r
+                                  threads->query->exclude_terms,\r
+-                                 threads->query->sort);\r
++                                 threads->query->sort,\r
++                                 FALSE);\r
+ }\r
\r
+ void\r
+diff --git a/lib/thread.cc b/lib/thread.cc\r
+index 757e143..baf07c2 100644\r
+--- a/lib/thread.cc\r
++++ b/lib/thread.cc\r
+@@ -37,6 +37,7 @@ struct visible _notmuch_thread {\r
+     char *thread_id;\r
+     char *subject;\r
+     notmuch_thread_addresses_t *authors;\r
++    notmuch_thread_addresses_t *recipients;\r
+     GHashTable *tags;\r
\r
+     notmuch_message_list_t *message_list;\r
+@@ -63,6 +64,7 @@ static int\r
+ _notmuch_thread_destructor (notmuch_thread_t *thread)\r
+ {\r
+     _notmuch_thread_addresses_destructor (thread->authors);\r
++    _notmuch_thread_addresses_destructor (thread->recipients);\r
+     g_hash_table_unref (thread->tags);\r
+     g_hash_table_unref (thread->message_hash);\r
+     return 0;\r
+@@ -204,14 +206,17 @@ _thread_cleanup_address (notmuch_thread_t *thread,\r
+ static void\r
+ _thread_add_message (notmuch_thread_t *thread,\r
+                    notmuch_message_t *message,\r
+-                   notmuch_string_list_t *exclude_terms)\r
++                   notmuch_string_list_t *exclude_terms,\r
++                   notmuch_bool_t include_recipients)\r
+ {\r
+     notmuch_tags_t *tags;\r
+     const char *tag;\r
+-    InternetAddressList *list = NULL;\r
++    InternetAddressList *from_list = NULL;\r
++    InternetAddressList *to_list = NULL;\r
+     InternetAddress *address;\r
+     const char *from, *author;\r
+-    char *clean_author;\r
++    const char *to, *recipient;\r
++    char *clean_address;\r
\r
+     _notmuch_message_list_add_message (thread->message_list,\r
+                                      talloc_steal (thread, message));\r
+@@ -223,10 +228,9 @@ _thread_add_message (notmuch_thread_t *thread,\r
\r
+     from = notmuch_message_get_header (message, "from");\r
+     if (from)\r
+-      list = internet_address_list_parse_string (from);\r
+-\r
+-    if (list) {\r
+-      address = internet_address_list_get_address (list, 0);\r
++      from_list = internet_address_list_parse_string (from);\r
++    if (from_list) {\r
++      address = internet_address_list_get_address (from_list, 0);\r
+       if (address) {\r
+           author = internet_address_get_name (address);\r
+           if (author == NULL) {\r
+@@ -234,11 +238,32 @@ _thread_add_message (notmuch_thread_t *thread,\r
+               mailbox = INTERNET_ADDRESS_MAILBOX (address);\r
+               author = internet_address_mailbox_get_addr (mailbox);\r
+           }\r
+-          clean_author = _thread_cleanup_author (thread, author, from);\r
+-          _thread_add_address (thread->authors, clean_author, FALSE);\r
+-          notmuch_message_set_author (message, clean_author);\r
++          clean_address = _thread_cleanup_address (thread, author, from);\r
++          _thread_add_address (thread->authors, clean_address, FALSE);\r
++          notmuch_message_set_author (message, clean_address);\r
++      }\r
++      g_object_unref (G_OBJECT (from_list));\r
++    }\r
++\r
++    if (include_recipients) {\r
++    to = notmuch_message_get_header (message, "to");\r
++    if (to)\r
++      to_list = internet_address_list_parse_string (to);\r
++    if (to_list) {\r
++      address = internet_address_list_get_address (to_list, 0);\r
++      if (address) {\r
++          recipient = internet_address_get_name (address);\r
++          if (recipient == NULL) {\r
++              InternetAddressMailbox *mailbox;\r
++              mailbox = INTERNET_ADDRESS_MAILBOX (address);\r
++              recipient = internet_address_mailbox_get_addr (mailbox);\r
++          }\r
++          clean_address = _thread_cleanup_address (thread, recipient, to);\r
++          _thread_add_address (thread->recipients, clean_address, FALSE);\r
++          notmuch_message_set_recipients (message, clean_address);\r
+       }\r
+-      g_object_unref (G_OBJECT (list));\r
++      g_object_unref (G_OBJECT (to_list));\r
++    }\r
+     }\r
\r
+     if (! thread->subject) {\r
+@@ -301,7 +326,8 @@ _thread_set_subject_from_message (notmuch_thread_t *thread,\r
+ static void\r
+ _thread_add_matched_message (notmuch_thread_t *thread,\r
+                            notmuch_message_t *message,\r
+-                           notmuch_sort_t sort)\r
++                           notmuch_sort_t sort,\r
++                           notmuch_bool_t include_recipients)\r
+ {\r
+     time_t date;\r
+     notmuch_message_t *hashed_message;\r
+@@ -331,6 +357,8 @@ _thread_add_matched_message (notmuch_thread_t *thread,\r
+     }\r
\r
+     _thread_add_address (thread->authors, notmuch_message_get_author (hashed_message), TRUE);\r
++    if (include_recipients)\r
++    _thread_add_address (thread->recipients, notmuch_message_get_recipients (hashed_message), TRUE);\r
+ }\r
\r
+ static void\r
+@@ -399,10 +427,10 @@ _thread_addresses_init (const void *ctx)\r
+  *\r
+  * Creating the thread will perform a database search to get all\r
+  * messages belonging to the thread and will get the first subject\r
+- * line, the total count of messages, and all authors in the thread.\r
+- * Each message in the thread is checked against match_set to allow\r
+- * for a separate count of matched messages, and to allow a viewer to\r
+- * display these messages differently.\r
++ * line, the total count of messages, and all authors and recipients\r
++ * of the thread.  Each message in the thread is checked against\r
++ * match_set to allow for a separate count of matched messages, and to\r
++ * allow a viewer to display these messages differently.\r
+  *\r
+  * Here, 'ctx' is talloc context for the resulting thread object.\r
+  *\r
+@@ -414,7 +442,8 @@ _notmuch_thread_create (void *ctx,\r
+                       unsigned int seed_doc_id,\r
+                       notmuch_doc_id_set_t *match_set,\r
+                       notmuch_string_list_t *exclude_terms,\r
+-                      notmuch_sort_t sort)\r
++                      notmuch_sort_t sort,\r
++                      notmuch_bool_t include_recipients)\r
+ {\r
+     notmuch_thread_t *thread;\r
+     notmuch_message_t *seed_message;\r
+@@ -453,6 +482,9 @@ _notmuch_thread_create (void *ctx,\r
+     thread->authors = _thread_addresses_init (thread);\r
+     if (unlikely (thread->authors == NULL))\r
+       return NULL;\r
++    thread->recipients = _thread_addresses_init (thread);\r
++    if (unlikely (thread->recipients == NULL))\r
++      return NULL;\r
\r
+     thread->tags = g_hash_table_new_full (g_str_hash, g_str_equal,\r
+                                         free, NULL);\r
+@@ -486,11 +518,11 @@ _notmuch_thread_create (void *ctx,\r
+       if (doc_id == seed_doc_id)\r
+           message = seed_message;\r
\r
+-      _thread_add_message (thread, message, exclude_terms);\r
++      _thread_add_message (thread, message, exclude_terms, include_recipients);\r
\r
+       if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {\r
+           _notmuch_doc_id_set_remove (match_set, doc_id);\r
+-          _thread_add_matched_message (thread, message, sort);\r
++          _thread_add_matched_message (thread, message, sort, include_recipients);\r
+       }\r
\r
+       _notmuch_message_close (message);\r
+@@ -499,6 +531,7 @@ _notmuch_thread_create (void *ctx,\r
+     notmuch_query_destroy (thread_id_query);\r
\r
+     _resolve_thread_addresses_string (thread->authors);\r
++    _resolve_thread_addresses_string (thread->recipients);\r
\r
+     _resolve_thread_relationships (thread);\r
\r
+@@ -536,6 +569,12 @@ notmuch_thread_get_authors (notmuch_thread_t *thread)\r
+ }\r
\r
+ const char *\r
++notmuch_thread_get_recipients (notmuch_thread_t *thread)\r
++{\r
++    return thread->recipients->string;\r
++}\r
++\r
++const char *\r
+ notmuch_thread_get_subject (notmuch_thread_t *thread)\r
+ {\r
+     return thread->subject;\r
+-- \r
+1.7.10.4\r
+\r