On Thu, Jun 2, 2011 at 10:20 AM, Sebastian Spaeth <sebast...@sspaeth.de> wrote: > On Thu, 2 Jun 2011 19:43:29 +1000, Brian May wrote: >> On 2 June 2011 17:05, Sebastian Spaeth <sebast...@sspaeth.de> wrote: >> >> > What would be the best way to solve this (besides fixing the C api to >> > allow to reset the iterator ;-) ?) > >> * It is not easy to fix the C api to reset the iterator (what about >> repeating the search?) > > I am not sure about the difficulty of that, I am not a C-kind of > guy. Repeating the search would be easy but potentially gives you > different results since the db could have changed since then.
Not too hard. Here's an utterly untested patch that implements iterator resetting for notmuch_messages_t iterators. It *should* be much more efficient than performing the query again, but if you use it, I'd love to know if that's actually true. This may not be useful if __len__ is gone, unless you really want to turn Messages/Threads into iterators rather than generators (as I've pointed out before, there is absolutely nothing unusual or un-Pythonic about how Messages/Threads works right now [well, except for the presence of __len__ in a generator, I suppose]). diff --git a/lib/messages.c b/lib/messages.c index 7bcd1ab..085691c 100644 --- a/lib/messages.c +++ b/lib/messages.c @@ -80,7 +80,8 @@ _notmuch_messages_create (notmuch_message_list_t *list) return NULL; messages->is_of_list_type = TRUE; - messages->iterator = list->head; + messages->head = list->head; + notmuch_messages_reset (messages); return messages; } @@ -137,6 +138,15 @@ notmuch_messages_move_to_next (notmuch_messages_t *messages) } void +notmuch_messages_reset (notmuch_messages_t *messages) +{ + if (! messages->is_of_list_type) + return _notmuch_mset_messages_reset (messages); + + messages->iterator = messages->head; +} + +void notmuch_messages_destroy (notmuch_messages_t *messages) { talloc_free (messages); diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 02e24ee..805d60c 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -413,6 +413,7 @@ typedef struct _notmuch_message_list { */ struct visible _notmuch_messages { notmuch_bool_t is_of_list_type; + notmuch_message_node_t *head; notmuch_message_node_t *iterator; }; @@ -441,6 +442,9 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages); void _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages); +void +_notmuch_mset_messages_reset (notmuch_messages_t *messages); + notmuch_bool_t _notmuch_doc_id_set_contains (notmuch_doc_id_set_t *doc_ids, unsigned int doc_id); diff --git a/lib/notmuch.h b/lib/notmuch.h index 9cdcec0..044cfaa 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -734,6 +734,15 @@ notmuch_messages_get (notmuch_messages_t *messages); void notmuch_messages_move_to_next (notmuch_messages_t *messages); +/* Reset the 'messages' iterator back to the first message. + * + * For iterators returned from notmuch_query_search_messages, this is + * both more efficient than performing the query a second time and + * guaranteed to result in the same messages as the first iteration. + */ +void +notmuch_messages_reset (notmuch_messages_t *messages); + /* Destroy a notmuch_messages_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 6f02b04..1e75be0 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -32,6 +32,7 @@ struct _notmuch_query { typedef struct _notmuch_mset_messages { notmuch_messages_t base; notmuch_database_t *notmuch; + Xapian::MSet mset; Xapian::MSetIterator iterator; Xapian::MSetIterator iterator_end; } notmuch_mset_messages_t; @@ -128,6 +129,7 @@ notmuch_query_search_messages (notmuch_query_t *query) messages->base.is_of_list_type = FALSE; messages->base.iterator = NULL; messages->notmuch = notmuch; + new (&messages->mset) Xapian::MSet (); new (&messages->iterator) Xapian::MSetIterator (); new (&messages->iterator_end) Xapian::MSetIterator (); @@ -181,8 +183,8 @@ notmuch_query_search_messages (notmuch_query_t *query) mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); - messages->iterator = mset.begin (); - messages->iterator_end = mset.end (); + messages->mset = mset; + _notmuch_mset_messages_reset (&messages->base); return &messages->base; @@ -257,6 +259,17 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) mset_messages->iterator++; } +void +_notmuch_mset_messages_reset (notmuch_messages_t *messages) +{ + notmuch_mset_messages_t *mset_messages; + + mset_messages = (notmuch_mset_messages_t *) messages; + + mset_messages->iterator = mset_messages->mset.begin (); + mset_messages->iterator_end = mset_messages->mset.end (); +} + static notmuch_bool_t _notmuch_doc_id_set_init (void *ctx, notmuch_doc_id_set_t *doc_ids, _______________________________________________ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch