[RFC PATCH v5 05/11] lib: Make notmuch_query_search_messages set the exclude flag

Austin Clements amdragon at MIT.EDU
Fri Feb 24 15:39:44 PST 2012


Quoth Mark Walters on Feb 15 at  9:03 am:
> Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by
> notmuch_query_search_messages for excluded messages. Also add an
> option omit_excluded_messages to the search that we do not want the
> excludes at all.
> 
> This exclude flag will be added to notmuch_query_search threads in the
> next patch.
> ---
>  lib/notmuch-private.h |    1 +
>  lib/notmuch.h         |   10 ++++++++-
>  lib/query.cc          |   52 +++++++++++++++++++++++++++++++++++++++++++++---
>  3 files changed, 58 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
> index 7bf153e..e791bb0 100644
> --- a/lib/notmuch-private.h
> +++ b/lib/notmuch-private.h
> @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list {
>   */
>  struct visible _notmuch_messages {
>      notmuch_bool_t is_of_list_type;
> +    notmuch_doc_id_set_t *excluded_doc_ids;
>      notmuch_message_node_t *iterator;
>  };
>  
> diff --git a/lib/notmuch.h b/lib/notmuch.h
> index 7929fe7..f75afae 100644
> --- a/lib/notmuch.h
> +++ b/lib/notmuch.h
> @@ -449,6 +449,13 @@ typedef enum {
>  const char *
>  notmuch_query_get_query_string (notmuch_query_t *query);
>  
> +/* Specify whether to results should omit the excluded results rather
> + * than just marking them excluded. This is useful for passing a
> + * notmuch_messages_t not containing the excluded messages to other
> + * functions. */
> +void
> +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit);
> +
>  /* Specify the sorting desired for this query. */
>  void
>  notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
> @@ -895,7 +902,8 @@ notmuch_message_get_filenames (notmuch_message_t *message);
>  
>  /* Message flags */
>  typedef enum _notmuch_message_flag {
> -    NOTMUCH_MESSAGE_FLAG_MATCH
> +    NOTMUCH_MESSAGE_FLAG_MATCH,
> +    NOTMUCH_MESSAGE_FLAG_EXCLUDED
>  } notmuch_message_flag_t;
>  
>  /* Get a value of a flag for the email corresponding to 'message'. */
> diff --git a/lib/query.cc b/lib/query.cc
> index c25b301..90a71a1 100644
> --- a/lib/query.cc
> +++ b/lib/query.cc
> @@ -28,6 +28,7 @@ struct _notmuch_query {
>      const char *query_string;
>      notmuch_sort_t sort;
>      notmuch_string_list_t *exclude_terms;
> +    notmuch_bool_t omit_excluded_messages;
>  };
>  
>  typedef struct _notmuch_mset_messages {
> @@ -57,6 +58,12 @@ struct visible _notmuch_threads {
>      notmuch_doc_id_set_t match_set;
>  };
>  
> +/* We need this in the message functions so forward declare. */
> +static notmuch_bool_t
> +_notmuch_doc_id_set_init (void *ctx,
> +			  notmuch_doc_id_set_t *doc_ids,
> +			  GArray *arr);
> +
>  notmuch_query_t *
>  notmuch_query_create (notmuch_database_t *notmuch,
>  		      const char *query_string)
> @@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
>  
>      query->exclude_terms = _notmuch_string_list_create (query);
>  
> +    query->omit_excluded_messages = FALSE;
> +
>      return query;
>  }
>  
> @@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
>  }
>  
>  void
> +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit)
> +{
> +    query->omit_excluded_messages = omit;
> +}
> +
> +void
>  notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort)
>  {
>      query->sort = sort;
> @@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
>  						   "mail"));
>  	Xapian::Query string_query, final_query, exclude_query;
>  	Xapian::MSet mset;
> +	Xapian::MSetIterator iterator;
>  	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
>  			      Xapian::QueryParser::FLAG_PHRASE |
>  			      Xapian::QueryParser::FLAG_LOVEHATE |
> @@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
>  	    final_query = Xapian::Query (Xapian::Query::OP_AND,
>  					 mail_query, string_query);
>  	}
> +	messages->base.excluded_doc_ids = NULL;
> +
> +	if (query->exclude_terms) {
> +	    exclude_query = _notmuch_exclude_tags (query, final_query);
> +	    exclude_query = Xapian::Query (Xapian::Query::OP_AND,
> +					   exclude_query, final_query);
> +
> +	    if (query->omit_excluded_messages)
> +		final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
> +					     final_query, exclude_query);
> +	    else {
> +		enquire.set_weighting_scheme (Xapian::BoolWeight());
> +		enquire.set_query (exclude_query);
> +
> +		mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
> +
> +		GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int));
> +
> +		for (iterator = mset.begin (); iterator != mset.end (); iterator++) {
> +		    unsigned int doc_id = *iterator;
> +		    g_array_append_val (excluded_doc_ids, doc_id);
> +		}
> +		messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set);

Should this have 'messages' as its talloc context?

> +		_notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids,
> +					  excluded_doc_ids);
> +		g_array_unref (excluded_doc_ids);
> +	    }
> +	}
>  
> -	exclude_query = _notmuch_exclude_tags (query, final_query);
> -
> -	final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
> -					 final_query, exclude_query);
>  
>  	enquire.set_weighting_scheme (Xapian::BoolWeight());
>  
> @@ -283,6 +323,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
>  	INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
>      }
>  
> +    if (messages->excluded_doc_ids &&
> +	_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))
> +	notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
> +

This, at least, is pleasingly simple!

>      return message;
>  }
>  


More information about the notmuch mailing list