unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: david@tethera.net
To: notmuch@notmuchmail.org
Cc: David Bremner <bremner@debian.org>
Subject: [Patch v5 11/11] tag-util: optimization of tag application
Date: Sat,  8 Dec 2012 18:57:01 -0400	[thread overview]
Message-ID: <1355007421-3069-12-git-send-email-david@tethera.net> (raw)
In-Reply-To: <1355007421-3069-1-git-send-email-david@tethera.net>

From: David Bremner <bremner@debian.org>

The idea is not to bother with restore operations if they don't change
the set of tags. This is actually a relatively common case.

In order to avoid fancy datastructures, this method is quadratic in
the number of tags; at least on my mail database this doesn't seem to
be a big problem.
---
 tag-util.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/tag-util.c b/tag-util.c
index 164fdf0..e7233ab 100644
--- a/tag-util.c
+++ b/tag-util.c
@@ -151,6 +151,71 @@ message_error (notmuch_message_t *message,
     fprintf (stderr, "Status: %s\n", notmuch_status_to_string (status));
 }
 
+static int
+makes_changes (notmuch_message_t *message,
+	       tag_op_list_t *list,
+	       tag_op_flag_t flags)
+{
+
+    size_t i;
+
+    notmuch_tags_t *tags;
+    notmuch_bool_t changes = FALSE;
+
+    /* First, do we delete an existing tag? */
+    changes = FALSE;
+    for (tags = notmuch_message_get_tags (message);
+	 ! changes && notmuch_tags_valid (tags);
+	 notmuch_tags_move_to_next (tags)) {
+	const char *cur_tag = notmuch_tags_get (tags);
+	int last_op =  (flags & TAG_FLAG_REMOVE_ALL) ? -1 : 0;
+
+	/* scan backwards to get last operation */
+	i = list->count;
+	while (i > 0) {
+	    i--;
+	    if (strcmp (cur_tag, list->ops[i].tag) == 0) {
+		last_op = list->ops[i].remove ? -1 : 1;
+		break;
+	    }
+	}
+
+	changes = (last_op == -1);
+    }
+    notmuch_tags_destroy (tags);
+
+    if (changes)
+	return TRUE;
+
+    /* Now check for adding new tags */
+    for (i = 0; i < list->count; i++) {
+	notmuch_bool_t exists = FALSE;
+
+	if (list->ops[i].remove)
+	    continue;
+
+	for (tags = notmuch_message_get_tags (message);
+	     notmuch_tags_valid (tags);
+	     notmuch_tags_move_to_next (tags)) {
+	    const char *cur_tag = notmuch_tags_get (tags);
+	    if (strcmp (cur_tag, list->ops[i].tag) == 0) {
+		exists = TRUE;
+		break;
+	    }
+	}
+	notmuch_tags_destroy (tags);
+
+	/* the following test is conservative,
+	 * in the sense it ignores cases like +foo ... -foo
+	 * but this is OK from a correctness point of view
+	 */
+	if (! exists)
+	    return TRUE;
+    }
+    return FALSE;
+
+}
+
 notmuch_status_t
 tag_op_list_apply (notmuch_message_t *message,
 		   tag_op_list_t *list,
@@ -160,6 +225,9 @@ tag_op_list_apply (notmuch_message_t *message,
     notmuch_status_t status = 0;
     tag_operation_t *tag_ops = list->ops;
 
+    if (! (flags & TAG_FLAG_PRE_OPTIMIZED) && ! makes_changes (message, list, flags))
+	return NOTMUCH_STATUS_SUCCESS;
+
     status = notmuch_message_freeze (message);
     if (status) {
 	message_error (message, status, "freezing message");
-- 
1.7.10.4

  parent reply	other threads:[~2012-12-08 22:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-08 22:56 v5 of Batch-tag dump/restore patches david
2012-12-08 22:56 ` [Patch v5 01/11] notmuch-dump: add --format=(batch-tag|sup) david
2012-12-08 22:56 ` [Patch v5 02/11] test: add sanity check for dump --format=batch-tag david
2012-12-08 22:56 ` [Patch v5 03/11] util: add string-util.[ch] david
2012-12-08 22:56 ` [Patch v5 04/11] tag-util.[ch]: New files for common tagging routines david
2012-12-08 22:56 ` [Patch v5 05/11] notmuch-restore: add support for input format 'batch-tag' david
2012-12-08 22:56 ` [Patch v5 06/11] notmuch-restore: normalize case of error messages david
2012-12-08 22:56 ` [Patch v5 07/11] test: update dump-restore roundtripping test for batch-tag format david
2012-12-08 22:56 ` [Patch v5 08/11] test: second set of dump/restore --format=batch-tag tests david
2012-12-08 22:56 ` [Patch v5 09/11] test/dump-restore: add test for warning/error messages david
2012-12-08 22:57 ` [Patch v5 10/11] notmuch-{dump, restore}.1: document new format options david
2012-12-08 22:57 ` david [this message]
2012-12-09 12:55 ` v5 of Batch-tag dump/restore patches David Bremner
2012-12-09 13:46   ` Jani Nikula
2012-12-09 17:17   ` Mark Walters
2012-12-09 23:05 ` David Bremner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1355007421-3069-12-git-send-email-david@tethera.net \
    --to=david@tethera.net \
    --cc=bremner@debian.org \
    --cc=notmuch@notmuchmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).