unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 0/5] notmuch batch count
@ 2013-01-15 21:54 Jani Nikula
  2013-01-15 21:54 ` [PATCH 1/5] cli: remove useless strdup Jani Nikula
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

Hi all -

Notmuch remote usage [1] is a pretty handy way of accessing a notmuch
database on a remote server. However, the more you have saved searches
and tags, the slower notmuch-hello becomes, and it ends up being by and
far the biggest usability issue with remote notmuch. This is because
notmuch-hello issues a separate 'notmuch count' for each saved search
and tag.

One could argue that notmuch-hello should be fixed somehow, but I chose
to try another route: batch support for notmuch count. This enables
notmuch-hello to get the counts for all the saved searches or tags in a
single call. The performance improvement is huge in remote usage, but
it's not limited to that. Regular local usage benefits from it too, but
it's not as obviously noticeable.

Here's a script that demonstrates one-by-one count vs. batch count,
locally and over ssh (assuming ssh key authentication is set up), over
10 iterations:

#!/bin/bash

echo "tag count:"
notmuch search --output=tags "*" | wc -l

for remote in "" "ssh example.com"; do
    export remote
    echo "one-by-one count:"
    time sh -c 'for i in `seq 10`; do notmuch search --format=text0 --output=tags "*" | xargs -0 -n 1 -I "{}" $remote notmuch count tag:"{}" > /dev/null; done'

    echo "batch count:"
    time sh -c 'for i in `seq 10`; do notmuch search --format=text --output=tags "*" | sed "s/.*/tag:\"\0\"/" | $remote notmuch count --batch > /dev/null; done'
done

And here's the output of it in my setup:

tag count:
36
one-by-one count:

real	0m2.349s
user	0m0.552s
sys	0m0.868s
batch count:

real	0m0.179s
user	0m0.120s
sys	0m0.064s
one-by-one count:

real	0m56.527s
user	0m1.424s
sys	0m1.164s
batch count:

real	0m2.407s
user	0m0.068s
sys	0m0.040s

As can be seen, in local usage (the first pair of results) the speedup
is more than 10x, although one-by-one notmuch count is usually
sufficiently fast. The difference is more noticeable in remote use (the
second pair of results), where the speedup is 20x here, and any
additional, occasional network latency is multiplied by tag count. (That
result is actually faster than usual for me, but it's still 5+ seconds
to display or refresh notmuch-hello.)

Mark has written a patch that I've been using to switch notmuch-hello to
use batch count. That has made me switch from running notmuch in ssh to
using remote notmuch. The great thing is that we could switch to using
that in Emacs with no special casing for remote usage, and it would
speed things up also in local use. I'm expecting Mark to post his patch
in reply to this series.

Mark actually wrote the elisp part based on the rough idea prior to any
of this cli plumbing, so I felt obliged to follow up. So thanks Mark!


BR,
Jani.


[1] http://notmuchmail.org/remoteusage/ (the page could use some
cleanup; it's really not nearly as complicated as the page suggests)


Jani Nikula (5):
  cli: remove useless strdup
  cli: extract count printing to a separate function in notmuch count
  cli: add --batch option to notmuch count
  man: document notmuch count --batch and --input options
  test: notmuch count --batch and --input options

 man/man1/notmuch-count.1 |   20 +++++++++
 notmuch-count.c          |  111 +++++++++++++++++++++++++++++++++++-----------
 test/count               |   46 +++++++++++++++++++
 3 files changed, 150 insertions(+), 27 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/5] cli: remove useless strdup
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
@ 2013-01-15 21:54 ` Jani Nikula
  2013-01-15 21:54 ` [PATCH 2/5] cli: extract count printing to a separate function in notmuch count Jani Nikula
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

---
 notmuch-count.c |    4 ----
 1 file changed, 4 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 2f98128..6a9fae3 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -76,10 +76,6 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    if (*query_str == '\0') {
-	query_str = talloc_strdup (ctx, "");
-    }
-
     query = notmuch_query_create (notmuch, query_str);
     if (query == NULL) {
 	fprintf (stderr, "Out of memory\n");
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/5] cli: extract count printing to a separate function in notmuch count
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
  2013-01-15 21:54 ` [PATCH 1/5] cli: remove useless strdup Jani Nikula
@ 2013-01-15 21:54 ` Jani Nikula
  2013-01-15 21:54 ` [PATCH 3/5] cli: add --batch option to " Jani Nikula
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

Make count printing on a query string reusable. No functional changes.
---
 notmuch-count.c |   59 +++++++++++++++++++++++++++++++++----------------------
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 6a9fae3..0e14b48 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -32,17 +32,48 @@ enum {
     EXCLUDE_FALSE,
 };
 
