[notmuch] [PATCH] notmuch-new: Eliminate tallocs whilst construct filenames.

Chris Wilson chris at chris-wilson.co.uk
Sat Nov 21 16:57:10 PST 2009


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 at 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



More information about the notmuch mailing list