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 8E451431FAE for ; Sun, 19 Aug 2012 18:53:10 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -2.3 X-Spam-Level: X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_MED=-2.3] 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 d21aE45cpBHE for ; Sun, 19 Aug 2012 18:53:08 -0700 (PDT) Received: from outgoing-mail.its.caltech.edu (outgoing-mail.its.caltech.edu [131.215.239.19]) by olra.theworths.org (Postfix) with ESMTP id BA23A431FB6 for ; Sun, 19 Aug 2012 18:53:06 -0700 (PDT) Received: from earth-doxen.imss.caltech.edu (localhost [127.0.0.1]) by earth-doxen-postvirus (Postfix) with ESMTP id 7292966E0016 for ; Sun, 19 Aug 2012 18:53:06 -0700 (PDT) X-Spam-Scanned: at Caltech-IMSS on earth-doxen by amavisd-new Received: from finestructure.net (unknown [76.89.192.57]) (Authenticated sender: jrollins) by earth-doxen-submit (Postfix) with ESMTP id 4AA8966E00D1 for ; Sun, 19 Aug 2012 18:53:04 -0700 (PDT) Received: by finestructure.net (Postfix, from userid 1000) id C7DE12C3; Sun, 19 Aug 2012 18:53:03 -0700 (PDT) From: Jameson Graef Rollins To: Notmuch Mail Subject: [PATCH 01/11] lib: new thread addresses structure Date: Sun, 19 Aug 2012 18:52:40 -0700 Message-Id: <1345427570-26518-2-git-send-email-jrollins@finestructure.net> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1345427570-26518-1-git-send-email-jrollins@finestructure.net> References: <1345427570-26518-1-git-send-email-jrollins@finestructure.net> 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: Mon, 20 Aug 2012 01:53:11 -0000 This new structure holds addresses associated with a thread, both matched and unmatched. Initially this will be used to replace the existing infrastructure for storing the addresses of thread authors. Further patches will use it to store the addresses of threads recipients. Init and destructor functions are included, as well as a function to add addresses to a struct, either "matched" or not. --- lib/notmuch.h | 1 + lib/thread.cc | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/lib/notmuch.h b/lib/notmuch.h index 3633bed..6acd38d 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -118,6 +118,7 @@ typedef struct _notmuch_database notmuch_database_t; typedef struct _notmuch_query notmuch_query_t; typedef struct _notmuch_threads notmuch_threads_t; typedef struct _notmuch_thread notmuch_thread_t; +typedef struct _notmuch_thread_addresses notmuch_thread_addresses_t; typedef struct _notmuch_messages notmuch_messages_t; typedef struct _notmuch_message notmuch_message_t; typedef struct _notmuch_tags notmuch_tags_t; diff --git a/lib/thread.cc b/lib/thread.cc index e976d64..7af9eeb 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -24,6 +24,14 @@ #include #include /* GHashTable */ +struct visible _notmuch_thread_addresses { + GHashTable *matched_hash; + GPtrArray *matched_array; + GHashTable *unmatched_hash; + GPtrArray *unmatched_array; + char *string; +}; + struct visible _notmuch_thread { notmuch_database_t *notmuch; char *thread_id; @@ -44,6 +52,18 @@ struct visible _notmuch_thread { }; static int +_notmuch_thread_addresses_destructor (notmuch_thread_addresses_t *addresses) +{ + g_hash_table_unref (addresses->matched_hash); + g_hash_table_unref (addresses->unmatched_hash); + g_ptr_array_free (addresses->matched_array, TRUE); + g_ptr_array_free (addresses->unmatched_array, TRUE); + addresses->matched_array = NULL; + addresses->unmatched_array = NULL; + return 0; +} + +static int _notmuch_thread_destructor (notmuch_thread_t *thread) { g_hash_table_unref (thread->authors_hash); @@ -64,6 +84,81 @@ _notmuch_thread_destructor (notmuch_thread_t *thread) return 0; } +/* Add address to a thread addresses struct. If matched is TRUE, then + * the address will be added to the matched list.*/ +static void +_thread_add_address (notmuch_thread_addresses_t *addresses, + const char *address, + notmuch_bool_t matched) +{ + char *address_copy; + GHashTable *hash; + GPtrArray *array; + + if (matched) { + hash = addresses->matched_hash; + array = addresses->matched_array; + } else { + hash = addresses->unmatched_hash; + array = addresses->unmatched_array; + } + + if (address == NULL) + return; + + if (g_hash_table_lookup_extended (hash, address, NULL, NULL)) + return; + + address_copy = talloc_strdup (addresses, address); + + g_hash_table_insert (hash, address_copy, NULL); + + g_ptr_array_add (array, address_copy); +} + +/* Construct an addresses string from matched and unmatched addresses + * in notmuch_thread_addresses_t. The string contains matched + * addresses first, then non-matched addresses (with the two groups + * separated by '|'). Within each group, addresses are listed in date + * order. */ +static void +_resolve_thread_addresses_string (notmuch_thread_addresses_t *addresses) +{ + unsigned int i; + char *address; + int first_non_matched_address = 1; + + /* First, list all matched addressses in date order. */ + for (i = 0; i < addresses->matched_array->len; i++) { + address = (char *) g_ptr_array_index (addresses->matched_array, i); + if (addresses->string) + addresses->string = talloc_asprintf (addresses, "%s, %s", + addresses->string, + address); + else + addresses->string = address; + } + + /* Next, append any non-matched addresses that haven't already appeared. */ + for (i = 0; i < addresses->unmatched_array->len; i++) { + address = (char *) g_ptr_array_index (addresses->unmatched_array, i); + if (g_hash_table_lookup_extended (addresses->matched_hash, + address, NULL, NULL)) + continue; + if (first_non_matched_address) { + addresses->string = talloc_asprintf (addresses, "%s| %s", + addresses->string, + address); + } else { + addresses->string = talloc_asprintf (addresses, "%s, %s", + addresses->string, + address); + } + + first_non_matched_address = 0; + } +} + /* Add each author of the thread to the thread's authors_hash and to * the thread's authors_array. */ static void @@ -382,6 +477,27 @@ _resolve_thread_relationships (unused (notmuch_thread_t *thread)) */ } +/* Initialize a thread addresses struct. */ +notmuch_thread_addresses_t * +_thread_addresses_init (const void *ctx) +{ + notmuch_thread_addresses_t *addresses; + + addresses = talloc (ctx, notmuch_thread_addresses_t); + if (unlikely (addresses == NULL)) + return NULL; + + addresses->matched_hash = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, NULL); + addresses->matched_array = g_ptr_array_new (); + addresses->unmatched_hash = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, NULL); + addresses->unmatched_array = g_ptr_array_new (); + addresses->string = NULL; + + return addresses; +} + /* Create a new notmuch_thread_t object by finding the thread * containing the message with the given doc ID, treating any messages * contained in match_set as "matched". Remove all messages in the -- 1.7.10.4