+static int
+print_count (notmuch_database_t *notmuch, const char *query_str,
+	     const char **exclude_tags, size_t exclude_tags_length, int output)
+{
+    notmuch_query_t *query;
+    size_t i;
+
+    query = notmuch_query_create (notmuch, query_str);
+    if (query == NULL) {
+	fprintf (stderr, "Out of memory\n");
+	return 1;
+    }
+
+    for (i = 0; i < exclude_tags_length; i++)
+	notmuch_query_add_tag_exclude (query, exclude_tags[i]);
+
+    switch (output) {
+    case OUTPUT_MESSAGES:
+	printf ("%u\n", notmuch_query_count_messages (query));
+	break;
+    case OUTPUT_THREADS:
+	printf ("%u\n", notmuch_query_count_threads (query));
+	break;
+    }
+
+    notmuch_query_destroy (query);
+
+    return 0;
+}
+
 int
 notmuch_count_command (void *ctx, int argc, char *argv[])
 {
     notmuch_config_t *config;
     notmuch_database_t *notmuch;
-    notmuch_query_t *query;
     char *query_str;
     int opt_index;
     int output = OUTPUT_MESSAGES;
     int exclude = EXCLUDE_TRUE;
-    unsigned int i;
+    const char **search_exclude_tags = NULL;
+    size_t search_exclude_tags_length = 0;
+    int ret;
 
     notmuch_opt_desc_t options[] = {
 	{ NOTMUCH_OPT_KEYWORD, &output, "output", 'o',
@@ -76,33 +107,15 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
-    query = notmuch_query_create (notmuch, query_str);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory\n");
-	return 1;
-    }
-
     if (exclude == EXCLUDE_TRUE) {
-	const char **search_exclude_tags;
-	size_t search_exclude_tags_length;
-
 	search_exclude_tags = notmuch_config_get_search_exclude_tags
 	    (config, &search_exclude_tags_length);
-	for (i = 0; i < search_exclude_tags_length; i++)
-	    notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
     }
 
-    switch (output) {
-    case OUTPUT_MESSAGES:
-	printf ("%u\n", notmuch_query_count_messages (query));
-	break;
-    case OUTPUT_THREADS:
-	printf ("%u\n", notmuch_query_count_threads (query));
-	break;
-    }
+    ret = print_count (notmuch, query_str, search_exclude_tags,
+		       search_exclude_tags_length, output);
 
-    notmuch_query_destroy (query);
     notmuch_database_destroy (notmuch);
 
-    return 0;
+    return ret;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/5] cli: add --batch option to notmuch count
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
  2013-01-15 21:54 ` [PATCH 1/5] cli: remove useless strdup Jani Nikula
  2013-01-15 21:54 ` [PATCH 2/5] cli: extract count printing to a separate function in notmuch count Jani Nikula
@ 2013-01-15 21:54 ` Jani Nikula
  2013-01-23 13:36   ` Tomi Ollila
  2013-01-15 21:54 ` [PATCH 4/5] man: document notmuch count --batch and --input options Jani Nikula
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

Add support for reading queries from stdin, one per line, and writing
results to stdin, one per line.

This will bring considerable performance improvements when utilized in
Emacs notmuch-hello, especially so when running remote notmuch.
---
 notmuch-count.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 0e14b48..4bc4215 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -62,6 +62,27 @@ print_count (notmuch_database_t *notmuch, const char *query_str,
     return 0;
 }
 
+static int
+count_file (notmuch_database_t *notmuch, FILE *input, const char **exclude_tags,
+	    size_t exclude_tags_length, int output)
+{
+    char *line = NULL;
+    ssize_t line_len;
+    size_t line_size;
+    int ret = 0;
+
+    while (!ret && (line_len = getline (&line, &line_size, input)) != -1) {
+	chomp_newline (line);
+	ret = print_count (notmuch, line, exclude_tags, exclude_tags_length,
+			   output);
+    }
+
+    if (line)
+	free (line);
+
+    return ret;
+}
+
 int
 notmuch_count_command (void *ctx, int argc, char *argv[])
 {
@@ -73,6 +94,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
     int exclude = EXCLUDE_TRUE;
     const char **search_exclude_tags = NULL;
     size_t search_exclude_tags_length = 0;
+    notmuch_bool_t batch = FALSE;
+    FILE *input = stdin;
+    char *input_file_name = NULL;
     int ret;
 
     notmuch_opt_desc_t options[] = {
@@ -84,6 +108,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	  (notmuch_keyword_t []){ { "true", EXCLUDE_TRUE },
 				  { "false", EXCLUDE_FALSE },
 				  { 0, 0 } } },
+	{ NOTMUCH_OPT_BOOLEAN, &batch, "batch", 0, 0 },
+	{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
 	{ 0, 0, 0, 0, 0 }
     };
 
@@ -93,6 +119,21 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	return 1;
     }
 
+    if (input_file_name) {
+	batch = TRUE;
+	input = fopen (input_file_name, "r");
+	if (input == NULL) {
+	    fprintf (stderr, "Error opening %s for reading: %s\n",
+		     input_file_name, strerror (errno));
+	    return 1;
+	}
+    }
+
+    if (batch && opt_index != argc) {
+	fprintf (stderr, "--batch and query string are not compatible\n");
+	return 1;
+    }
+
     config = notmuch_config_open (ctx, NULL, NULL);
     if (config == NULL)
 	return 1;
@@ -112,10 +153,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	    (config, &search_exclude_tags_length);
     }
 
-    ret = print_count (notmuch, query_str, search_exclude_tags,
-		       search_exclude_tags_length, output);
+    if (batch)
+	ret = count_file (notmuch, input, search_exclude_tags,
+			  search_exclude_tags_length, output);
+    else
+	ret = print_count (notmuch, query_str, search_exclude_tags,
+			   search_exclude_tags_length, output);
 
     notmuch_database_destroy (notmuch);
 
+    if (input != stdin)
+	fclose (input);
+
     return ret;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/5] man: document notmuch count --batch and --input options
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
                   ` (2 preceding siblings ...)
  2013-01-15 21:54 ` [PATCH 3/5] cli: add --batch option to " Jani Nikula
@ 2013-01-15 21:54 ` Jani Nikula
  2013-01-15 21:54 ` [PATCH 5/5] test: " Jani Nikula
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

---
 man/man1/notmuch-count.1 |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/man/man1/notmuch-count.1 b/man/man1/notmuch-count.1
index 335adf5..40be158 100644
--- a/man/man1/notmuch-count.1
+++ b/man/man1/notmuch-count.1
@@ -46,6 +46,26 @@ Output the number of matching threads.
 Specify whether to omit messages matching search.tag_exclude from the
 count (the default) or not.
 .RE
+
+.RS 4
+.TP 4
+.BR \-\-batch
+
+Read queries from a file (stdin by default), one per line, and output
+the number of matching messages (or threads) to stdout, one per
+line. On an empty input line the count of all messages (or threads) in
+the database will be output. This option is not compatible with
+specifying search terms on the command line.
+.RE
+
+.RS 4
+.TP 4
+.BR "\-\-input=" <filename>
+
+Read input from given file, instead of from stdin. Implies
+.BR --batch .
+.RE
+
 .RE
 .RE
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/5] test: notmuch count --batch and --input options
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
                   ` (3 preceding siblings ...)
  2013-01-15 21:54 ` [PATCH 4/5] man: document notmuch count --batch and --input options Jani Nikula
@ 2013-01-15 21:54 ` Jani Nikula
  2013-01-15 23:24 ` [PATCH] emacs: hello: use batch count Mark Walters
  2013-01-15 23:43 ` [PATCH 0/5] notmuch " Mark Walters
  6 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2013-01-15 21:54 UTC (permalink / raw)
  To: notmuch

---
 test/count |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/test/count b/test/count
index 879b114..05713fd 100755
--- a/test/count
+++ b/test/count
@@ -38,4 +38,50 @@ test_expect_equal \
     "0" \
     "`notmuch count --output=threads from:cworth and not from:cworth`"
 
+test_begin_subtest "message count is the default for batch count"
+notmuch count --batch >OUTPUT <<EOF
+
+from:cworth
+EOF
+notmuch count --output=messages >EXPECTED
+notmuch count --output=messages from:cworth >>EXPECTED
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "batch message count"
+notmuch count --batch --output=messages >OUTPUT <<EOF
+from:cworth
+
+tag:inbox
+EOF
+notmuch count --output=messages from:cworth >EXPECTED
+notmuch count --output=messages >>EXPECTED
+notmuch count --output=messages tag:inbox >>EXPECTED
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "batch thread count"
+notmuch count --batch --output=threads >OUTPUT <<EOF
+
+from:cworth
+from:cworth and not from:cworth
+foo
+EOF
+notmuch count --output=threads >EXPECTED
+notmuch count --output=threads from:cworth >>EXPECTED
+notmuch count --output=threads from:cworth and not from:cworth >>EXPECTED
+notmuch count --output=threads foo >>EXPECTED
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "batch message count with input file"
+cat >INPUT <<EOF
+from:cworth
+
+tag:inbox
+EOF
+notmuch count --input=INPUT --output=messages >OUTPUT
+notmuch count --output=messages from:cworth >EXPECTED
+notmuch count --output=messages >>EXPECTED
+notmuch count --output=messages tag:inbox >>EXPECTED
+test_expect_equal_file EXPECTED OUTPUT
+
+
 test_done
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH] emacs: hello: use batch count
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
                   ` (4 preceding siblings ...)
  2013-01-15 21:54 ` [PATCH 5/5] test: " Jani Nikula
