Store "from" and "subject" headers in the database.

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.
This commit is contained in:
Austin Clements 2011-11-06 12:17:36 -05:00 committed by David Bremner
parent 9cda22c39b
commit 567bcbc294
3 changed files with 29 additions and 7 deletions

View file

@ -1725,7 +1725,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
goto DONE; goto DONE;
date = notmuch_message_file_get_header (message_file, "date"); 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); _notmuch_message_index_file (message, filename);
} else { } else {

View file

@ -412,6 +412,21 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message)
const char * const char *
notmuch_message_get_header (notmuch_message_t *message, const char *header) 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); _notmuch_message_ensure_message_file (message);
if (message->message_file == NULL) if (message->message_file == NULL)
return NULL; return NULL;
@ -795,8 +810,10 @@ notmuch_message_set_author (notmuch_message_t *message,
} }
void void
_notmuch_message_set_date (notmuch_message_t *message, _notmuch_message_set_header_values (notmuch_message_t *message,
const char *date) const char *date,
const char *from,
const char *subject)
{ {
time_t time_value; time_t time_value;
@ -809,6 +826,8 @@ _notmuch_message_set_date (notmuch_message_t *message,
message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP, message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
Xapian::sortable_serialise (time_value)); 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. */ /* Synchronize changes made to message->doc out into the database. */

View file

@ -93,7 +93,9 @@ NOTMUCH_BEGIN_DECLS
typedef enum { typedef enum {
NOTMUCH_VALUE_TIMESTAMP = 0, NOTMUCH_VALUE_TIMESTAMP = 0,
NOTMUCH_VALUE_MESSAGE_ID NOTMUCH_VALUE_MESSAGE_ID,
NOTMUCH_VALUE_FROM,
NOTMUCH_VALUE_SUBJECT
} notmuch_value_t; } notmuch_value_t;
/* Xapian (with flint backend) complains if we provide a term longer /* 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); _notmuch_message_ensure_thread_id (notmuch_message_t *message);
void void
_notmuch_message_set_date (notmuch_message_t *message, _notmuch_message_set_header_values (notmuch_message_t *message,
const char *date); const char *date,
const char *from,
const char *subject);
void void
_notmuch_message_sync (notmuch_message_t *message); _notmuch_message_sync (notmuch_message_t *message);