]> git.notmuchmail.org Git - notmuch/blobdiff - lib/thread.cc
Merge branch 'release'
[notmuch] / lib / thread.cc
index e976d643db3584f7ce057a7e20dc4adca2bcbdb7..c126aac8cc8b945e9018f7505f7910174c83535e 100644 (file)
@@ -35,7 +35,11 @@ struct visible _notmuch_thread {
     char *authors;
     GHashTable *tags;
 
+    /* All messages, oldest first. */
     notmuch_message_list_t *message_list;
+    /* Top-level messages, oldest first. */
+    notmuch_message_list_t *toplevel_list;
+
     GHashTable *message_hash;
     int total_messages;
     int matched_messages;
@@ -345,29 +349,22 @@ _thread_add_matched_message (notmuch_thread_t *thread,
 }
 
 static void
-_resolve_thread_relationships (unused (notmuch_thread_t *thread))
+_resolve_thread_relationships (notmuch_thread_t *thread)
 {
-    notmuch_message_node_t **prev, *node;
+    notmuch_message_node_t *node;
     notmuch_message_t *message, *parent;
     const char *in_reply_to;
 
-    prev = &thread->message_list->head;
-    while ((node = *prev)) {
+    for (node = thread->message_list->head; node; node = node->next) {
        message = node->message;
        in_reply_to = _notmuch_message_get_in_reply_to (message);
        if (in_reply_to && strlen (in_reply_to) &&
            g_hash_table_lookup_extended (thread->message_hash,
                                          in_reply_to, NULL,
                                          (void **) &parent))
-       {
-           *prev = node->next;
-           if (thread->message_list->tail == &node->next)
-               thread->message_list->tail = prev;
-           node->next = NULL;
-           _notmuch_message_add_reply (parent, node);
-       } else {
-           prev = &((*prev)->next);
-       }
+           _notmuch_message_add_reply (parent, message);
+       else
+           _notmuch_message_list_add_message (thread->toplevel_list, message);
     }
 
     /* XXX: After scanning through the entire list looking for parents
@@ -406,7 +403,8 @@ _notmuch_thread_create (void *ctx,
                        notmuch_string_list_t *exclude_terms,
                        notmuch_sort_t sort)
 {
-    notmuch_thread_t *thread;
+    void *local = talloc_new (ctx);
+    notmuch_thread_t *thread = NULL;
     notmuch_message_t *seed_message;
     const char *thread_id;
     char *thread_id_query_string;
@@ -415,24 +413,23 @@ _notmuch_thread_create (void *ctx,
     notmuch_messages_t *messages;
     notmuch_message_t *message;
 
-    seed_message = _notmuch_message_create (ctx, notmuch, seed_doc_id, NULL);
+    seed_message = _notmuch_message_create (local, notmuch, seed_doc_id, NULL);
     if (! seed_message)
        INTERNAL_ERROR ("Thread seed message %u does not exist", seed_doc_id);
 
     thread_id = notmuch_message_get_thread_id (seed_message);
-    thread_id_query_string = talloc_asprintf (ctx, "thread:%s", thread_id);
+    thread_id_query_string = talloc_asprintf (local, "thread:%s", thread_id);
     if (unlikely (thread_id_query_string == NULL))
-       return NULL;
+       goto DONE;
 
-    thread_id_query = notmuch_query_create (notmuch, thread_id_query_string);
+    thread_id_query = talloc_steal (
+       local, notmuch_query_create (notmuch, thread_id_query_string));
     if (unlikely (thread_id_query == NULL))
-       return NULL;
+       goto DONE;
 
-    talloc_free (thread_id_query_string);
-
-    thread = talloc (ctx, notmuch_thread_t);
+    thread = talloc (local, notmuch_thread_t);
     if (unlikely (thread == NULL))
-       return NULL;
+       goto DONE;
 
     talloc_set_destructor (thread, _notmuch_thread_destructor);
 
@@ -451,8 +448,12 @@ _notmuch_thread_create (void *ctx,
                                          free, NULL);
 
     thread->message_list = _notmuch_message_list_create (thread);
-    if (unlikely (thread->message_list == NULL))
-       return NULL;
+    thread->toplevel_list = _notmuch_message_list_create (thread);
+    if (unlikely (thread->message_list == NULL ||
+                 thread->toplevel_list == NULL)) {
+       thread = NULL;
+       goto DONE;
+    }
 
     thread->message_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                  free, NULL);
@@ -489,17 +490,26 @@ _notmuch_thread_create (void *ctx,
        _notmuch_message_close (message);
     }
 
-    notmuch_query_destroy (thread_id_query);
-
     _resolve_thread_authors_string (thread);
 
     _resolve_thread_relationships (thread);
 
+    /* Commit to returning thread. */
+    talloc_steal (ctx, thread);
+
+  DONE:
+    talloc_free (local);
     return thread;
 }
 
 notmuch_messages_t *
 notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread)
+{
+    return _notmuch_messages_create (thread->toplevel_list);
+}
+
+notmuch_messages_t *
+notmuch_thread_get_messages (notmuch_thread_t *thread)
 {
     return _notmuch_messages_create (thread->message_list);
 }