@ 2013-01-15 23:24 ` Mark Walters
  2013-01-23 14:13   ` Tomi Ollila
  2013-01-15 23:43 ` [PATCH 0/5] notmuch " Mark Walters
  6 siblings, 1 reply; 13+ messages in thread
From: Mark Walters @ 2013-01-15 23:24 UTC (permalink / raw)
  To: notmuch

This modifies notmuch hello to use the new count --batch
functionality. It should give exactly the same results as before but
under many conditions it should be much faster. In particular it is
much faster for remote use.

The code is a little ugly as it has to do some working out of the
query when asking the query and some when dealing with the result.
However, the code path is exactly the same in both local and remote
use.
---

It's a little ugly but seems to work and does give a useful speedup.

Best wishes

Mark

 emacs/notmuch-hello.el |   52 +++++++++++++++++++++++++++++------------------
 1 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 6db62a0..2244892 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -381,26 +381,38 @@ The result is the list of elements of the form (NAME QUERY COUNT).
 The values :show-empty-searches, :filter and :filter-count from
 options will be handled as specified for
 `notmuch-hello-insert-searches'."
-  (notmuch-remove-if-not
-   #'identity
-   (mapcar
-    (lambda (elem)
-      (let* ((name (car elem))
-	     (query-and-count (if (consp (cdr elem))
-				  ;; do we have a different query for the message count?
-				  (cons (second elem) (third elem))
-				(cons (cdr elem) (cdr elem))))
-	     (message-count
-	      (string-to-number
-	       (notmuch-saved-search-count
-		(notmuch-hello-filtered-query (cdr query-and-count)
-					      (or (plist-get options :filter-count)
-						 (plist-get options :filter)))))))
-	(and (or (plist-get options :show-empty-searches) (> message-count 0))
-	     (list name (notmuch-hello-filtered-query
-			 (car query-and-count) (plist-get options :filter))
-		   message-count))))
-    query-alist)))
+  (with-temp-buffer
+    (dolist (elem query-alist nil)
+      (let ((count-query (if (consp (cdr elem))
+			     ;; do we have a different query for the message count?
+			     (third elem)
+			   (cdr elem))))
+	(insert
+	 (notmuch-hello-filtered-query count-query
+				       (or (plist-get options :filter-count)
+					   (plist-get options :filter)))
+	 "\n")))
+
+    (call-process-region (point-min) (point-max) notmuch-command
+			 t t nil "count" "--batch")
+    (goto-char (point-min))
+
+    (notmuch-remove-if-not
+     #'identity
+     (mapcar
+      (lambda (elem)
+	(let ((name (car elem))
+	      (search-query (if (consp (cdr elem))
+				 ;; do we have a different query for the message count?
+				 (second elem)
+			      (cdr elem)))
+	      (message-count (prog1 (read (current-buffer))
+				(forward-line 1))))
+	  (and (or (plist-get options :show-empty-searches) (> message-count 0))
+	       (list name (notmuch-hello-filtered-query
+			   search-query (plist-get options :filter))
+		     message-count))))
+      query-alist))))
 
 (defun notmuch-hello-insert-buttons (searches)
   "Insert buttons for SEARCHES.
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/5] notmuch batch count
  2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
                   ` (5 preceding siblings ...)
  2013-01-15 23:24 ` [PATCH] emacs: hello: use batch count Mark Walters
@ 2013-01-15 23:43 ` Mark Walters
  2013-01-16  5:02   ` Tomi Ollila
  6 siblings, 1 reply; 13+ messages in thread
From: Mark Walters @ 2013-01-15 23:43 UTC (permalink / raw)
  To: Jani Nikula, notmuch


On Tue, 15 Jan 2013, Jani Nikula <jani@nikula.org> wrote:
> Hi all -
>
> Notmuch remote usage [1] is a pretty handy way of accessing a notmuch
> database on a remote server. However, the more you have saved searches
> and tags, the slower notmuch-hello becomes, and it ends up being by and
> far the biggest usability issue with remote notmuch. This is because
> notmuch-hello issues a separate 'notmuch count' for each saved search
> and tag.
>
> One could argue that notmuch-hello should be fixed somehow, but I chose
> to try another route: batch support for notmuch count. This enables
> notmuch-hello to get the counts for all the saved searches or tags in a
> single call. The performance improvement is huge in remote usage, but
> it's not limited to that. Regular local usage benefits from it too, but
> it's not as obviously noticeable.

