lib: Add the exclude flag to notmuch_query_search_threads

Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to
notmuch_query_search_threads. Implemented by inspecting the tags
directly in _notmuch_thread_create/_thread_add_message rather than as
a Xapian query for speed reasons.

Note notmuch_thread_get_matched_messages now returns the number of
non-excluded matching messages. This API is not totally desirable but
fixing it means breaking binary compatibility so we delay that.
This commit is contained in:
Mark Walters 2012-03-01 22:30:38 +00:00 committed by David Bremner
parent c9eb94d7fb
commit 1a53f9f116
4 changed files with 25 additions and 7 deletions

View file

@ -148,6 +148,8 @@ typedef enum _notmuch_private_status {
typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t; typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
typedef struct _notmuch_string_list notmuch_string_list_t;
/* database.cc */ /* database.cc */
/* Lookup a prefix value by name. /* Lookup a prefix value by name.
@ -216,6 +218,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch, notmuch_database_t *notmuch,
unsigned int seed_doc_id, unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set, notmuch_doc_id_set_t *match_set,
notmuch_string_list_t *excluded_terms,
notmuch_sort_t sort); notmuch_sort_t sort);
/* message.cc */ /* message.cc */
@ -459,11 +462,11 @@ typedef struct _notmuch_string_node {
struct _notmuch_string_node *next; struct _notmuch_string_node *next;
} notmuch_string_node_t; } notmuch_string_node_t;
typedef struct visible _notmuch_string_list { struct visible _notmuch_string_list {
int length; int length;
notmuch_string_node_t *head; notmuch_string_node_t *head;
notmuch_string_node_t **tail; notmuch_string_node_t **tail;
} notmuch_string_list_t; };
notmuch_string_list_t * notmuch_string_list_t *
_notmuch_string_list_create (const void *ctx); _notmuch_string_list_create (const void *ctx);

View file

@ -672,8 +672,10 @@ notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread);
/* Get the number of messages in 'thread' that matched the search. /* Get the number of messages in 'thread' that matched the search.
* *
* This count includes only the messages in this thread that were * This count includes only the messages in this thread that were
* matched by the search from which the thread was created. Contrast * matched by the search from which the thread was created and were
* with notmuch_thread_get_total_messages() . * not excluded by any exclude tags passed in with the query (see
* notmuch_query_add_tag_exclude). Contrast with
* notmuch_thread_get_total_messages() .
*/ */
int int
notmuch_thread_get_matched_messages (notmuch_thread_t *thread); notmuch_thread_get_matched_messages (notmuch_thread_t *thread);

View file

@ -475,6 +475,7 @@ notmuch_threads_get (notmuch_threads_t *threads)
threads->query->notmuch, threads->query->notmuch,
doc_id, doc_id,
&threads->match_set, &threads->match_set,
threads->query->exclude_terms,
threads->query->sort); threads->query->sort);
} }

View file

@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread,
*/ */
static void static void
_thread_add_message (notmuch_thread_t *thread, _thread_add_message (notmuch_thread_t *thread,
notmuch_message_t *message) notmuch_message_t *message,
notmuch_string_list_t *exclude_terms)
{ {
notmuch_tags_t *tags; notmuch_tags_t *tags;
const char *tag; const char *tag;
@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread,
notmuch_tags_move_to_next (tags)) notmuch_tags_move_to_next (tags))
{ {
tag = notmuch_tags_get (tags); tag = notmuch_tags_get (tags);
/* Mark excluded messages. */
for (notmuch_string_node_t *term = exclude_terms->head; term;
term = term->next) {
/* We ignore initial 'K'. */
if (strcmp(tag, (term->string + 1)) == 0) {
notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
break;
}
}
g_hash_table_insert (thread->tags, xstrdup (tag), NULL); g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
} }
} }
@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread,
_thread_set_subject_from_message (thread, message); _thread_set_subject_from_message (thread, message);
} }
thread->matched_messages++; if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
thread->matched_messages++;
if (g_hash_table_lookup_extended (thread->message_hash, if (g_hash_table_lookup_extended (thread->message_hash,
notmuch_message_get_message_id (message), NULL, notmuch_message_get_message_id (message), NULL,
@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx,
notmuch_database_t *notmuch, notmuch_database_t *notmuch,
unsigned int seed_doc_id, unsigned int seed_doc_id,
notmuch_doc_id_set_t *match_set, notmuch_doc_id_set_t *match_set,
notmuch_string_list_t *exclude_terms,
notmuch_sort_t sort) notmuch_sort_t sort)
{ {
notmuch_thread_t *thread; notmuch_thread_t *thread;
@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx,
if (doc_id == seed_doc_id) if (doc_id == seed_doc_id)
message = seed_message; message = seed_message;
_thread_add_message (thread, message); _thread_add_message (thread, message, exclude_terms);
if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { if ( _notmuch_doc_id_set_contains (match_set, doc_id)) {
_notmuch_doc_id_set_remove (match_set, doc_id); _notmuch_doc_id_set_remove (match_set, doc_id);