Store "from" and "subject" headers in the database.
authorAustin Clements <amdragon@MIT.EDU>
Sun, 6 Nov 2011 17:17:36 +0000 (12:17 -0500)
committerDavid Bremner <bremner@debian.org>
Mon, 14 Nov 2011 21:10:58 +0000 (17:10 -0400)
This is a rebase and cleanup of Istvan Marko's patch from
id:m3pqnj2j7a.fsf@zsu.kismala.com

Search retrieves these headers for every message in the search
results.  Previously, this required opening and parsing every message
file.  Storing them directly in the database significantly reduces IO
and computation, speeding up search by between 50% and 10X.

Taking full advantage of this requires a database rebuild, but it will
fall back to the old behavior for messages that do not have headers
stored in the database.

lib/database.cc
lib/message.cc
lib/notmuch-private.h

index fa632f85121a56d969c2365ff882282290007f53..e4ef14e0c1ee7d7a748e9116de5a20a11e035860 100644 (file)
@@ -1725,7 +1725,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
                goto DONE;
 
            date = notmuch_message_file_get_header (message_file, "date");
-           _notmuch_message_set_date (message, date);
+           _notmuch_message_set_header_values (message, date, from, subject);
 
            _notmuch_message_index_file (message, filename);
        } else {
index 8f22e02a5cde2d37a614febec9b7ad950dc08631..ca7fbf21f19262d6dd69c0f8cc1429685817fb71 100644 (file)
@@ -412,6 +412,21 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message)
 const char *
 notmuch_message_get_header (notmuch_message_t *message, const char *header)
 {
+    std::string value;
+
+    /* Fetch header from the appropriate xapian value field if
+     * available */
+    if (strcasecmp (header, "from") == 0)
+       value = message->doc.get_value (NOTMUCH_VALUE_FROM);
+    else if (strcasecmp (header, "subject") == 0)
+       value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
+    else if (strcasecmp (header, "message-id") == 0)
+       value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID);
+
+    if (!value.empty())
+       return talloc_strdup (message, value.c_str ());
+
+    /* Otherwise fall back to parsing the file */
     _notmuch_message_ensure_message_file (message);
     if (message->message_file == NULL)
        return NULL;
@@ -795,8 +810,10 @@ notmuch_message_set_author (notmuch_message_t *message,
 }
 
 void
-_notmuch_message_set_date (notmuch_message_t *message,
-                          const char *date)
+_notmuch_message_set_header_values (notmuch_message_t *message,
+                                   const char *date,
+                                   const char *from,
+                                   const char *subject)
 {
     time_t time_value;
 
@@ -809,6 +826,8 @@ _notmuch_message_set_date (notmuch_message_t *message,
 
     message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
                            Xapian::sortable_serialise (time_value));
+    message->doc.add_value (NOTMUCH_VALUE_FROM, from);
+    message->doc.add_value (NOTMUCH_VALUE_SUBJECT, subject);
 }
 
 /* Synchronize changes made to message->doc out into the database. */
index 0d3cc27e406f0036d9e20c1cc18c93b59760385a..60a932fc936324fc39fedb3b736d86aeaa4857e5 100644 (file)
@@ -93,7 +93,9 @@ NOTMUCH_BEGIN_DECLS
 
 typedef enum {
     NOTMUCH_VALUE_TIMESTAMP = 0,
-    NOTMUCH_VALUE_MESSAGE_ID
+    NOTMUCH_VALUE_MESSAGE_ID,
+    NOTMUCH_VALUE_FROM,
+    NOTMUCH_VALUE_SUBJECT
 } notmuch_value_t;
 
 /* Xapian (with flint backend) complains if we provide a term longer
@@ -269,9 +271,10 @@ void
 _notmuch_message_ensure_thread_id (notmuch_message_t *message);
 
 void
-_notmuch_message_set_date (notmuch_message_t *message,
-                          const char *date);
-
+_notmuch_message_set_header_values (notmuch_message_t *message,
+                                   const char *date,
+                                   const char *from,
+                                   const char *subject);
 void
 _notmuch_message_sync (notmuch_message_t *message);