This series looks good to me (that is the code looks fine).

Two questions are:

Do we want this functionality? I think it is useful even on local setups
particularly if people have lots of tags (the section that shows all
tags can be quite noticeably sped up). It is a substantial improvement
on remote setups but I am not sure if that is sufficiently common to
warrant the change. At least the code path is the same so it will get
enough testing.

Secondly, if we do the functionality should it be more general so that
it can do searches etc too. I think this is less clear. Count is likely
to be the most useful one since running several (simultaneous) counts is
probably more common than running several simultaneous searches.

Best wishes

Mark


>
> Here's a script that demonstrates one-by-one count vs. batch count,
> locally and over ssh (assuming ssh key authentication is set up), over
> 10 iterations:
>
> #!/bin/bash
>
> echo "tag count:"
> notmuch search --output=tags "*" | wc -l
>
> for remote in "" "ssh example.com"; do
>     export remote
>     echo "one-by-one count:"
>     time sh -c 'for i in `seq 10`; do notmuch search --format=text0 --output=tags "*" | xargs -0 -n 1 -I "{}" $remote notmuch count tag:"{}" > /dev/null; done'
>
>     echo "batch count:"
>     time sh -c 'for i in `seq 10`; do notmuch search --format=text --output=tags "*" | sed "s/.*/tag:\"\0\"/" | $remote notmuch count --batch > /dev/null; done'
> done
>
> And here's the output of it in my setup:
>
> tag count:
> 36
> one-by-one count:
>
> real	0m2.349s
> user	0m0.552s
> sys	0m0.868s
> batch count:
>
> real	0m0.179s
> user	0m0.120s
> sys	0m0.064s
> one-by-one count:
>
> real	0m56.527s
> user	0m1.424s
> sys	0m1.164s
> batch count:
>
> real	0m2.407s
> user	0m0.068s
> sys	0m0.040s
>
> As can be seen, in local usage (the first pair of results) the speedup
> is more than 10x, although one-by-one notmuch count is usually
> sufficiently fast. The difference is more noticeable in remote use (the
> second pair of results), where the speedup is 20x here, and any
> additional, occasional network latency is multiplied by tag count. (That
> result is actually faster than usual for me, but it's still 5+ seconds
> to display or refresh notmuch-hello.)
>
> Mark has written a patch that I've been using to switch notmuch-hello to
> use batch count. That has made me switch from running notmuch in ssh to
> using remote notmuch. The great thing is that we could switch to using
> that in Emacs with no special casing for remote usage, and it would
> speed things up also in local use. I'm expecting Mark to post his patch
> in reply to this series.
>
> Mark actually wrote the elisp part based on the rough idea prior to any
> of this cli plumbing, so I felt obliged to follow up. So thanks Mark!
>
>
> BR,
> Jani.
>
>
> [1] http://notmuchmail.org/remoteusage/ (the page could use some
> cleanup; it's really not nearly as complicated as the page suggests)
>
>
> Jani Nikula (5):
>   cli: remove useless strdup
>   cli: extract count printing to a separate function in notmuch count
>   cli: add --batch option to notmuch count
>   man: document notmuch count --batch and --input options
>   test: notmuch count --batch and --input options
>
>  man/man1/notmuch-count.1 |   20 +++++++++
>  notmuch-count.c          |  111 +++++++++++++++++++++++++++++++++++-----------
>  test/count               |   46 +++++++++++++++++++
>  3 files changed, 150 insertions(+), 27 deletions(-)
>
> -- 
> 1.7.10.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/5] notmuch batch count
  2013-01-15 23:43 ` [PATCH 0/5] notmuch " Mark Walters
@ 2013-01-16  5:02   ` Tomi Ollila
  2013-01-21 17:21     ` Jani Nikula
  0 siblings, 1 reply; 13+ messages in thread
From: Tomi Ollila @ 2013-01-16  5:02 UTC (permalink / raw)
  To: Mark Walters, Jani Nikula, notmuch

On Wed, Jan 16 2013, Mark Walters <markwalters1009@gmail.com> wrote:

> On Tue, 15 Jan 2013, Jani Nikula <jani@nikula.org> wrote:
>> Hi all -
>>
>> Notmuch remote usage [1] is a pretty handy way of accessing a notmuch
>> database on a remote server. However, the more you have saved searches
>> and tags, the slower notmuch-hello becomes, and it ends up being by and
>> far the biggest usability issue with remote notmuch. This is because
>> notmuch-hello issues a separate 'notmuch count' for each saved search
>> and tag.
>>
>> One could argue that notmuch-hello should be fixed somehow, but I chose
>> to try another route: batch support for notmuch count. This enables
>> notmuch-hello to get the counts for all the saved searches or tags in a
>> single call. The performance improvement is huge in remote usage, but
>> it's not limited to that. Regular local usage benefits from it too, but
>> it's not as obviously noticeable.
>
> This series looks good to me (that is the code looks fine).
>
> Two questions are:
>
> Do we want this functionality? I think it is useful even on local setups
> particularly if people have lots of tags (the section that shows all
> tags can be quite noticeably sped up). It is a substantial improvement
> on remote setups but I am not sure if that is sufficiently common to
> warrant the change. At least the code path is the same so it will get
> enough testing.

I do want the functionality. Especialy where I am now it takes about
0.4 sec for 'ssh remote echo foo' to get executed (using connection sharing).
pipelining the count requests could make all the count requests emacs
does (in my current set) to complete in less than 1 sec. 

> Secondly, if we do the functionality should it be more general so that
> it can do searches etc too. I think this is less clear. Count is likely
> to be the most useful one since running several (simultaneous) counts is
> probably more common than running several simultaneous searches.

One could argue that we'd should send json "documents" to notmuch in
stdin and notmuch would output json(/sexp) "documents". That is just
SMOP. I bet Austin would like this solution, especially the part
that involves writing or integrating json parser >;). 
I'd be happy with this 'batch' approach. 

I'll be testing this soon, but refrain from reviewing the code
until 0.15 is out.

>
> Best wishes
>
> Mark


Tomi


>
>
>>
>> Here's a script that demonstrates one-by-one count vs. batch count,
>> locally and over ssh (assuming ssh key authentication is set up), over
>> 10 iterations:
>>
>> #!/bin/bash
>>
>> echo "tag count:"
>> notmuch search --output=tags "*" | wc -l
>>
>> for remote in "" "ssh example.com"; do
>>     export remote
>>     echo "one-by-one count:"
>>     time sh -c 'for i in `seq 10`; do notmuch search --format=text0 --output=tags "*" | xargs -0 -n 1 -I "{}" $remote notmuch count tag:"{}" > /dev/null; done'
>>
>>     echo "batch count:"
>>     time sh -c 'for i in `seq 10`; do notmuch search --format=text --output=tags "*" | sed "s/.*/tag:\"\0\"/" | $remote notmuch count --batch > /dev/null; done'
>> done
>>
>> And here's the output of it in my setup:
>>
>> tag count:
>> 36
>> one-by-one count:
>>
>> real	0m2.349s
>> user	0m0.552s
>> sys	0m0.868s
>> batch count:
>>
>> real	0m0.179s
>> user	0m0.120s
>> sys	0m0.064s
>> one-by-one count:
>>
>> real	0m56.527s
>> user	0m1.424s
>> sys	0m1.164s
>> batch count:
>>
>> real	0m2.407s
>> user	0m0.068s
>> sys	0m0.040s
>>
>> As can be seen, in local usage (the first pair of results) the speedup
>> is more than 10x, although one-by-one notmuch count is usually
>> sufficiently fast. The difference is more noticeable in remote use (the
>> second pair of results), where the speedup is 20x here, and any
>> additional, occasional network latency is multiplied by tag count. (That
>> result is actually faster than usual for me, but it's still 5+ seconds
>> to display or refresh notmuch-hello.)
>>
>> Mark has written a patch that I've been using to switch notmuch-hello to
>> use batch count. That has made me switch from running notmuch in ssh to
>> using remote notmuch. The great thing is that we could switch to using
>> that in Emacs with no special casing for remote usage, and it would
>> speed things up also in local use. I'm expecting Mark to post his patch
>> in reply to this series.
>>
>> Mark actually wrote the elisp part based on the rough idea prior to any
>> of this cli plumbing, so I felt obliged to follow up. So thanks Mark!
>>
>>
>> BR,
>> Jani.
>>
>>
>> [1] http://notmuchmail.org/remoteusage/ (the page could use some
>> cleanup; it's really not nearly as complicated as the page suggests)
>>
>>
>> Jani Nikula (5):
>>   cli: remove useless strdup
>>   cli: extract count printing to a separate function in notmuch count
>>   cli: add --batch option to notmuch count
>>   man: document notmuch count --batch and --input options
>>   test: notmuch count --batch and --input options
>>
>>  man/man1/notmuch-count.1 |   20 +++++++++
>>  notmuch-count.c          |  111 +++++++++++++++++++++++++++++++++++-----------
>>  test/count               |   46 +++++++++++++++++++
>>  3 files changed, 150 insertions(+), 27 deletions(-)
>>
>> -- 
>> 1.7.10.4
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/5] notmuch batch count
  2013-01-16  5:02   ` Tomi Ollila
