+/* Glib objects force use to use a talloc destructor as well, (but not
+ * nearly as ugly as the for message_results due to C++ objects). At
+ * this point, I'd really like to have some talloc-friendly
+ * equivalents for the few pieces of glib that I'm using. */
+static int
+_notmuch_thread_results_destructor (notmuch_thread_results_t *results)
+{
+ g_ptr_array_free (results->threads, TRUE);
+
+ return 0;
+}
+
+notmuch_thread_results_t *
+notmuch_query_search_threads (notmuch_query_t *query)
+{
+ notmuch_thread_results_t *thread_results;
+ notmuch_thread_t *thread;
+ const char *thread_id;
+ notmuch_message_results_t *message_results;
+ notmuch_message_t *message;
+ notmuch_tags_t *tags;
+ const char *tag;
+ GHashTable *seen;
+
+ thread_results = talloc (query, notmuch_thread_results_t);
+ if (thread_results == NULL)
+ return NULL;
+
+ thread_results->notmuch = query->notmuch;
+ thread_results->threads = g_ptr_array_new ();
+ thread_results->index = 0;
+
+ talloc_set_destructor (thread_results, _notmuch_thread_results_destructor);
+
+ seen = g_hash_table_new_full (g_str_hash, g_str_equal,
+ free, NULL);
+
+ for (message_results = notmuch_query_search_messages (query);
+ notmuch_message_results_has_more (message_results);
+ notmuch_message_results_advance (message_results))
+ {
+ message = notmuch_message_results_get (message_results);
+
+ thread_id = notmuch_message_get_thread_id (message);
+
+ if (! g_hash_table_lookup_extended (seen,
+ thread_id, NULL,
+ (void **) &thread))
+ {
+ const char *subject;
+
+ thread = _notmuch_thread_create (query, query->notmuch,
+ thread_id);
+
+ subject = _notmuch_message_get_subject (message);
+
+ _notmuch_thread_set_subject (thread, subject);
+
+ g_hash_table_insert (seen, xstrdup (thread_id), thread);
+
+ g_ptr_array_add (thread_results->threads, thread);
+ }
+
+ for (tags = notmuch_message_get_tags (message);
+ notmuch_tags_has_more (tags);
+ notmuch_tags_advance (tags))
+ {
+ tag = notmuch_tags_get (tags);
+ _notmuch_thread_add_tag (thread, tag);
+ }
+
+ notmuch_message_destroy (message);
+ }
+
+ g_hash_table_unref (seen);
+
+ return thread_results;
+}
+