1 Return-Path: <amdragon@gmail.com>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 38EF1431FB6
\r
6 for <notmuch@notmuchmail.org>; Sun, 20 Mar 2011 23:56:09 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.699 tagged_above=-999 required=5
\r
12 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001,
\r
13 RCVD_IN_DNSWL_LOW=-0.7] autolearn=unavailable
\r
14 Received: from olra.theworths.org ([127.0.0.1])
\r
15 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id 3o7rZmVIYAmr for <notmuch@notmuchmail.org>;
\r
17 Sun, 20 Mar 2011 23:56:09 -0700 (PDT)
\r
18 Received: from mail-qy0-f174.google.com (mail-qy0-f174.google.com
\r
19 [209.85.216.174]) (using TLSv1 with cipher RC4-SHA (128/128 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id DB6BE431FB5
\r
22 for <notmuch@notmuchmail.org>; Sun, 20 Mar 2011 23:56:08 -0700 (PDT)
\r
23 Received: by qyk7 with SMTP id 7so2228072qyk.5
\r
24 for <notmuch@notmuchmail.org>; Sun, 20 Mar 2011 23:56:05 -0700 (PDT)
\r
25 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;
\r
26 h=domainkey-signature:mime-version:sender:in-reply-to:references:date
\r
27 :x-google-sender-auth:message-id:subject:from:to:cc:content-type
\r
28 :content-transfer-encoding;
\r
29 bh=7RamGmwwsGCyK+eSUskw6piW/pYhxlgZHTXvR7c/0B0=;
\r
30 b=kdtB0hlyuTRyiBZRuYnN9HaJt4j/4qbYAGfuLJW6SCdGUiQQsroEU7Bc+muKLx1Rbi
\r
31 m4TTydHVihyGcBoqtjMKqrHWhnTRVJGjrM9NuBZil7tl5z16rZ3RTwUuY5RqzK0oARUJ
\r
32 JhBi4laqSVSkD6c9IEjZfgZmDgu2P5rJCX7p8=
\r
33 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;
\r
34 h=mime-version:sender:in-reply-to:references:date
\r
35 :x-google-sender-auth:message-id:subject:from:to:cc:content-type
\r
36 :content-transfer-encoding;
\r
37 b=xJCf3C6pAyEuO+3EWMAM3f+7pmvd9VpgGueGDVXc9nQ4eNmiztVJGhxMMwozfG6igJ
\r
38 k27gtjLJnVqxQVOqE3TtJJfQ+lnNXtiXPEBiAtoMw66jjMbJPxY5cM4vsmNmyOx/NjLu
\r
39 f2urq7ijqrUctbWNA7YMKoUAxOhUwWBiodUrY=
\r
41 Received: by 10.229.102.209 with SMTP id h17mr2945734qco.102.1300690565502;
\r
42 Sun, 20 Mar 2011 23:56:05 -0700 (PDT)
\r
43 Sender: amdragon@gmail.com
\r
44 Received: by 10.229.30.68 with HTTP; Sun, 20 Mar 2011 23:56:05 -0700 (PDT)
\r
45 In-Reply-To: <87hbba8ggp.fsf@yoom.home.cworth.org>
\r
46 References: <1291928396-27937-1-git-send-email-amdragon@mit.edu>
\r
47 <AANLkTiknTgHruLKKYsVo-r9319VHxmuXcw5oxOLPzHQ_@mail.gmail.com>
\r
48 <87hbba8ggp.fsf@yoom.home.cworth.org>
\r
49 Date: Mon, 21 Mar 2011 02:56:05 -0400
\r
50 X-Google-Sender-Auth: GRcovGu3vALGYFkuVRjsY60hFyw
\r
51 Message-ID: <AANLkTi=uZXTacQFiUUk8k5h17NrV1wTo5OR7T=3UguE_@mail.gmail.com>
\r
52 Subject: Re: [PATCH 0/5] Fetch all message metadata in a single pass
\r
53 From: Austin Clements <amdragon@mit.edu>
\r
54 To: Carl Worth <cworth@cworth.org>
\r
55 Content-Type: text/plain; charset=ISO-8859-1
\r
56 Content-Transfer-Encoding: quoted-printable
\r
57 Cc: notmuch@notmuchmail.org
\r
58 X-BeenThere: notmuch@notmuchmail.org
\r
59 X-Mailman-Version: 2.1.13
\r
61 List-Id: "Use and development of the notmuch mail system."
\r
62 <notmuch.notmuchmail.org>
\r
63 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
64 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
65 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
66 List-Post: <mailto:notmuch@notmuchmail.org>
\r
67 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
68 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
69 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
70 X-List-Received-Date: Mon, 21 Mar 2011 06:56:09 -0000
\r
72 Thanks for the thorough review. My updated patches are on the
\r
73 eager-metadata-v4 branch (also, for-review/eager-metadata-v4) at
\r
74 http://awakening.csail.mit.edu/git/notmuch.git
\r
77 On Thu, Mar 10, 2011 at 10:48 PM, Carl Worth <cworth@cworth.org> wrote:
\r
78 > On Sun, 13 Feb 2011 15:25:48 -0500, Austin Clements <amdragon@mit.edu> wr=
\r
80 >> I've rebased this against current master and fixed a few merge
\r
81 >> conflicts. =A0The rebased patches are on the eager-metadata-v3 branch of
\r
82 >> =A0 http://awakening.csail.mit.edu/git/notmuch.git
\r
86 > This looks like a great set of optimizations and cleanup. Here is some
\r
87 > (long-overdue) review.
\r
89 > First, the patch series looks excellent and my review here is quite
\r
90 > nit-picky. I feel bad reviewing this so late and not just immediately
\r
91 > merging it, but I will commit to picking up a refreshed series very
\r
94 > One very minor thing is that the word "metadata" might be confused with
\r
95 > Xapian metadata which we are using already such as:
\r
97 > =A0 =A0version_string =3D notmuch->xapian_db->get_metadata ("version");
\r
99 > So we might want to come up with a better name here. I don't have any
\r
100 > concrete suggestion yet, so if you don't think of anything obvious, then
\r
101 > don't worry about it.
\r
103 Hmm. I think this is okay because I always refer to "message
\r
104 metadata" (and I couldn't think of a better term).
\r
106 >> + =A0 =A0/* Get tags */
\r
107 >> + =A0 =A0if (!message->tag_list) {
\r
108 >> + =A0 =A0 message->tag_list =3D
\r
109 >> + =A0 =A0 =A0 =A0 _notmuch_get_terms_with_prefix (message, i, end, tag_p=
\r
111 >> + =A0 =A0 _notmuch_string_list_sort (message->tag_list);
\r
114 > Looks like the above case is missing the assert to ensure proper prefix
\r
119 >> + =A0 =A0if (!message->tag_list)
\r
120 >> + =A0 =A0 _notmuch_message_ensure_metadata (message);
\r
122 >> + =A0 =A0/* We tell the iterator to add a talloc reference to the
\r
123 >> + =A0 =A0 * underlying list, rather than stealing it. =A0As a result, it=
\r
125 >> + =A0 =A0 * possible to modify the message tags while iterating because
\r
126 >> + =A0 =A0 * the iterator will keep the current list alive. */
\r
127 >> + =A0 =A0return _notmuch_tags_create (message, message->tag_list, FALSE)=
\r
130 > The behavior here is great, but don't like Boolean function parameters
\r
131 > being used to change the semantics. The problem with a Boolean argument
\r
132 > is that it's impossible to know the semantic by just reading the calling
\r
133 > code---you must also consult the implementation as well.
\r
135 > For any case where it seems natural to implement something with a
\r
136 > Boolean argument, I sometimes use an approach something like this:
\r
138 > =A0 =A0 =A0 =A0static void
\r
139 > =A0 =A0 =A0 =A0_foo_function_internal (foo_t *, ..., bool_t be_different)
\r
141 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0...;
\r
144 > =A0 =A0 =A0 =A0void
\r
145 > =A0 =A0 =A0 =A0foo_function (foo_t *, ...)
\r
147 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return _foo_function_internal (foo, ..., F=
\r
151 > =A0 =A0 =A0 =A0void
\r
152 > =A0 =A0 =A0 =A0foo_function_different (foo_t *, ...)
\r
154 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return _foo_function_internal (foo, ..., T=
\r
158 > That is, I'm willing to accept the Boolean parameter in the case of a
\r
159 > static function defined immediately next to all callers. Here, for any
\r
160 > non-static callers the semantics should be quite clear. (And perhaps the
\r
161 > function calling with the FALSE case will need a clarifying suffix as
\r
162 > well---one might have some_function_foo and some_function_bar for the
\r
165 > Of course, my proscription against Boolean parameter doesn't apply to
\r
166 > something like a function that is setting some Boolean feature to TRUE
\r
167 > or FALSE. The important criterion is that the function semantics should
\r
168 > be evident to someone reading code calling the function. So if the
\r
169 > Boolean argument is obviously tied to some portion of the function name,
\r
170 > then that can be adequate.
\r
172 > Enough with the generalities, back to _notmuch_tags_create...
\r
174 > The caller above is the exceptional caller. It's the only one using
\r
175 > passing FALSE, and it also already has a large comment. So it seems that
\r
176 > the right fix here is to have the extra talloc_reference happen here
\r
177 > where there's a comment talking about adding a talloc reference.
\r
179 > So it would be great to see something here like:
\r
181 > =A0 =A0 =A0 =A0tags =3D _notmuch_tags_create (message, message->tag_list)=
\r
183 > =A0 =A0 =A0 =A0talloc_reference (message, message->tag_list);
\r
184 > =A0 =A0 =A0 =A0return tags;
\r
186 > Of course, that would mean that _notmuch_tags_create can't have done the
\r
187 > talloc_steal. So perhaps all the other callers should be calling:
\r
189 > =A0 =A0 =A0 =A0_notmuch_tags_create_with_steal (ctx, tag_list);
\r
191 > What do you think?
\r
193 Your point about the boolean argument is well taken. In this case
\r
194 there's really no need for two difference versions, so I wound up
\r
195 making _notmuch_tags_create always steal the reference.
\r
197 I debated for a while whether it should add a reference, thus forcing
\r
198 most callers to talloc_unlink, or steal the reference, thus forcing
\r
199 one caller to talloc_reference. I ultimately decided it was much more
\r
200 likely that the caller would forget the talloc_unlink, resulting in a
\r
201 difficult-to-track memory leak (since the list would *eventually* be
\r
202 cleaned up), than that the steal would cause confusion. Also, there
\r
203 is some precedence for internal functions that steal an argument. So
\r
204 I made it steal the reference.
\r
206 This doesn't cause any problems in the one weird case that still needs
\r
207 the reference to the list. After the _notmuch_tags_create, the caller
\r
208 simply adds that reference.
\r
210 >> -notmuch_tags_t *
\r
211 >> -_notmuch_convert_tags (void *ctx, Xapian::TermIterator &i,
\r
212 >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Xapian::TermIterator &end);
\r
213 >> +notmuch_string_list_t *
\r
214 >> +_notmuch_get_terms_with_prefix (void *ctx, Xapian::TermIterator &i,
\r
215 >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Xapian::TermIt=
\r
217 >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *pr=
\r
220 > I don't really like the fact that _notmuch_get_terms_with_prefix doesn't
\r
221 > make a clear indication of what file it's defined in, (the old function
\r
222 > _notmuch_convert_tags had the same problem). It could be named
\r
223 > _notmuch_database_convert_tags since it's in database.cc, but that would
\r
224 > be odd in not actually accepting a notmuch_database_t * as the first
\r
225 > parameter. Any suggestion here?
\r
227 _notmuch_get_terms_with_prefix is weird because it captures a pattern
\r
228 that lies squarely in the Xapian world, being all about term
\r
229 iterators. Hence, I think the "right" solution (note, not the best
\r
230 solution), would be to hide the term iterators and make two copies of
\r
231 the function: one that takes a notmuch_database_t and always considers
\r
232 all database terms, and one private to message.cc that acts as a
\r
233 helper to what's now all bundled in _notmuch_message_ensure_metadata.
\r
235 But that bothers me more than a function that doesn't take a
\r
236 notmuch_database_t *. So I just added "database" to the name.
\r
238 >> index 0000000..d92a0ba
\r
240 >> +++ b/lib/strings.c
\r
241 >> @@ -0,0 +1,94 @@
\r
242 >> +/* strings.c - Iterator for a list of strings
\r
244 > Similarly, this file might be better as string-list.c.
\r
248 >> + * You should have received a copy of the GNU General Public License
\r
249 >> + * along with this program. =A0If not, see http://www.gnu.org/licenses/=
\r
252 >> + * Author: Carl Worth <cworth@cworth.org>
\r
254 > Hey, wait a second, some of this code is mine, but I think the sort
\r
255 > function is yours. Please do start annotating the Author tags on all
\r
256 > files as appropriate. (There are probably lots of files missing your
\r
257 > Author attribution---I just happened to notice this one here since you
\r
258 > happened to have an Author line in the patch.)
\r
260 Heh, fixed. I suppose I hadn't been thinking about it, since none of
\r
261 the source in lib/ has other authors listed.
\r
263 But it raises an interesting question. When is it kosher to add
\r
264 oneself to a file's author list? In this case I wrote about half of
\r
265 the code in that admittedly short file, so that makes sense Changing
\r
266 a few lines presumably isn't enough. Adding a few functions?
\r
268 >> -/* XXX: Should write some talloc-friendly list to avoid the need for
\r
271 > Hurrah! I love patches that get to remove XXX comments.
\r
275 >> + =A0 =A0/* Get thread */
\r
276 >> + =A0 =A0if (!message->thread_id)
\r
277 >> + =A0 =A0 message->thread_id =3D
\r
278 >> + =A0 =A0 =A0 =A0 _notmuch_message_get_term (message, i, end, thread_pre=
\r
281 >> + =A0 =A0/* Get id */
\r
282 >> + =A0 =A0assert (strcmp (thread_prefix, id_prefix) < 0);
\r
283 >> + =A0 =A0if (!message->message_id)
\r
284 >> + =A0 =A0 message->message_id =3D
\r
285 >> + =A0 =A0 =A0 =A0 _notmuch_message_get_term (message, i, end, id_prefix)=
\r
288 > Missing asserts on the above two as well?
\r
290 Fixed. (Actually, I think there was only one assert missing in total,
\r
291 but it had propagated through the history.)
\r