@ 2013-01-21 17:21     ` Jani Nikula
  2013-01-22 13:43       ` Tomi Ollila
  0 siblings, 1 reply; 13+ messages in thread
From: Jani Nikula @ 2013-01-21 17:21 UTC (permalink / raw)
  To: Tomi Ollila, Mark Walters, notmuch

On Wed, 16 Jan 2013, Tomi Ollila <tomi.ollila@iki.fi> wrote:
> On Wed, Jan 16 2013, Mark Walters <markwalters1009@gmail.com> wrote:
>
>> On Tue, 15 Jan 2013, Jani Nikula <jani@nikula.org> wrote:
>>> Hi all -
>>>
>>> Notmuch remote usage [1] is a pretty handy way of accessing a notmuch
>>> database on a remote server. However, the more you have saved searches
>>> and tags, the slower notmuch-hello becomes, and it ends up being by and
>>> far the biggest usability issue with remote notmuch. This is because
>>> notmuch-hello issues a separate 'notmuch count' for each saved search
>>> and tag.
>>>
>>> One could argue that notmuch-hello should be fixed somehow, but I chose
>>> to try another route: batch support for notmuch count. This enables
>>> notmuch-hello to get the counts for all the saved searches or tags in a
>>> single call. The performance improvement is huge in remote usage, but
>>> it's not limited to that. Regular local usage benefits from it too, but
>>> it's not as obviously noticeable.
>>
>> This series looks good to me (that is the code looks fine).
>>
>> Two questions are:
>>
>> Do we want this functionality? I think it is useful even on local setups
>> particularly if people have lots of tags (the section that shows all
>> tags can be quite noticeably sped up). It is a substantial improvement
>> on remote setups but I am not sure if that is sufficiently common to
>> warrant the change. At least the code path is the same so it will get
>> enough testing.
>
> I do want the functionality. Especialy where I am now it takes about
> 0.4 sec for 'ssh remote echo foo' to get executed (using connection sharing).
> pipelining the count requests could make all the count requests emacs
> does (in my current set) to complete in less than 1 sec. 
>
>> Secondly, if we do the functionality should it be more general so that
>> it can do searches etc too. I think this is less clear. Count is likely
>> to be the most useful one since running several (simultaneous) counts is
>> probably more common than running several simultaneous searches.
>
> One could argue that we'd should send json "documents" to notmuch in
> stdin and notmuch would output json(/sexp) "documents". That is just
> SMOP. I bet Austin would like this solution, especially the part
> that involves writing or integrating json parser >;). 
> I'd be happy with this 'batch' approach. 
>
> I'll be testing this soon, but refrain from reviewing the code
> until 0.15 is out.

id:87a9s5cp38.fsf@zancas.localnet ;)

J.


