--- /dev/null
+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