[notmuch] [PATCH 4/5] Added backwards iterator to threads
Ruben Pollan
meskio at sindominio.net
Sat Mar 20 03:23:24 PDT 2010
Added the functions notmuch_threads_move_to_prevoius,
notmuch_threads_move_to_last and notmuch_threads_move_to_first to
notmuch library. With them is possible to iterate backwards on threads.
* notmuch_threads_move_to_prevoius do the opposite than
notmuch_threads_move_to_next, getting the threads iterator one
position backwards.
* notmuch_threads_move_to_last move the iterator to the first last thread.
* notmuch_threads_move_to_first move the iterator to the first valid
thread.
For it has been implemented notmuch_thread_list_t structur that stores
the thread_ids so the backwards iteration gets the thread_id in the same
order that was show on forward iteration.
---
lib/notmuch.h | 28 +++++++++++
lib/query.cc | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 159 insertions(+), 12 deletions(-)
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 753f3bb..b96b624 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -466,6 +466,15 @@ notmuch_threads_valid (notmuch_threads_t *threads);
notmuch_thread_t *
notmuch_threads_get (notmuch_threads_t *threads);
+/* Move the 'threads' iterator to the first thread.
+ *
+ * After that the 'threads' iterator will be set to the first valid
+ * thread, so it can be use to iterate with
+ * notmuch_threads_move_to_next.
+ */
+void
+notmuch_threads_move_to_first (notmuch_threads_t *threads);
+
/* Move the 'threads' iterator to the next thread.
*
* If 'threads' is already pointing at the last thread then the
@@ -479,6 +488,25 @@ notmuch_threads_get (notmuch_threads_t *threads);
void
notmuch_threads_move_to_next (notmuch_threads_t *threads);
+/* Move the 'threads' iterator to the last thread.
+ *
+ * After that the 'threads' iterator will be set to the last valid
+ * thread, so it can be use to iterate with
+ * notmuch_threads_move_to_previous.
+ */
+void
+notmuch_threads_move_to_last (notmuch_threads_t *threads);
+
+/* Move the 'threads' iterator to the previous thread.
+ *
+ * If 'threads' is already pointing at the first thread then the
+ * iterator will be moved to a point just beyond that first thread,
+ * (where notmuch_threads_valid will return FALSE and
+ * notmuch_threads_get will return NULL).
+ */
+void
+notmuch_threads_move_to_previous (notmuch_threads_t *threads);
+
/* Destroy a notmuch_threads_t object.
*
* It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 44950c1..39985e7 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -39,13 +39,25 @@ typedef struct _notmuch_mset_messages {
Xapian::MSetIterator iterator_end;
} notmuch_mset_messages_t;
+typedef struct _notmuch_thread_node {
+ const char *thread_id;
+ struct _notmuch_thread_node *next;
+ struct _notmuch_thread_node *prev;
+} notmuch_thread_node_t;
+
+typedef struct _notmuch_thread_list {
+ notmuch_thread_node_t *head;
+ notmuch_thread_node_t *tail;
+ notmuch_thread_node_t *iterator;
+} notmuch_thread_list_t;
+
struct _notmuch_threads {
notmuch_query_t *query;
GHashTable *threads;
notmuch_messages_t *messages;
- /* This thread ID is our iterator state. */
- const char *thread_id;
+ /* thread list with the thread_id of the showed messages */
+ notmuch_thread_list_t *list;
};
notmuch_query_t *
@@ -269,6 +281,64 @@ _notmuch_mset_messages_move_to_previous (notmuch_messages_t *messages)
}
}
+static void
+_notmuch_thread_list_create (notmuch_thread_list_t *list, const char *thread_id)
+{
+ list->head = talloc (list, notmuch_thread_node_t);
+ list->tail = list->head;
+ list->iterator = list->head;
+ list->iterator->thread_id = thread_id;
+ list->iterator->next = NULL;
+ list->iterator->prev = NULL;
+}
+
+static void
+_notmuch_thread_list_append (notmuch_thread_list_t *list, const char *thread_id)
+{
+ list->tail->next = talloc (list, notmuch_thread_node_t);
+ list->iterator = list->tail->next;
+ list->iterator->thread_id = thread_id;
+ list->iterator->next = NULL;
+ list->iterator->prev = list->tail;
+ list->tail = list->iterator;
+}
+
+static const char *
+_notmuch_thread_list_get_id (notmuch_thread_list_t *list)
+{
+ return list->iterator->thread_id;
+}
+
+static notmuch_bool_t
+_notmuch_thread_list_valid (notmuch_thread_list_t *list)
+{
+ return (list->iterator != NULL);
+}
+
+static void
+_notmuch_thread_list_move_to_first (notmuch_thread_list_t *list)
+{
+ list->iterator = list->head;
+}
+
+static void
+_notmuch_thread_list_move_to_next (notmuch_thread_list_t *list)
+{
+ list->iterator = list->iterator->next;
+}
+
+static void
+_notmuch_thread_list_move_to_last (notmuch_thread_list_t *list)
+{
+ list->iterator = list->tail;
+}
+
+static void
+_notmuch_thread_list_move_to_previous (notmuch_thread_list_t *list)
+{
+ list->iterator = list->iterator->prev;
+}
+
/* Glib objects force use to use a talloc destructor as well, (but not
* nearly as ugly as the for messages due to C++ objects). At
* this point, I'd really like to have some talloc-friendly
@@ -297,10 +367,13 @@ notmuch_query_search_threads (notmuch_query_t *query)
threads->messages = notmuch_query_search_messages (query);
+ threads->list = talloc (threads, notmuch_thread_list_t);
message = notmuch_messages_get (threads->messages);
- threads->thread_id = notmuch_message_get_thread_id (message);
+ _notmuch_thread_list_create (threads->list,
+ notmuch_message_get_thread_id (message));
g_hash_table_insert (threads->threads,
- xstrdup (threads->thread_id), NULL);
+ xstrdup (_notmuch_thread_list_get_id (threads->list)),
+ NULL);
talloc_set_destructor (threads, _notmuch_threads_destructor);
@@ -316,7 +389,7 @@ notmuch_query_destroy (notmuch_query_t *query)
notmuch_bool_t
notmuch_threads_valid (notmuch_threads_t *threads)
{
- return (threads->thread_id != NULL);
+ return _notmuch_thread_list_valid (threads->list);
}
notmuch_thread_t *
@@ -327,37 +400,83 @@ notmuch_threads_get (notmuch_threads_t *threads)
return _notmuch_thread_create (threads->query,
threads->query->notmuch,
- threads->thread_id,
+ _notmuch_thread_list_get_id (threads->list),
threads->query->query_string);
}
void
+notmuch_threads_move_to_first (notmuch_threads_t *threads)
+{
+ _notmuch_thread_list_move_to_first (threads->list);
+}
+
+void
notmuch_threads_move_to_next (notmuch_threads_t *threads)
{
- notmuch_message_t *message;
+ if (!_notmuch_thread_list_valid (threads->list))
+ return;
+
+ _notmuch_thread_list_move_to_next (threads->list);
+ if (_notmuch_thread_list_valid (threads->list))
+ return;
while (notmuch_messages_valid (threads->messages))
{
- message = notmuch_messages_get (threads->messages);
+ notmuch_message_t *message;
+ const char *thread_id;
- threads->thread_id = notmuch_message_get_thread_id (message);
+ message = notmuch_messages_get (threads->messages);
+ thread_id = notmuch_message_get_thread_id (message);
if (! g_hash_table_lookup_extended (threads->threads,
- threads->thread_id,
+ thread_id,
NULL, NULL))
{
g_hash_table_insert (threads->threads,
- xstrdup (threads->thread_id), NULL);
+ xstrdup (thread_id), NULL);
+ _notmuch_thread_list_append (threads->list, thread_id);
notmuch_messages_move_to_next (threads->messages);
return;
}
notmuch_messages_move_to_next (threads->messages);
}
+}
+
+void
+notmuch_threads_move_to_last (notmuch_threads_t *threads)
+{
+ _notmuch_thread_list_move_to_last (threads->list);
+
+ while (notmuch_messages_valid (threads->messages))
+ {
+ notmuch_message_t *message;
+ const char *thread_id;
+
+ message = notmuch_messages_get (threads->messages);
+ thread_id = notmuch_message_get_thread_id (message);
+
+ if (! g_hash_table_lookup_extended (threads->threads,
+ thread_id,
+ NULL, NULL))
+ {
+ g_hash_table_insert (threads->threads,
+ xstrdup (thread_id), NULL);
+ _notmuch_thread_list_append (threads->list, thread_id);
+ }
- threads->thread_id = NULL;
+ notmuch_messages_move_to_next (threads->messages);
+ }
}
+void
+notmuch_threads_move_to_previous (notmuch_threads_t *threads)
+{
+ if (!_notmuch_thread_list_valid (threads->list))
+ return;
+
+ _notmuch_thread_list_move_to_previous (threads->list);
+}
void
notmuch_threads_destroy (notmuch_threads_t *threads)
--
1.7.0
More information about the notmuch
mailing list