>
>>
>> Best wishes
>>
>> Mark
>
>
> Tomi
>
>
>>
>>
>>>
>>> Here's a script that demonstrates one-by-one count vs. batch count,
>>> locally and over ssh (assuming ssh key authentication is set up), over
>>> 10 iterations:
>>>
>>> #!/bin/bash
>>>
>>> echo "tag count:"
>>> notmuch search --output=tags "*" | wc -l
>>>
>>> for remote in "" "ssh example.com"; do
>>>     export remote
>>>     echo "one-by-one count:"
>>>     time sh -c 'for i in `seq 10`; do notmuch search --format=text0 --output=tags "*" | xargs -0 -n 1 -I "{}" $remote notmuch count tag:"{}" > /dev/null; done'
>>>
>>>     echo "batch count:"
>>>     time sh -c 'for i in `seq 10`; do notmuch search --format=text --output=tags "*" | sed "s/.*/tag:\"\0\"/" | $remote notmuch count --batch > /dev/null; done'
>>> done
>>>
>>> And here's the output of it in my setup:
>>>
>>> tag count:
>>> 36
>>> one-by-one count:
>>>
>>> real	0m2.349s
>>> user	0m0.552s
>>> sys	0m0.868s
>>> batch count:
>>>
>>> real	0m0.179s
>>> user	0m0.120s
>>> sys	0m0.064s
>>> one-by-one count:
>>>
>>> real	0m56.527s
>>> user	0m1.424s
>>> sys	0m1.164s
>>> batch count:
>>>
>>> real	0m2.407s
>>> user	0m0.068s
>>> sys	0m0.040s
>>>
>>> As can be seen, in local usage (the first pair of results) the speedup
>>> is more than 10x, although one-by-one notmuch count is usually
>>> sufficiently fast. The difference is more noticeable in remote use (the
>>> second pair of results), where the speedup is 20x here, and any
>>> additional, occasional network latency is multiplied by tag count. (That
>>> result is actually faster than usual for me, but it's still 5+ seconds
>>> to display or refresh notmuch-hello.)
>>>
>>> Mark has written a patch that I've been using to switch notmuch-hello to
>>> use batch count. That has made me switch from running notmuch in ssh to
>>> using remote notmuch. The great thing is that we could switch to using
>>> that in Emacs with no special casing for remote usage, and it would
>>> speed things up also in local use. I'm expecting Mark to post his patch
>>> in reply to this series.
>>>
>>> Mark actually wrote the elisp part based on the rough idea prior to any
>>> of this cli plumbing, so I felt obliged to follow up. So thanks Mark!
>>>
>>>
>>> BR,
>>> Jani.
>>>
>>>
>>> [1] http://notmuchmail.org/remoteusage/ (the page could use some
>>> cleanup; it's really not nearly as complicated as the page suggests)
>>>
>>>
>>> Jani Nikula (5):
>>>   cli: remove useless strdup
>>>   cli: extract count printing to a separate function in notmuch count
>>>   cli: add --batch option to notmuch count
>>>   man: document notmuch count --batch and --input options
>>>   test: notmuch count --batch and --input options
>>>
>>>  man/man1/notmuch-count.1 |   20 +++++++++
>>>  notmuch-count.c          |  111 +++++++++++++++++++++++++++++++++++-----------
>>>  test/count               |   46 +++++++++++++++++++
>>>  3 files changed, 150 insertions(+), 27 deletions(-)
>>>
>>> -- 
>>> 1.7.10.4
>> _______________________________________________
>> notmuch mailing list
>> notmuch@notmuchmail.org
>> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/5] notmuch batch count
  2013-01-21 17:21     ` Jani Nikula
@ 2013-01-22 13:43       ` Tomi Ollila
  0 siblings, 0 replies; 13+ messages in thread
From: Tomi Ollila @ 2013-01-22 13:43 UTC (permalink / raw)
  To: Jani Nikula, Mark Walters, notmuch

On Mon, Jan 21 2013, Jani Nikula <jani@nikula.org> wrote:

> On Wed, 16 Jan 2013, Tomi Ollila <tomi.ollila@iki.fi> wrote:
>> One could argue that we'd should send json "documents" to notmuch in
>> stdin and notmuch would output json(/sexp) "documents". That is just
>> SMOP. I bet Austin would like this solution, especially the part
>> that involves writing or integrating json parser >;). 
>> I'd be happy with this 'batch' approach. 
>>
>> I'll be testing this soon, but refrain from reviewing the code
>> until 0.15 is out.
>
> id:87a9s5cp38.fsf@zancas.localnet ;)

OK :D

I started testing:

First a remote script to prepare:

cat > remote-notmuch-test.sh << EOF
#!/bin/bash
printf -v ARGS '%q ' "$@" # bash feature
ssh -S '~'/.ssh/master-notmuch-remote1 -oControlMaster=no 0.1 notmuch $ARGS
EOF
chmod 755 remote-notmuch-test.sh

