1 Return-Path: <amdragon@mit.edu>
\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 2C28A431FD0
\r
6 for <notmuch@notmuchmail.org>; Sun, 3 Jul 2011 10:17:58 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id bwy0xnHscZbu for <notmuch@notmuchmail.org>;
\r
16 Sun, 3 Jul 2011 10:17:56 -0700 (PDT)
\r
17 Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU
\r
19 by olra.theworths.org (Postfix) with ESMTP id F0BCF431FB6
\r
20 for <notmuch@notmuchmail.org>; Sun, 3 Jul 2011 10:17:55 -0700 (PDT)
\r
21 X-AuditID: 1209190f-b7c82ae000000a20-4f-4e10a448440e
\r
22 Received: from mailhub-auth-2.mit.edu ( [18.7.62.36])
\r
23 by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP
\r
24 id C7.34.02592.844A01E4; Sun, 3 Jul 2011 13:18:00 -0400 (EDT)
\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])
\r
26 by mailhub-auth-2.mit.edu (8.13.8/8.9.2) with ESMTP id p63HHsIx021268;
\r
27 Sun, 3 Jul 2011 13:17:55 -0400
\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])
\r
29 (authenticated bits=0)
\r
30 (User authenticated as amdragon@ATHENA.MIT.EDU)
\r
31 by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id p63HHrnC027795
\r
32 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);
\r
33 Sun, 3 Jul 2011 13:17:54 -0400 (EDT)
\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.72)
\r
35 (envelope-from <amdragon@mit.edu>)
\r
36 id 1QdQIh-0001AG-Mb; Sun, 03 Jul 2011 13:17:43 -0400
\r
37 Date: Sun, 3 Jul 2011 13:17:43 -0400
\r
38 From: Austin Clements <amdragon@MIT.EDU>
\r
39 To: Pieter Praet <pieter@praet.org>
\r
40 Subject: Re: [PATCH 2/2] [RFC] possible solution for "Race condition for
\r
42 Message-ID: <20110703171743.GL15901@mit.edu>
\r
44 <CAH-f9WticM4EN8F1_ik_-mcBcBtrXwSpO+Drbtp7=UN7McECrg@mail.gmail.com>
\r
45 <87zkkwydag.fsf@praet.org>
\r
47 Content-Type: text/plain; charset=us-ascii
\r
48 Content-Disposition: inline
\r
49 In-Reply-To: <87zkkwydag.fsf@praet.org>
\r
50 User-Agent: Mutt/1.5.20 (2009-06-14)
\r
51 X-Brightmail-Tracker:
\r
52 H4sIAAAAAAAAA+NgFprAKsWRmVeSWpSXmKPExsUixG6nouuxRMDPYM1VaYvrN2cyW/x+fYPZ
\r
53 gcnj2apbzB4d+y6zBjBFcdmkpOZklqUW6dslcGXsO7uBpeCKccXMdUuZGxjXa3QxcnJICJhI
\r
54 PP6/nRHCFpO4cG89WxcjF4eQwD5Gidm/JjJBOOsZJX7PbIByTjBJTOv6BuUsAcqsbGYF6WcR
\r
55 UJF4ev0fG4jNJqAhsW3/crC5IgLKEqef/GQHsZkFpCW+/W5mArGFBcIlpn54BlbPK6Aj8erV
\r
56 HrB6IYFciecf/rBDxAUlTs58wgLRqyVx499LoF4OsDnL/3GAhDkF1CWWf9oHVi4KdMK1/e1s
\r
57 ExiFZiHpnoWkexZC9wJG5lWMsim5Vbq5iZk5xanJusXJiXl5qUW6Jnq5mSV6qSmlmxhBgc0p
\r
58 yb+D8dtBpUOMAhyMSjy8DJME/IRYE8uKK3MPMUpyMCmJ8qotBgrxJeWnVGYkFmfEF5XmpBYf
\r
59 YpTgYFYS4T1QBZTjTUmsrEotyodJSXOwKInzlnv/9xUSSE8sSc1OTS1ILYLJynBwKEnw5oIM
\r
60 FSxKTU+tSMvMKUFIM3FwggznARq+AKSGt7ggMbc4Mx0if4pRl2PN2keHGYVY8vLzUqXEeZtA
\r
61 igRAijJK8+DmwBLSK0ZxoLeEeWeBVPEAkxncpFdAS5iAlmTm84IsKUlESEk1MC52aDlooHEl
\r
62 qKlW2bLy00W12DPypiUVzrd2iPr9O3BrdfPNJ6tj59T/KxZeWmX1wu7/pFiGre45Wyb8uSCg
\r
63 Yemd8+uL9eKSTRek7yxvPzDfxeDVfMvpVQeYzn3LvGaz8vLR2ckpP5bNvXxEOi8+u8/RLLPw
\r
64 xqa1u9a35Z/kT9G89DzRY7ols6MSS3FGoqEWc1FxIgBs/DhsIwMAAA==
\r
65 Cc: notmuch@notmuchmail.org
\r
66 X-BeenThere: notmuch@notmuchmail.org
\r
67 X-Mailman-Version: 2.1.13
\r
69 List-Id: "Use and development of the notmuch mail system."
\r
70 <notmuch.notmuchmail.org>
\r
71 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
72 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
73 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
74 List-Post: <mailto:notmuch@notmuchmail.org>
\r
75 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
76 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
77 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
78 X-List-Received-Date: Sun, 03 Jul 2011 17:17:58 -0000
\r
80 Quoth Pieter Praet on Jul 02 at 4:20 pm:
\r
81 > On Fri, 1 Jul 2011 12:37:11 -0400, Austin Clements <amdragon@mit.edu> wrote:
\r
82 > Non-text part: multipart/alternative
\r
83 > > On Jul 1, 2011 10:55 AM, "Austin Clements" <amdragon@mit.edu> wrote:
\r
85 > > > On Thu, Jun 30, 2011 at 3:38 PM, Pieter Praet <pieter@praet.org> wrote:
\r
86 > > > > Ok, even though my very first reply [1] may have created the impression
\r
87 > > > > that I understood the issue, I clearly didn't...
\r
89 > > > > The test [2] needs a more applicable commit message, and the subsequent
\r
90 > > > > patch [3] points more or less in the right direction, but the Message-Id
\r
91 > > > > list should be local to the *search buffer* rather than to the
\r
92 > > > > `notmuch-search-operate-all' function.
\r
94 > > > > `notmuch-search' could:
\r
95 > > > > - run "notmuch-command search" with the "--output=messages" option
\r
96 > > > > instead of a plain search,
\r
97 > > > > - maintain a buffer-local var with a list of returned Message-Id's,
\r
98 > > > > - ...and populate the buffer based on that list.
\r
100 > > > > As such we'd have -for each individual search buffer- a canonical list
\r
101 > > > > of Message-Id's (i.e. messages which actually *match* the query AND are
\r
102 > > > > currently visible in the search buffer), to be used by
\r
103 > > > > `notmuch-search-operate-all' et al.
\r
109 > > > > [1] id:"87fwmuxxgd.fsf@praet.org"
\r
110 > > > > [2] id:"1309450108-2793-2-git-send-email-pieter@praet.org"
\r
111 > > > > [3] id:"1309450108-2793-1-git-send-email-pieter@praet.org"
\r
113 > > > Ideally, this wouldn't be per-buffer, but per *line*. This race
\r
114 > > > equally affects adding and removing tags from individual results,
\r
115 > > > since that's done using a thread: query, whose results could have
\r
116 > > > changed since the original search.
\r
118 > > > This almost certainly requires support from the notmuch core. The
\r
119 > > > good news is that the library already provides this information, so
\r
120 > > > there will be virtually no performance hit for outputting it.
\r
122 > > Actually, with a smidgeon of library support, you could even use document
\r
123 > > IDs for this, rather than message IDs, which would make the tagging
\r
124 > > operations (even '*') no more expensive than they are now. (Of course, it
\r
125 > > would be good to know just how much overhead going through message IDs
\r
126 > > actually introduces.)
\r
127 > Non-text part: text/html
\r
130 > That would be awesome!
\r
132 > Though I'd rather leave the plumbing to someone sufficiently capable,
\r
133 > so, if leaving libnotmuch hacking out of the equation, how would one go
\r
134 > about doing this?
\r
136 > I (ignorantly) assume we'd get `notmuch-search-process-filter'
\r
137 > to append each line with an invisible field containing a list
\r
138 > of matching Message-Id's, presumably obtained via
\r
139 > `notmuch_thread_get_matched_messages' (@ lib/thread.cc) ?
\r
141 Here's a super-hacky patch that adds an "id:x or id:y or ..." query
\r
142 string to the end of each search line, right after the list of tags.
\r
143 This is just the C side; care to prototype the elisp side?
\r
145 I also added a --stdin argument to notmuch tag that'll read the query
\r
146 string from stdin, since these queries could get very long (though
\r
147 ARG_MAX appears to be 2 megs these days, so maybe this wasn't
\r
148 necessary for prototyping).
\r
150 diff --git a/notmuch-search.c b/notmuch-search.c
\r
151 index faccaf7..65fe438 100644
\r
152 --- a/notmuch-search.c
\r
153 +++ b/notmuch-search.c
\r
154 @@ -190,6 +190,23 @@ format_thread_json (const void *ctx,
\r
155 talloc_free (ctx_quote);
\r
159 +show_message_ids (notmuch_messages_t *messages, notmuch_bool_t first)
\r
161 + notmuch_message_t *message;
\r
164 + notmuch_messages_valid (messages);
\r
165 + notmuch_messages_move_to_next (messages)) {
\r
167 + fputs (" or ", stdout);
\r
169 + message = notmuch_messages_get (messages);
\r
170 + printf ("id:\"%s\"", notmuch_message_get_message_id (message));
\r
171 + show_message_ids (notmuch_message_get_replies (message), FALSE);
\r
176 do_search_threads (const search_format_t *format,
\r
177 notmuch_query_t *query,
\r
178 @@ -252,6 +269,12 @@ do_search_threads (const search_format_t *format,
\r
180 fputs (format->tag_end, stdout);
\r
182 + if (format == &format_text) {
\r
183 + notmuch_messages_t *toplevel = notmuch_thread_get_toplevel_messages (thread);
\r
184 + fputs (" ", stdout);
\r
185 + show_message_ids (toplevel, TRUE);
\r
188 fputs (format->item_end, stdout);
\r
191 diff --git a/notmuch-tag.c b/notmuch-tag.c
\r
192 index 6204ae3..5609d02 100644
\r
193 --- a/notmuch-tag.c
\r
194 +++ b/notmuch-tag.c
\r
195 @@ -30,6 +30,36 @@ handle_sigint (unused (int sig))
\r
200 +query_string_from_stdin (void *ctx)
\r
202 + char *query_string = talloc_strdup (ctx, "");
\r
205 + if (query_string == NULL) {
\r
206 + fprintf (stderr, "Out of memory.\n");
\r
211 + ssize_t r = read(0, buf, sizeof (buf));
\r
213 + fprintf (stderr, "Error reading from stdin: %s\n",
\r
214 + strerror (errno));
\r
216 + } else if (r == 0) {
\r
219 + query_string = talloc_strndup_append (query_string, buf, r);
\r
220 + if (!query_string) {
\r
221 + fprintf (stderr, "Out of memory.\n");
\r
226 + return query_string;
\r
230 notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
\r
232 @@ -44,6 +74,7 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
\r
233 notmuch_message_t *message;
\r
234 struct sigaction action;
\r
235 notmuch_bool_t synchronize_flags;
\r
236 + notmuch_bool_t use_stdin = FALSE;
\r
239 /* Setup our handler for SIGINT */
\r
240 @@ -70,7 +101,9 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
\r
244 - if (argv[i][0] == '+') {
\r
245 + if (STRNCMP_LITERAL (argv[i], "--stdin") == 0) {
\r
246 + use_stdin = TRUE;
\r
247 + } else if (argv[i][0] == '+') {
\r
248 add_tags[add_tags_count++] = i;
\r
249 } else if (argv[i][0] == '-') {
\r
250 remove_tags[remove_tags_count++] = i;
\r
251 @@ -84,7 +117,13 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
\r
255 - query_string = query_string_from_args (ctx, argc - i, &argv[i]);
\r
257 + query_string = query_string_from_stdin (ctx);
\r
259 + query_string = query_string_from_args (ctx, argc - i, &argv[i]);
\r
261 + if (!query_string)
\r
264 if (*query_string == '\0') {
\r
265 fprintf (stderr, "Error: notmuch tag requires at least one search term.\n");
\r