unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames.
@ 2009-11-22  0:57 Chris Wilson
  2009-11-27 13:23 ` Carl Worth
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2009-11-22  0:57 UTC (permalink / raw)
  To: notmuch

The majority of filenames will fit within PATH_MAX [4096] (because
that's a hard limit imposed by the filesystems) so we can avoid an
allocation per lookup and thereby eliminate a large proportion of the
overhead of scanning a maildir.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 notmuch-new.c |   75 ++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index 0dd2784..13559d1 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -107,6 +107,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 		     add_files_state_t *state)
 {
     DIR *dir = NULL;
+    char buf[4096];
     struct dirent *entry = NULL;
     char *next = NULL;
     time_t path_mtime, path_dbtime;
@@ -114,6 +115,7 @@ add_files_recursive (notmuch_database_t *notmuch,
     notmuch_message_t *message = NULL;
     struct dirent **namelist = NULL;
     int num_entries;
+    int path_len, dname_len;
 
     /* If we're told to, we bail out on encountering a read-only
      * directory, (with this being a clear clue from the user to
@@ -140,6 +142,12 @@ add_files_recursive (notmuch_database_t *notmuch,
 
     int i=0;
 
+    path_len = strlen (path);
+    if (path_len + 2 < (int) sizeof (buf)) {
+	memcpy (buf, path, path_len);
+	buf[path_len] = '/';
+    }
+
     while (!interrupted) {
 	if (i == num_entries)
 	    break;
@@ -164,37 +172,42 @@ add_files_recursive (notmuch_database_t *notmuch,
 	    continue;
 	}
 
-	next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
+	dname_len = strlen (entry->d_name);
+	if (path_len + dname_len + 2 < (int) sizeof (buf)) {
+	    memcpy (buf + path_len + 1, entry->d_name, dname_len);
+	    buf[path_len + dname_len + 1] = '\0';
+	    next = buf;
+	} else {
+	    next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
+	}
 
 	if (stat (next, st)) {
 	    fprintf (stderr, "Error reading %s: %s\n",
 		     next, strerror (errno));
 	    ret = NOTMUCH_STATUS_FILE_ERROR;
-	    continue;
-	}
-
-	if (S_ISREG (st->st_mode)) {
-	    /* If the file hasn't been modified since the last
-	     * add_files, then we need not look at it. */
-	    if (path_dbtime == 0 || st->st_mtime > path_dbtime) {
-		state->processed_files++;
-
-		status = notmuch_database_add_message (notmuch, next, &message);
-		switch (status) {
-		    /* success */
+	} else {
+	    if (S_ISREG (st->st_mode)) {
+		/* If the file hasn't been modified since the last
+		 * add_files, then we need not look at it. */
+		if (path_dbtime == 0 || st->st_mtime > path_dbtime) {
+		    state->processed_files++;
+
+		    status = notmuch_database_add_message (notmuch, next, &message);
+		    switch (status) {
+			/* success */
 		    case NOTMUCH_STATUS_SUCCESS:
 			state->added_messages++;
 			tag_inbox_and_unread (message);
 			break;
-		    /* Non-fatal issues (go on to next file) */
+			/* Non-fatal issues (go on to next file) */
 		    case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
-		        /* Stay silent on this one. */
+			/* Stay silent on this one. */
 			break;
 		    case NOTMUCH_STATUS_FILE_NOT_EMAIL:
 			fprintf (stderr, "Note: Ignoring non-mail file: %s\n",
 				 next);
 			break;
-		    /* Fatal issues. Don't process anymore. */
+			/* Fatal issues. Don't process anymore. */
 		    case NOTMUCH_STATUS_READONLY_DATABASE:
 		    case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
 		    case NOTMUCH_STATUS_OUT_OF_MEMORY:
@@ -210,25 +223,27 @@ add_files_recursive (notmuch_database_t *notmuch,
 		    case NOTMUCH_STATUS_LAST_STATUS:
 			INTERNAL_ERROR ("add_message returned unexpected value: %d",  status);
 			goto DONE;
-		}
+		    }
 
-		if (message) {
-		    notmuch_message_destroy (message);
-		    message = NULL;
-		}
+		    if (message) {
+			notmuch_message_destroy (message);
+			message = NULL;
+		    }
 
-		if (do_add_files_print_progress) {
-		    do_add_files_print_progress = 0;
-		    add_files_print_progress (state);
+		    if (do_add_files_print_progress) {
+			do_add_files_print_progress = 0;
+			add_files_print_progress (state);
+		    }
 		}
+	    } else if (S_ISDIR (st->st_mode)) {
+		status = add_files_recursive (notmuch, next, st, state);
+		if (status && ret == NOTMUCH_STATUS_SUCCESS)
+		    ret = status;
 	    }
-	} else if (S_ISDIR (st->st_mode)) {
-	    status = add_files_recursive (notmuch, next, st, state);
-	    if (status && ret == NOTMUCH_STATUS_SUCCESS)
-		ret = status;
 	}
 
-	talloc_free (next);
+	if (next != buf)
+	    talloc_free (next);
 	next = NULL;
     }
 
@@ -237,7 +252,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 	ret = status;
 
   DONE:
-    if (next)
+    if (next != buf)
 	talloc_free (next);
     if (entry)
 	free (entry);
-- 
1.6.5.3

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

end of thread, other threads:[~2009-11-28 17:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-22  0:57 [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames Chris Wilson
2009-11-27 13:23 ` Carl Worth
2009-11-27 13:50   ` [PATCH] notmuch-new: Check for non-fatal errors from stat() Chris Wilson
2009-11-28  5:37     ` Carl Worth
2009-11-27 14:17   ` [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames Chris Wilson
2009-11-28  5:41     ` Carl Worth
2009-11-28  5:58       ` Jeffrey Ollie
2009-11-28 17:38   ` Archiving outgoing email in Gnus (was Re: notmuch-new: Eliminate tallocs whilst construct filenames.) Adam Sjøgren

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).