Note 2 things about the script:

    1)	'~' is in quotes so shell doesn't expand it -- ssh uses /etc/passwd
        instead of environment variable to get HOME (security feature).
        This can be easly tested by prefixing the command with HOME=/tmp.
    2)	The remote address '0.1' is ignored when control socket is active
 	if control socket is down, connection will fail (0.0 connects to
        localhost (I'm not sure which interface in that case)).

Another "script", for emacs:

cat > remote-notmuch-test.el << EOF
(load "notmuch")
(setq notmuch-command "/home/too/remote-notmuch-test.sh")

(setq notmuch-saved-searches '(("inbox" . "tag:inbox")
                               ("unread" . "tag:unread")
                               ("contrib" . "tag:notmuch::contrib")
                               ("pushed" . "tag:notmuch::pushed")
                               ("needs-review" . "tag:notmuch::needs-review")
                               ("moreinfo" . "tag:notmuch::moreinfo")
                               ("stale" . "tag:notmuch::stale")
                               ("wip" . "tag:notmuch::wip")
                               ("bug" . "tag:notmuch::bug")
                               ("obsolete" . "tag:notmuch::obsolete")))

(notmuch)
EOF

First ssh connection with ControlMaster needs to be started
from one terminal:

ssh -S '~'/.ssh/master-notmuch-remote1 -M remote.host.tld

Then, from another terminal, emacs:

emacs -l remote-notmuch-test.el

works, takes quite a long time -- opening 'all tags' even longer.

Let's edit wrapper script:

cat > remote-notmuch-test.sh << EOF
#!/bin/bash
printf -v ARGS '%q ' "$@" # bash feature
echo /usr/bin/time ./remote-notmuch-test.sh $ARGS >> notmuch-replay.$PPID.log
ssh -S '~'/.ssh/master-notmuch-remote1 -oControlMaster=no 0.1 notmuch $ARGS
EOF
chmod 755 remote-notmuch-test.sh

Now, after emacs -l remote-notmuch-test.el run and all tags opened,
exit emacs and run the replay script

env TIME='grepme %Us user %Ss system %P cpu %E total' /usr/bin/time sh ../notmuch-replay.1744.log
last line outputs:
grepme 0.38s user 0.40s system 1% cpu 0:48.21 total

and wc notmuch-replay.1744.log
  61  240 3787 notmuch-replay.1744.log

and each of the individual command in script printed either

grepme 0.00s user 0.00s system 1% cpu 0:00.78 total or
grepme 0.00s user 0.00s system 1% cpu 0:00.79 total.

( 0.785 * 61 = 47.9 so notmuch was wasted elsewhere :)

---

Ok, now patching 2 notmuch trees, one in local and one in
remote machine and building and installing those.

Running emacs -l remote-notmuch-test.el 
was fast (not in one second, but just a few).

Unsuprisingly, the "replay" script cannot be run anymore
as it requires input from stdin, therefore tuning it as follows

cat > remote-notmuch-test.sh << EOF
#!/bin/bash
printf -v ARGS '%q ' "$@" # bash feature
echo `date`: $ARGS >> notmuch-dates.$PPID.log
echo /usr/bin/time ./remote-notmuch-test.sh $ARGS >> notmuch-replay.$PPID.log
ssh -S '~'/.ssh/master-notmuch-remote1 -oControlMaster=no 0.1 notmuch $ARGS
date >> notmuch-dates.$PPID.log
EOF
chmod 755 remote-notmuch-test.sh

now, again: emacs -l remote-notmuch-test.el 
then 'echo output of echo : >> notmuch-dates.2678.log'
and finally opening 'all tags' 

cat notmuch-dates.2678.log

Tue 22 Jan 15:04:34 EET 2013: count
Tue 22 Jan 15:04:35 EET 2013
Tue 22 Jan 15:04:35 EET 2013: count --batch
Tue 22 Jan 15:04:36 EET 2013
Tue 22 Jan 15:04:36 EET 2013: search-tags
Tue 22 Jan 15:04:37 EET 2013
output of echo :
Tue 22 Jan 15:04:45 EET 2013: count
Tue 22 Jan 15:04:45 EET 2013
Tue 22 Jan 15:04:45 EET 2013: count --batch
Tue 22 Jan 15:04:47 EET 2013
Tue 22 Jan 15:04:47 EET 2013: search-tags
Tue 22 Jan 15:04:47 EET 2013
Tue 22 Jan 15:04:47 EET 2013: count --batch
Tue 22 Jan 15:04:49 EET 2013

3 seconds for first tags and 4 seconds for second tags (approximately :)
-- quite an improvement 48 seconds.

Also, changes work fine. Now that I forgot my laptop charger to office
I'll have to wait until tomorrow to do the core review.

(maybe the 2 'count's could be combined in elisp code ;)

>
> J.

Tomi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/5] cli: add --batch option to notmuch count
  2013-01-15 21:54 ` [PATCH 3/5] cli: add --batch option to " Jani Nikula
@ 2013-01-23 13:36   ` Tomi Ollila
  0 siblings, 0 replies; 13+ messages in thread
From: Tomi Ollila @ 2013-01-23 13:36 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Tue, Jan 15 2013, Jani Nikula <jani@nikula.org> wrote:

> Add support for reading queries from stdin, one per line, and writing
> results to stdin, one per line.

Jani's parts LGTM, except one IMPORTANT part -- results are written
to STDOUT! (hopefully...yes) instead of STDIN! ;)

I don't see a reason why this particular way to get counts could
not be supported in notmuch into foreseeable future; the implementation
is simple and clean.

Next to look Mark's changes...

Tomi

>
> This will bring considerable performance improvements when utilized in
> Emacs notmuch-hello, especially so when running remote notmuch.
> ---
>  notmuch-count.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 50 insertions(+), 2 deletions(-)
>
> diff --git a/notmuch-count.c b/notmuch-count.c
> index 0e14b48..4bc4215 100644
> --- a/notmuch-count.c
> +++ b/notmuch-count.c
> @@ -62,6 +62,27 @@ print_count (notmuch_database_t *notmuch, const char *query_str,
>      return 0;
>  }
>  
> +static int
> +count_file (notmuch_database_t *notmuch, FILE *input, const char **exclude_tags,
> +	    size_t exclude_tags_length, int output)
> +{
> +    char *line = NULL;
> +    ssize_t line_len;
> +    size_t line_size;
> +    int ret = 0;
> +
> +    while (!ret && (line_len = getline (&line, &line_size, input)) != -1) {
> +	chomp_newline (line);
> +	ret = print_count (notmuch, line, exclude_tags, exclude_tags_length,
> +			   output);
> +    }
> +
> +    if (line)
> +	free (line);
> +
> +    return ret;
> +}
> +
>  int
>  notmuch_count_command (void *ctx, int argc, char *argv[])
>  {
> @@ -73,6 +94,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>      int exclude = EXCLUDE_TRUE;
>      const char **search_exclude_tags = NULL;
>      size_t search_exclude_tags_length = 0;
> +    notmuch_bool_t batch = FALSE;
> +    FILE *input = stdin;
> +    char *input_file_name = NULL;
>      int ret;
>  
>      notmuch_opt_desc_t options[] = {
> @@ -84,6 +108,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>  	  (notmuch_keyword_t []){ { "true", EXCLUDE_TRUE },
>  				  { "false", EXCLUDE_FALSE },
>  				  { 0, 0 } } },
> +	{ NOTMUCH_OPT_BOOLEAN, &batch, "batch", 0, 0 },
> +	{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
>  	{ 0, 0, 0, 0, 0 }
>      };
>  
> @@ -93,6 +119,21 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>  	return 1;
>      }
>  
> +    if (input_file_name) {
> +	batch = TRUE;
> +	input = fopen (input_file_name, "r");
> +	if (input == NULL) {
> +	    fprintf (stderr, "Error opening %s for reading: %s\n",
> +		     input_file_name, strerror (errno));
> +	    return 1;
> +	}
> +    }
> +
> +    if (batch && opt_index != argc) {
> +	fprintf (stderr, "--batch and query string are not compatible\n");
> +	return 1;
> +    }
> +
>      config = notmuch_config_open (ctx, NULL, NULL);
>      if (config == NULL)
>  	return 1;
> @@ -112,10 +153,17 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
>  	    (config, &search_exclude_tags_length);
>      }
>  
> -    ret = print_count (notmuch, query_str, search_exclude_tags,
> -		       search_exclude_tags_length, output);
> +    if (batch)
> +	ret = count_file (notmuch, input, search_exclude_tags,
> +			  search_exclude_tags_length, output);
> +    else
> +	ret = print_count (notmuch, query_str, search_exclude_tags,
> +			   search_exclude_tags_length, output);
>  
>      notmuch_database_destroy (notmuch);
>  
> +    if (input != stdin)
> +	fclose (input);
> +
>      return ret;
>  }
> -- 
> 1.7.10.4
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] emacs: hello: use batch count
  2013-01-15 23:24 ` [PATCH] emacs: hello: use batch count Mark Walters
@ 2013-01-23 14:13   ` Tomi Ollila
  0 siblings, 0 replies; 13+ messages in thread
