lib: merge internal prefix tables

Replace multiple tables with some flags in a single table. This makes
the code in notmuch_database_open_verbose a bit shorter, and it should
also make it easier to add other options to fields, e.g. regexp
searching.
This commit is contained in:
David Bremner 2017-02-16 23:07:49 -04:00
parent 08343d3da0
commit e30fa4182f
2 changed files with 64 additions and 47 deletions

View file

@ -148,6 +148,30 @@ operator&=(_notmuch_features &a, _notmuch_features b)
return a; return a;
} }
/*
* Configuration options for xapian database fields */
typedef enum notmuch_field_flags {
NOTMUCH_FIELD_NO_FLAGS = 0,
NOTMUCH_FIELD_EXTERNAL = 1 << 0,
NOTMUCH_FIELD_PROBABILISTIC = 1 << 1
} notmuch_field_flag_t;
/*
* define bitwise operators to hide casts */
inline notmuch_field_flag_t
operator|(notmuch_field_flag_t a, notmuch_field_flag_t b)
{
return static_cast<notmuch_field_flag_t>(
static_cast<unsigned>(a) | static_cast<unsigned>(b));
}
inline notmuch_field_flag_t
operator&(notmuch_field_flag_t a, notmuch_field_flag_t b)
{
return static_cast<notmuch_field_flag_t>(
static_cast<unsigned>(a) & static_cast<unsigned>(b));
}
#define NOTMUCH_QUERY_PARSER_FLAGS (Xapian::QueryParser::FLAG_BOOLEAN | \ #define NOTMUCH_QUERY_PARSER_FLAGS (Xapian::QueryParser::FLAG_BOOLEAN | \
Xapian::QueryParser::FLAG_PHRASE | \ Xapian::QueryParser::FLAG_PHRASE | \
Xapian::QueryParser::FLAG_LOVEHATE | \ Xapian::QueryParser::FLAG_LOVEHATE | \

View file

@ -42,6 +42,7 @@ using namespace std;
typedef struct { typedef struct {
const char *name; const char *name;
const char *prefix; const char *prefix;
notmuch_field_flag_t flags;
} prefix_t; } prefix_t;
#define NOTMUCH_DATABASE_VERSION 3 #define NOTMUCH_DATABASE_VERSION 3
@ -247,37 +248,38 @@ typedef struct {
* nearly universal to all mail messages). * nearly universal to all mail messages).
*/ */
static prefix_t BOOLEAN_PREFIX_INTERNAL[] = { static const
{ "type", "T" }, prefix_t prefix_table[] = {
{ "reference", "XREFERENCE" }, /* name term prefix flags */
{ "replyto", "XREPLYTO" }, { "type", "T", NOTMUCH_FIELD_NO_FLAGS },
{ "directory", "XDIRECTORY" }, { "reference", "XREFERENCE", NOTMUCH_FIELD_NO_FLAGS },
{ "file-direntry", "XFDIRENTRY" }, { "replyto", "XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
{ "directory-direntry", "XDDIRENTRY" }, { "directory", "XDIRECTORY", NOTMUCH_FIELD_NO_FLAGS },
}; { "file-direntry", "XFDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
{ "directory-direntry", "XDDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = { { "thread", "G", NOTMUCH_FIELD_EXTERNAL },
{ "thread", "G" }, { "tag", "K", NOTMUCH_FIELD_EXTERNAL },
{ "tag", "K" }, { "is", "K", NOTMUCH_FIELD_EXTERNAL },
{ "is", "K" }, { "id", "Q", NOTMUCH_FIELD_EXTERNAL },
{ "id", "Q" }, { "path", "P", NOTMUCH_FIELD_EXTERNAL },
{ "path", "P" }, { "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL },
{ "property", "XPROPERTY" },
/* /*
* Unconditionally add ':' to reduce potential ambiguity with * Unconditionally add ':' to reduce potential ambiguity with
* overlapping prefixes and/or terms that start with capital * overlapping prefixes and/or terms that start with capital
* letters. See Xapian document termprefixes.html for related * letters. See Xapian document termprefixes.html for related
* discussion. * discussion.
*/ */
{ "folder", "XFOLDER:" }, { "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL },
}; { "from", "XFROM", NOTMUCH_FIELD_EXTERNAL |
NOTMUCH_FIELD_PROBABILISTIC },
static prefix_t PROBABILISTIC_PREFIX[]= { { "to", "XTO", NOTMUCH_FIELD_EXTERNAL |
{ "from", "XFROM" }, NOTMUCH_FIELD_PROBABILISTIC },
{ "to", "XTO" }, { "attachment", "XATTACHMENT", NOTMUCH_FIELD_EXTERNAL |
{ "attachment", "XATTACHMENT" }, NOTMUCH_FIELD_PROBABILISTIC },
{ "mimetype", "XMIMETYPE"}, { "mimetype", "XMIMETYPE", NOTMUCH_FIELD_EXTERNAL |
{ "subject", "XSUBJECT"}, NOTMUCH_FIELD_PROBABILISTIC },
{ "subject", "XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
NOTMUCH_FIELD_PROBABILISTIC },
}; };
const char * const char *
@ -285,19 +287,9 @@ _find_prefix (const char *name)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_INTERNAL); i++) { for (i = 0; i < ARRAY_SIZE (prefix_table); i++) {
if (strcmp (name, BOOLEAN_PREFIX_INTERNAL[i].name) == 0) if (strcmp (name, prefix_table[i].name) == 0)
return BOOLEAN_PREFIX_INTERNAL[i].prefix; return prefix_table[i].prefix;
}
for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {
if (strcmp (name, BOOLEAN_PREFIX_EXTERNAL[i].name) == 0)
return BOOLEAN_PREFIX_EXTERNAL[i].prefix;
}
for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) {
if (strcmp (name, PROBABILISTIC_PREFIX[i].name) == 0)
return PROBABILISTIC_PREFIX[i].prefix;
} }
INTERNAL_ERROR ("No prefix exists for '%s'\n", name); INTERNAL_ERROR ("No prefix exists for '%s'\n", name);
@ -1053,15 +1045,16 @@ notmuch_database_open_verbose (const char *path,
notmuch->query_parser->add_valuerangeprocessor (notmuch->date_range_processor); notmuch->query_parser->add_valuerangeprocessor (notmuch->date_range_processor);
notmuch->query_parser->add_valuerangeprocessor (notmuch->last_mod_range_processor); notmuch->query_parser->add_valuerangeprocessor (notmuch->last_mod_range_processor);
for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) { for (i = 0; i < ARRAY_SIZE (prefix_table); i++) {
prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i]; const prefix_t *prefix = &prefix_table[i];
if (prefix->flags & NOTMUCH_FIELD_EXTERNAL) {
if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC) {
notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
} else {
notmuch->query_parser->add_boolean_prefix (prefix->name, notmuch->query_parser->add_boolean_prefix (prefix->name,
prefix->prefix); prefix->prefix);
} }
}
for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) {
prefix_t *prefix = &PROBABILISTIC_PREFIX[i];
notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
} }
} catch (const Xapian::Error &error) { } catch (const Xapian::Error &error) {
IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n", IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",