Re: [PATCH 01/11] lib: new thread addresses structure
authorMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 30 Aug 2012 15:38:51 +0000 (17:38 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:49:14 +0000 (09:49 -0800)
83/1a650e839e34b62d399147e4cf086760725cce [new file with mode: 0644]

diff --git a/83/1a650e839e34b62d399147e4cf086760725cce b/83/1a650e839e34b62d399147e4cf086760725cce
new file mode 100644 (file)
index 0000000..550dbf3
--- /dev/null
@@ -0,0 +1,263 @@
+Return-Path: <sojkam1@fel.cvut.cz>\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 15344431FB6\r
+       for <notmuch@notmuchmail.org>; Thu, 30 Aug 2012 08:39:01 -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 ItPaG9fibirb for <notmuch@notmuchmail.org>;\r
+       Thu, 30 Aug 2012 08:38:59 -0700 (PDT)\r
+Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
+       by olra.theworths.org (Postfix) with ESMTP id 331C6431FAE\r
+       for <notmuch@notmuchmail.org>; Thu, 30 Aug 2012 08:38:59 -0700 (PDT)\r
+Received: from localhost (unknown [192.168.200.4])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id BB63B19F337A;\r
+       Thu, 30 Aug 2012 17:38:54 +0200 (CEST)\r
+X-Virus-Scanned: IMAP AMAVIS\r
+Received: from max.feld.cvut.cz ([192.168.200.1])\r
+       by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new,\r
+       port 10044)\r
+       with ESMTP id jCpFnc00AfAB; Thu, 30 Aug 2012 17:38:52 +0200 (CEST)\r
+Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
+       by max.feld.cvut.cz (Postfix) with ESMTP id 917DA19F32FF;\r
+       Thu, 30 Aug 2012 17:38:52 +0200 (CEST)\r
+Received: from steelpick.2x.cz (note-sojka.felk.cvut.cz [147.32.86.30])\r
+       (Authenticated sender: sojkam1)\r
+       by imap.feld.cvut.cz (Postfix) with ESMTPSA id 3B254660904;\r
+       Thu, 30 Aug 2012 17:38:52 +0200 (CEST)\r
+Received: from wsh by steelpick.2x.cz with local (Exim 4.80)\r
+       (envelope-from <sojkam1@fel.cvut.cz>)\r
+       id 1T76pX-0004f8-Vq; Thu, 30 Aug 2012 17:38:51 +0200\r
+From: Michal Sojka <sojkam1@fel.cvut.cz>\r
+To: Jameson Graef Rollins <jrollins@finestructure.net>,\r
+       Notmuch Mail <notmuch@notmuchmail.org>\r
+Subject: Re: [PATCH 01/11] lib: new thread addresses structure\r
+In-Reply-To: <1345427570-26518-2-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
+User-Agent: Notmuch/0.14+3~g608c52f (http://notmuchmail.org) Emacs/24.1.1\r
+       (x86_64-pc-linux-gnu)\r
+Date: Thu, 30 Aug 2012 17:38:51 +0200\r
+Message-ID: <87y5kw4cfo.fsf@steelpick.2x.cz>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain\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: Thu, 30 Aug 2012 15:39:01 -0000\r
+\r
+Hi Jameson,\r
+\r
+some comments below.\r
+\r
+On Mon, Aug 20 2012, Jameson Graef Rollins wrote:\r
+> This new structure holds addresses associated with a thread, both\r
+> matched and unmatched.  Initially this will be used to replace the\r
+> existing infrastructure for storing the addresses of thread authors.\r
+> Further patches will use it to store the addresses of threads\r
+> recipients.\r
+>\r
+> Init and destructor functions are included, as well as a function to\r
+> add addresses to a struct, either "matched" or not.\r
+> ---\r
+>  lib/notmuch.h |    1 +\r
+>  lib/thread.cc |  116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+>  2 files changed, 117 insertions(+)\r
+>\r
+> diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+> index 3633bed..6acd38d 100644\r
+> --- a/lib/notmuch.h\r
+> +++ b/lib/notmuch.h\r
+> @@ -118,6 +118,7 @@ typedef struct _notmuch_database notmuch_database_t;\r
+>  typedef struct _notmuch_query notmuch_query_t;\r
+>  typedef struct _notmuch_threads notmuch_threads_t;\r
+>  typedef struct _notmuch_thread notmuch_thread_t;\r
+> +typedef struct _notmuch_thread_addresses notmuch_thread_addresses_t;\r
+>  typedef struct _notmuch_messages notmuch_messages_t;\r
+>  typedef struct _notmuch_message notmuch_message_t;\r
+>  typedef struct _notmuch_tags notmuch_tags_t;\r
+> diff --git a/lib/thread.cc b/lib/thread.cc\r
+> index e976d64..7af9eeb 100644\r
+> --- a/lib/thread.cc\r
+> +++ b/lib/thread.cc\r
+> @@ -24,6 +24,14 @@\r
+>  #include <gmime/gmime.h>\r
+>  #include <glib.h> /* GHashTable */\r
+>  \r
+> +struct visible _notmuch_thread_addresses {\r
+> +    GHashTable *matched_hash;\r
+> +    GPtrArray *matched_array;\r
+> +    GHashTable *unmatched_hash;\r
+> +    GPtrArray *unmatched_array;\r
+> +    char *string;\r
+> +};\r
+> +\r
+>  struct visible _notmuch_thread {\r
+>      notmuch_database_t *notmuch;\r
+>      char *thread_id;\r
+> @@ -44,6 +52,18 @@ struct visible _notmuch_thread {\r
+>  };\r
+>  \r
+>  static int\r
+> +_notmuch_thread_addresses_destructor (notmuch_thread_addresses_t *addresses)\r
+> +{\r
+> +    g_hash_table_unref (addresses->matched_hash);\r
+> +    g_hash_table_unref (addresses->unmatched_hash);\r
+> +    g_ptr_array_free (addresses->matched_array, TRUE);\r
+> +    g_ptr_array_free (addresses->unmatched_array, TRUE);\r
+> +    addresses->matched_array = NULL;\r
+> +    addresses->unmatched_array = NULL;\r
+> +    return 0;\r
+> +}\r
+> +\r
+> +static int\r
+>  _notmuch_thread_destructor (notmuch_thread_t *thread)\r
+>  {\r
+>      g_hash_table_unref (thread->authors_hash);\r
+> @@ -64,6 +84,81 @@ _notmuch_thread_destructor (notmuch_thread_t *thread)\r
+>      return 0;\r
+>  }\r
+>  \r
+> +/* Add address to a thread addresses struct.  If matched is TRUE, then\r
+> + * the address will be added to the matched list.*/\r
+> +static void\r
+> +_thread_add_address (notmuch_thread_addresses_t *addresses,\r
+> +                 const char *address,\r
+> +                 notmuch_bool_t matched)\r
+> +{\r
+> +    char *address_copy;\r
+> +    GHashTable *hash;\r
+> +    GPtrArray *array;\r
+> +\r
+> +    if (matched) {\r
+> +    hash = addresses->matched_hash;\r
+> +    array = addresses->matched_array;\r
+> +    } else {\r
+> +    hash = addresses->unmatched_hash;\r
+> +    array = addresses->unmatched_array;\r
+> +    }\r
+> +\r
+> +    if (address == NULL)\r
+> +    return;\r
+> +\r
+> +    if (g_hash_table_lookup_extended (hash, address, NULL, NULL))\r
+> +    return;\r
+> +\r
+> +    address_copy = talloc_strdup (addresses, address);\r
+> +\r
+> +    g_hash_table_insert (hash, address_copy, NULL);\r
+> +\r
+> +    g_ptr_array_add (array, address_copy);\r
+> +}\r
+> +\r
+> +/* Construct an addresses string from matched and unmatched addresses\r
+> + * in notmuch_thread_addresses_t. The string contains matched\r
+> + * addresses first, then non-matched addresses (with the two groups\r
+> + * separated by '|'). Within each group, addresses are listed in date\r
+> + * order. */\r
+\r
+I'd say the the addresses are listed in the order in which they have\r
+been added, which might or might not be the date order.\r
+\r
+> +static void\r
+> +_resolve_thread_addresses_string (notmuch_thread_addresses_t *addresses)\r
+> +{\r
+> +    unsigned int i;\r
+> +    char *address;\r
+> +    int first_non_matched_address = 1;\r
+> +\r
+> +    /* First, list all matched addressses in date order. */\r
+> +    for (i = 0; i < addresses->matched_array->len; i++) {\r
+> +    address = (char *) g_ptr_array_index (addresses->matched_array, i);\r
+> +    if (addresses->string)\r
+> +        addresses->string = talloc_asprintf (addresses, "%s, %s",\r
+> +                                             addresses->string,\r
+> +                                             address);\r
+> +    else\r
+> +        addresses->string = address;\r
+> +    }\r
+> +\r
+> +    /* Next, append any non-matched addresses that haven't already appeared. */\r
+> +    for (i = 0; i < addresses->unmatched_array->len; i++) {\r
+> +    address = (char *) g_ptr_array_index (addresses->unmatched_array, i);\r
+> +    if (g_hash_table_lookup_extended (addresses->matched_hash,\r
+> +                                      address, NULL, NULL))\r
+> +        continue;\r
+> +    if (first_non_matched_address) {\r
+> +        addresses->string = talloc_asprintf (addresses, "%s| %s",\r
+> +                                             addresses->string,\r
+> +                                             address);\r
+> +    } else {\r
+> +        addresses->string = talloc_asprintf (addresses, "%s, %s",\r
+> +                                             addresses->string,\r
+> +                                             address);\r
+> +    }\r
+\r
+Simpler would be:\r
+\r
+addresses->string = talloc_asprintf (addresses, "%s%c %s",\r
+                                     addresses->string,\r
+                                     first_non_matched_address ? '|' : ','\r
+                                     address);\r
+\r
+Also, you might want to talloc_free the old address->string to not waste\r
+memory in the case of long lived notmuch_thread_addresses_t object. Or\r
+better use talloc_asprintf_append() function, which hopefully implements\r
+freeing internally.\r
+\r
+-Michal\r
+\r
+> +\r
+> +    first_non_matched_address = 0;\r
+> +    }\r
+> +}\r
+> +\r
+>  /* Add each author of the thread to the thread's authors_hash and to\r
+>   * the thread's authors_array. */\r
+>  static void\r
+> @@ -382,6 +477,27 @@ _resolve_thread_relationships (unused (notmuch_thread_t *thread))\r
+>       */\r
+>  }\r
+>  \r
+> +/* Initialize a thread addresses struct. */\r
+> +notmuch_thread_addresses_t *\r
+> +_thread_addresses_init (const void *ctx)\r
+> +{\r
+> +    notmuch_thread_addresses_t *addresses;\r
+> +\r
+> +    addresses = talloc (ctx, notmuch_thread_addresses_t);\r
+> +    if (unlikely (addresses == NULL))\r
+> +    return NULL;\r
+> +\r
+> +    addresses->matched_hash = g_hash_table_new_full (g_str_hash, g_str_equal,\r
+> +                                                 NULL, NULL);\r
+> +    addresses->matched_array = g_ptr_array_new ();\r
+> +    addresses->unmatched_hash = g_hash_table_new_full (g_str_hash, g_str_equal,\r
+> +                                                   NULL, NULL);\r
+> +    addresses->unmatched_array = g_ptr_array_new ();\r
+> +    addresses->string = NULL;\r
+> +\r
+> +    return addresses;\r
+> +}\r
+> +\r
+>  /* Create a new notmuch_thread_t object by finding the thread\r
+>   * containing the message with the given doc ID, treating any messages\r
+>   * contained in match_set as "matched".  Remove all messages in the\r
+> -- \r
+> 1.7.10.4\r