[notmuch] [PATCH] notmuch-restore.c: only update tags for messages that differ from...
authordavid <david@tethera.net>
Sun, 6 Dec 2009 18:30:25 +0000 (14:30 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:35:50 +0000 (09:35 -0800)
6b/c7e750d8aa2317ca80b45781ffaa4ec49353c9 [new file with mode: 0644]

diff --git a/6b/c7e750d8aa2317ca80b45781ffaa4ec49353c9 b/6b/c7e750d8aa2317ca80b45781ffaa4ec49353c9
new file mode 100644 (file)
index 0000000..43fb834
--- /dev/null
@@ -0,0 +1,196 @@
+Return-Path: <bremner@pivot.cs.unb.ca>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 28822431FBC\r
+       for <notmuch@notmuchmail.org>; Sun,  6 Dec 2009 10:30:57 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id ml5u7FT1xzzu for <notmuch@notmuchmail.org>;\r
+       Sun,  6 Dec 2009 10:30:56 -0800 (PST)\r
+Received: from pivot.cs.unb.ca (pivot.cs.unb.ca [131.202.240.57])\r
+       by olra.theworths.org (Postfix) with ESMTP id 5A73C431FAE\r
+       for <notmuch@notmuchmail.org>; Sun,  6 Dec 2009 10:30:56 -0800 (PST)\r
+Received: from\r
+       fctnnbsc30w-142167182194.pppoe-dynamic.high-speed.nb.bellaliant.net\r
+       ([142.167.182.194] helo=localhost)\r
+       by pivot.cs.unb.ca with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32)\r
+       (Exim 4.69) (envelope-from <bremner@pivot.cs.unb.ca>)\r
+       id 1NHLsk-0000tQ-RB; Sun, 06 Dec 2009 14:30:55 -0400\r
+Received: from bremner by localhost with local (Exim 4.69)\r
+       (envelope-from <bremner@pivot.cs.unb.ca>)\r
+       id 1NHLse-0002pB-HU; Sun, 06 Dec 2009 14:30:48 -0400\r
+From: david@tethera.net\r
+To: notmuch@notmuchmail.org\r
+Date: Sun,  6 Dec 2009 14:30:25 -0400\r
+Message-Id: <1260124225-10830-1-git-send-email-david@tethera.net>\r
+X-Mailer: git-send-email 1.6.5.3\r
+X-Sender-Verified: bremner@pivot.cs.unb.ca\r
+Cc: David Bremner <bremner@unb.ca>\r
+Subject: [notmuch] [PATCH] notmuch-restore.c: only update tags for messages\r
+       that differ from dump file.\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.12\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 06 Dec 2009 18:30:57 -0000\r
+\r
+From: David Bremner <bremner@unb.ca>\r
+\r
+The main feature of this patch is that it compares the list of current\r
+tags on a message with those read by restore. Only if the two lists\r
+differ is the tag list in the message replaced.  In my experiments this leads to\r
+a large performance improvement.\r
+\r
+Since I had to rewrite the parsing of tags from the dump file anyway\r
+to keep a list of tags (in case they should be written to the\r
+database), I decided to make it a bit more robust. It sorts the\r
+incoming tags (it is critical for the comparison of the two tag lists\r
+that they are both sorted), and allows arbitrary whitespace (as\r
+determined by "isspace") between tags.\r
+\r
+The patch allocates a temporary array to keep track of the current\r
+list of tags using calloc and grows it as neccesary using realloc.\r
+---\r
+ notmuch-restore.c |   73 ++++++++++++++++++++++++++++++++++++++++++++--------\r
+ 1 files changed, 61 insertions(+), 12 deletions(-)\r
+\r
+diff --git a/notmuch-restore.c b/notmuch-restore.c\r
+index 1b9598d..31e29f6 100644\r
+--- a/notmuch-restore.c\r
++++ b/notmuch-restore.c\r
+@@ -18,8 +18,17 @@\r
+  * Author: Carl Worth <cworth@cworth.org>\r
+  */\r
\r
++#include <stdlib.h>\r
++#include <string.h>\r
++#include <ctype.h>\r
+ #include "notmuch-client.h"\r
\r
++#define DEFAULT_TAG_ARRAY_SIZE 2\r
++/* for qsort */\r
++static int scmp( const void *sp1, const void *sp2 )\r
++{\r
++    return( strcmp(*(const char **)sp1, *(const char **)sp2) );\r
++}\r
+ int\r
+ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+ {\r
+@@ -31,6 +40,9 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+     ssize_t line_len;\r
+     regex_t regex;\r
+     int rerr;\r
++    char **tag_array=NULL;\r
++    int tag_array_size=DEFAULT_TAG_ARRAY_SIZE;\r
++\r
\r
+     config = notmuch_config_open (ctx, NULL, NULL);\r
+     if (config == NULL)\r
+@@ -61,11 +73,18 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+             "^([^ ]+) \\(([^)]*)\\)$",\r
+             REG_EXTENDED);\r
\r
++    /* Make an array of pointers to point to individual tokens */\r
++    tag_array=calloc(tag_array_size,sizeof(char*));\r
++\r
+     while ((line_len = getline (&line, &line_size, input)) != -1) {\r
+       regmatch_t match[3];\r
+-      char *message_id, *tags, *tag, *next;\r
++      char *message_id, *tags,  *next;\r
+       notmuch_message_t *message;\r
+       notmuch_status_t status;\r
++      int tag_count;\r
++\r
++      notmuch_tags_t *tag_list;\r
++      int i;\r
\r
+       chomp_newline (line);\r
\r
+@@ -89,26 +108,53 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+           goto NEXT_LINE;\r
+       }\r
\r
+-      notmuch_message_freeze (message);\r
++      next=tags;\r
++      tag_count=0;\r
++      while(*next){\r
++        while(*next && isspace(*next))\r
++          next++;\r
++        if (*next) {\r
++          while (tag_count>= tag_array_size){\r
++            tag_array_size*=2;\r
++            tag_array=realloc(tag_array,tag_array_size*sizeof(char *));\r
++          }\r
++          tag_array[tag_count]=next;\r
++          tag_count++;\r
++        }\r
++        while (*next && !isspace(*next))\r
++          next++;\r
++        if (*next){\r
++          *next='\0';\r
++          next++;\r
++        }\r
++      }\r
++\r
++      qsort(tag_array,tag_count,sizeof(char*),scmp);\r
++      \r
++      tag_list = notmuch_message_get_tags (message);\r
++      i=0;\r
++      while (notmuch_tags_has_more (tag_list) && i<tag_count &&\r
++             (strcmp(notmuch_tags_get (tag_list),tag_array[i])==0)){\r
++        notmuch_tags_advance (tag_list);\r
++        i++;\r
++      }\r
\r
+-      notmuch_message_remove_all_tags (message);\r
++      if (notmuch_tags_has_more (tag_list) && i<tag_count ){\r
++        notmuch_message_freeze (message);\r
++        notmuch_message_remove_all_tags (message);\r
\r
+-      next = tags;\r
+-      while (next) {\r
+-          tag = strsep (&next, " ");\r
+-          if (*tag == '\0')\r
+-              continue;\r
+-          status = notmuch_message_add_tag (message, tag);\r
++        for (i=0; i<tag_count; i++) {\r
++          status = notmuch_message_add_tag (message, tag_array[i]);\r
+           if (status) {\r
+               fprintf (stderr,\r
+                        "Error applying tag %s to message %s:\n",\r
+-                       tag, message_id);\r
++                       tag_array[i], message_id);\r
+               fprintf (stderr, "%s\n",\r
+                        notmuch_status_to_string (status));\r
+           }\r
++        }\r
++        notmuch_message_thaw (message);\r
+       }\r
+-\r
+-      notmuch_message_thaw (message);\r
+       notmuch_message_destroy (message);\r
+       NEXT_LINE:\r
+       free (message_id);\r
+@@ -120,6 +166,9 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+     if (line)\r
+       free (line);\r
\r
++    if (tag_array)\r
++      free (tag_array);\r
++\r
+     notmuch_database_close (notmuch);\r
+     if (input != stdin)\r
+       fclose (input);\r
+-- \r
+1.6.5.3\r
+\r