Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 38457431FD0 for ; Thu, 2 Jun 2011 07:38:49 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.699 X-Spam-Level: X-Spam-Status: No, score=-0.699 tagged_above=-999 required=5 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id S+TvpbWxgSr3 for ; Thu, 2 Jun 2011 07:38:48 -0700 (PDT) Received: from mail-qy0-f181.google.com (mail-qy0-f181.google.com [209.85.216.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 24CD7431FB6 for ; Thu, 2 Jun 2011 07:38:48 -0700 (PDT) Received: by qyg14 with SMTP id 14so525363qyg.5 for ; Thu, 02 Jun 2011 07:38:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; bh=WGnx4TC0uJY+Q7IhUFou5EPL0Y4Nqgr7SRfsC14aEoc=; b=Gc67lnVLks9xqaI+0qz8/sGuGVg5ESXLUVPY3ES35SAE9bta9ZTX2CYVpXm04OFK5H HRXfjZBIoOdRdzdPp+rGo6W2RKjI8qMf8tuMp4mlX0ORKYHrZaYJuzRhdGm7vmedLe4U S6tqk5JuqKUmt9dVGu7pYYtjFqL/JJ+QK0Pp8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; b=iEanlP7mLxM9AOJjlHr1ibgHbUxyFYBcoCT7eumgIScwXgZlaZVO4t5P+U4ETpFucL G5ts+54Itkpvy6qbll2tO+8ZPWtofwE12mMF+AMyRz3v1qBWD68XuDcx7wiiqpJBUml1 iRD/h8tiHMh4L3nJRTxHJFolv3w8ACMahFIEY= MIME-Version: 1.0 Received: by 10.224.187.9 with SMTP id cu9mr532984qab.381.1307025527091; Thu, 02 Jun 2011 07:38:47 -0700 (PDT) Sender: amdragon@gmail.com Received: by 10.229.188.68 with HTTP; Thu, 2 Jun 2011 07:38:46 -0700 (PDT) In-Reply-To: <87r57cuxgh.fsf@SSpaeth.de> References: <1306588052-sup-9838@brick> <87aae07lxi.fsf@SSpaeth.de> <87r57cuxgh.fsf@SSpaeth.de> Date: Thu, 2 Jun 2011 10:38:46 -0400 X-Google-Sender-Auth: 0ESy2bkvXgnvGVXhVHQ2pab55KI Message-ID: Subject: Re: [python] get all messages of a thread From: Austin Clements To: Sebastian Spaeth Content-Type: text/plain; charset=ISO-8859-1 Cc: notmuch X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Jun 2011 14:38:49 -0000 On Thu, Jun 2, 2011 at 10:20 AM, Sebastian Spaeth wrote: > On Thu, 2 Jun 2011 19:43:29 +1000, Brian May wrote: >> On 2 June 2011 17:05, Sebastian Spaeth 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,