From: Tomi Ollila @ 2013-01-23 14:13 UTC (permalink / raw)
  To: Mark Walters, notmuch

On Wed, Jan 16 2013, Mark Walters <markwalters1009@gmail.com> wrote:

> This modifies notmuch hello to use the new count --batch
> functionality. It should give exactly the same results as before but
> under many conditions it should be much faster. In particular it is
> much faster for remote use.
>
> The code is a little ugly as it has to do some working out of the
> query when asking the query and some when dealing with the result.
> However, the code path is exactly the same in both local and remote
> use.
> ---

Well, the code Looks Good To Me (not Bad or Ugly). Pretty straightforward
conversion.

Can we have newlines in query string^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H

Tomi

>
> It's a little ugly but seems to work and does give a useful speedup.
>
> Best wishes
>
> Mark
>
>  emacs/notmuch-hello.el |   52 +++++++++++++++++++++++++++++------------------
>  1 files changed, 32 insertions(+), 20 deletions(-)
>
> diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
> index 6db62a0..2244892 100644
> --- a/emacs/notmuch-hello.el
> +++ b/emacs/notmuch-hello.el
> @@ -381,26 +381,38 @@ The result is the list of elements of the form (NAME QUERY COUNT).
>  The values :show-empty-searches, :filter and :filter-count from
>  options will be handled as specified for
>  `notmuch-hello-insert-searches'."
> -  (notmuch-remove-if-not
> -   #'identity
> -   (mapcar
> -    (lambda (elem)
> -      (let* ((name (car elem))
> -	     (query-and-count (if (consp (cdr elem))
> -				  ;; do we have a different query for the message count?
> -				  (cons (second elem) (third elem))
> -				(cons (cdr elem) (cdr elem))))
> -	     (message-count
> -	      (string-to-number
> -	       (notmuch-saved-search-count
> -		(notmuch-hello-filtered-query (cdr query-and-count)
> -					      (or (plist-get options :filter-count)
> -						 (plist-get options :filter)))))))
> -	(and (or (plist-get options :show-empty-searches) (> message-count 0))
> -	     (list name (notmuch-hello-filtered-query
> -			 (car query-and-count) (plist-get options :filter))
> -		   message-count))))
> -    query-alist)))
> +  (with-temp-buffer
> +    (dolist (elem query-alist nil)
> +      (let ((count-query (if (consp (cdr elem))
> +			     ;; do we have a different query for the message count?
> +			     (third elem)
> +			   (cdr elem))))
> +	(insert
> +	 (notmuch-hello-filtered-query count-query
> +				       (or (plist-get options :filter-count)
> +					   (plist-get options :filter)))
> +	 "\n")))
> +
> +    (call-process-region (point-min) (point-max) notmuch-command
> +			 t t nil "count" "--batch")
> +    (goto-char (point-min))
> +
> +    (notmuch-remove-if-not
> +     #'identity
> +     (mapcar
> +      (lambda (elem)
> +	(let ((name (car elem))
> +	      (search-query (if (consp (cdr elem))
> +				 ;; do we have a different query for the message count?
> +				 (second elem)
> +			      (cdr elem)))
> +	      (message-count (prog1 (read (current-buffer))
> +				(forward-line 1))))
> +	  (and (or (plist-get options :show-empty-searches) (> message-count 0))
> +	       (list name (notmuch-hello-filtered-query
> +			   search-query (plist-get options :filter))
> +		     message-count))))
> +      query-alist))))
>  
>  (defun notmuch-hello-insert-buttons (searches)
>    "Insert buttons for SEARCHES.
> -- 
> 1.7.9.1
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-01-23 14:13 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-15 21:54 [PATCH 0/5] notmuch batch count Jani Nikula
2013-01-15 21:54 ` [PATCH 1/5] cli: remove useless strdup Jani Nikula
2013-01-15 21:54 ` [PATCH 2/5] cli: extract count printing to a separate function in notmuch count Jani Nikula
2013-01-15 21:54 ` [PATCH 3/5] cli: add --batch option to " Jani Nikula
2013-01-23 13:36   ` Tomi Ollila
2013-01-15 21:54 ` [PATCH 4/5] man: document notmuch count --batch and --input options Jani Nikula
2013-01-15 21:54 ` [PATCH 5/5] test: " Jani Nikula
2013-01-15 23:24 ` [PATCH] emacs: hello: use batch count Mark Walters
2013-01-23 14:13   ` Tomi Ollila
2013-01-15 23:43 ` [PATCH 0/5] notmuch " Mark Walters
2013-01-16  5:02   ` Tomi Ollila
2013-01-21 17:21     ` Jani Nikula
2013-01-22 13:43       ` Tomi Ollila

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).