[PATCH 3/3] NEWS: Insert markdown formatting commands
[notmuch-archives.git] / 2f / 062ccea49480ba30281b6ea64f0e570da294da
1 Return-Path: <jani@nikula.org>\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 B73B7431FD0\r
6         for <notmuch@notmuchmail.org>; Wed,  9 Nov 2011 00:46:10 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \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 A-XrQYTBeypi for <notmuch@notmuchmail.org>;\r
16         Wed,  9 Nov 2011 00:46:08 -0800 (PST)\r
17 Received: from mail-vx0-f181.google.com (mail-vx0-f181.google.com\r
18         [209.85.220.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
19         (No client certificate requested)\r
20         by olra.theworths.org (Postfix) with ESMTPS id 7F388431FB6\r
21         for <notmuch@notmuchmail.org>; Wed,  9 Nov 2011 00:46:08 -0800 (PST)\r
22 Received: by vcbfk26 with SMTP id fk26so1473768vcb.26\r
23         for <notmuch@notmuchmail.org>; Wed, 09 Nov 2011 00:46:06 -0800 (PST)\r
24 Received: by 10.52.26.9 with SMTP id h9mr2658719vdg.99.1320828366706;\r
25         Wed, 09 Nov 2011 00:46:06 -0800 (PST)\r
26 Received: from localhost (nikula.org. [92.243.24.172])\r
27         by mx.google.com with ESMTPS id bl9sm6412627vdb.15.2011.11.09.00.46.03\r
28         (version=SSLv3 cipher=OTHER); Wed, 09 Nov 2011 00:46:04 -0800 (PST)\r
29 From: Jani Nikula <jani@nikula.org>\r
30 To: Austin Clements <amdragon@MIT.EDU>, notmuch@notmuchmail.org\r
31 Subject: Re: [PATCH] tag: Automatically limit to messages whose tags will\r
32         actually change.\r
33 In-Reply-To: <1320724523-23568-1-git-send-email-amdragon@mit.edu>\r
34 References: <1320724523-23568-1-git-send-email-amdragon@mit.edu>\r
35 User-Agent: Notmuch/0.5-232-g917e874 (http://notmuchmail.org) Emacs/23.1.1\r
36         (i686-pc-linux-gnu)\r
37 Date: Wed, 09 Nov 2011 08:46:02 +0000\r
38 Message-ID: <87ty6d1y5x.fsf@nikula.org>\r
39 MIME-Version: 1.0\r
40 Content-Type: text/plain; charset=us-ascii\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Wed, 09 Nov 2011 08:46:10 -0000\r
54 \r
55 \r
56 FWIW, I reviewed this and didn't find any obvious problems. A few\r
57 nitpicks below, though.\r
58 \r
59 BR,\r
60 Jani.\r
61 \r
62 On Mon,  7 Nov 2011 22:55:23 -0500, Austin Clements <amdragon@MIT.EDU> wrote:\r
63 > This optimizes the user's tagging query to exclude messages that won't\r
64 > be affected by the tagging operation, saving computation and IO for\r
65 > redundant tagging operations.\r
66\r
67 > For example,\r
68 >   notmuch tag +notmuch to:notmuch@notmuchmail.org\r
69 > will now use the query\r
70 >   ( to:notmuch@notmuchmail.org ) and (not tag:"notmuch")\r
71\r
72 > In the past, we've often suggested that people do this exact\r
73 > transformation by hand for slow tagging operations.  This makes that\r
74 > unnecessary.\r
75 > ---\r
76 > I was about to implement this optimization in my initial tagging\r
77 > script, but then I figured, why not just do it in notmuch so we can\r
78 > stop telling people to do this by hand?\r
79\r
80 >  NEWS          |    9 ++++++\r
81 >  notmuch-tag.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
82 >  2 files changed, 85 insertions(+), 0 deletions(-)\r
83\r
84 > diff --git a/NEWS b/NEWS\r
85 > index e00452a..9ca5e0c 100644\r
86 > --- a/NEWS\r
87 > +++ b/NEWS\r
88 > @@ -16,6 +16,15 @@ Add search terms to  "notmuch dump"\r
89 >    search/show/tag. The output file argument of dump is deprecated in\r
90 >    favour of using stdout.\r
91 >  \r
92 > +Optimizations\r
93 > +-------------\r
94 > +\r
95 > +Automatic tag query optimization\r
96 > +\r
97 > +  "notmuch tag" now automatically optimizes the user's query to\r
98 > +  exclude messages whose tags won't change.  In the past, we've\r
99 > +  suggested that people do this by hand; this is no longer necessary.\r
100 > +\r
101 >  Notmuch 0.9 (2011-10-01)\r
102 >  ========================\r
103 >  \r
104 > diff --git a/notmuch-tag.c b/notmuch-tag.c\r
105 > index dded39e..62c4bf1 100644\r
106 > --- a/notmuch-tag.c\r
107 > +++ b/notmuch-tag.c\r
108 > @@ -30,6 +30,76 @@ handle_sigint (unused (int sig))\r
109 >      interrupted = 1;\r
110 >  }\r
111 >  \r
112 > +static char *\r
113 > +_escape_tag (char *buf, const char *tag)\r
114 > +{\r
115 > +    const char *in = tag;\r
116 > +    char *out = buf;\r
117 > +    /* Boolean terms surrounded by double quotes can contain any\r
118 > +     * character.  Double quotes are quoted by doubling them. */\r
119 > +    *(out++) = '"';\r
120 > +    while (*in) {\r
121 > +     if (*in == '"')\r
122 > +         *(out++) = '"';\r
123 > +     *(out++) = *(in++);\r
124 > +    }\r
125 > +    *(out++) = '"';\r
126 \r
127 The parenthesis are unnecessary for *p++.\r
128 \r
129 > +    *out = 0;\r
130 > +    return buf;\r
131 > +}\r
132 > +\r
133 > +static char *\r
134 > +_optimize_tag_query (void *ctx, const char *orig_query_string, char *argv[],\r
135 > +                  int *add_tags, int add_tags_count,\r
136 > +                  int *remove_tags, int remove_tags_count)\r
137 > +{\r
138 > +    /* This is subtler than it looks.  Xapian ignores the '-' operator\r
139 > +     * at the beginning both queries and parenthesized groups and,\r
140 > +     * furthermore, the presence of a '-' operator at the beginning of\r
141 > +     * a group can inhibit parsing of the previous operator.  Hence,\r
142 > +     * the user-provided query MUST appear first, but it is safe to\r
143 > +     * parenthesize and the exclusion part of the query must not use\r
144 > +     * the '-' operator (though the NOT operator is fine). */\r
145 > +\r
146 > +    char *escaped, *query_string;\r
147 > +    const char *join = "";\r
148 > +    int i;\r
149 > +    unsigned int max_tag_len = 0;\r
150 > +\r
151 > +    /* Allocate a buffer for escaping tags. */\r
152 > +    for (i = 0; i < add_tags_count; i++)\r
153 > +     if (strlen (argv[add_tags[i]] + 1) > max_tag_len)\r
154 > +         max_tag_len = strlen (argv[add_tags[i]] + 1);\r
155 > +    for (i = 0; i < remove_tags_count; i++)\r
156 > +     if (strlen (argv[remove_tags[i]] + 1) > max_tag_len)\r
157 > +         max_tag_len = strlen (argv[remove_tags[i]] + 1);\r
158 > +    escaped = talloc_array(ctx, char, max_tag_len * 2 + 3);\r
159 \r
160 Perhaps a comment here or above _escape_tag() explaining the worst case\r
161 memory consumption of strlen(tag) * 2 + 3 for a tag of "s would be in\r
162 order.\r
163 \r
164 It's unrelated, but looking at the above also made me check something\r
165 I've suspected before: notmuch allows you to have empty or zero length\r
166 tags "", which is probably not intentional.\r
167 \r
168 There's no check for talloc failures here or below. But then there are\r
169 few checks for that in the cli in general. *shrug*.\r
170 \r
171 > +\r
172 > +    /* Build the new query string */\r
173 > +    if (strcmp (orig_query_string, "*") == 0)\r
174 > +     query_string = talloc_strdup (ctx, "(");\r
175 > +    else\r
176 > +     query_string = talloc_asprintf (ctx, "( %s ) and (", orig_query_string);\r
177 > +\r
178 > +    for (i = 0; i < add_tags_count; i++) {\r
179 > +     query_string = talloc_asprintf_append_buffer (\r
180 > +         query_string, "%snot tag:%s", join,\r
181 > +         _escape_tag (escaped, argv[add_tags[i]] + 1));\r
182 > +     join = " or ";\r
183 > +    }\r
184 > +    for (i = 0; i < remove_tags_count; i++) {\r
185 > +     query_string = talloc_asprintf_append_buffer (\r
186 > +         query_string, "%stag:%s", join,\r
187 > +         _escape_tag (escaped, argv[remove_tags[i]] + 1));\r
188 > +     join = " or ";\r
189 > +    }\r
190 > +\r
191 > +    query_string = talloc_strdup_append_buffer (query_string, ")");\r
192 > +\r
193 > +    talloc_free (escaped);\r
194 > +    return query_string;\r
195 > +}\r
196 > +\r
197 >  int\r
198 >  notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))\r
199 >  {\r
200 > @@ -93,6 +163,12 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))\r
201 >       return 1;\r
202 >      }\r
203 >  \r
204 > +    /* Optimize the query so it excludes messages that already have\r
205 > +     * the specified set of tags. */\r
206 > +    query_string = _optimize_tag_query (ctx, query_string, argv,\r
207 > +                                     add_tags, add_tags_count,\r
208 > +                                     remove_tags, remove_tags_count);\r
209 > +\r
210 >      config = notmuch_config_open (ctx, NULL, NULL);\r
211 >      if (config == NULL)\r
212 >       return 1;\r
213 > -- \r
214 > 1.7.7.1\r
215\r
216 > _______________________________________________\r
217 > notmuch mailing list\r
218 > notmuch@notmuchmail.org\r
219 > http://notmuchmail.org/mailman/listinfo/notmuch\r