From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id 8LMrEhVVBF9deQAA0tVLHw (envelope-from ) for ; Tue, 07 Jul 2020 10:57:25 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id qOb+DRVVBF9vXgAA1q6Kng (envelope-from ) for ; Tue, 07 Jul 2020 10:57:25 +0000 Received: from mail.notmuchmail.org (nmbug.tethera.net [IPv6:2607:5300:201:3100::1657]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id C764C940220 for ; Tue, 7 Jul 2020 10:57:24 +0000 (UTC) Received: from [144.217.243.247] (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id 7B6EF1FD76; Tue, 7 Jul 2020 06:57:04 -0400 (EDT) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by mail.notmuchmail.org (Postfix) with ESMTP id D10141FCB5 for ; Tue, 7 Jul 2020 06:56:53 -0400 (EDT) Received: by fethera.tethera.net (Postfix, from userid 1001) id A55AA613B0; Tue, 7 Jul 2020 06:56:53 -0400 (EDT) Received: (nullmailer pid 433310 invoked by uid 1000); Tue, 07 Jul 2020 10:56:48 -0000 From: David Bremner To: notmuch@notmuchmail.org Cc: David Bremner Subject: [PATCH 2/3] lib: migrate from Xapian ValueRangeProcessor to RangeProcessor Date: Tue, 7 Jul 2020 07:56:46 -0300 Message-Id: <20200707105647.433187-3-david@tethera.net> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200707105647.433187-1-david@tethera.net> References: <20200707105647.433187-1-david@tethera.net> MIME-Version: 1.0 Message-ID-Hash: 3QZFN55FBMNZZEQIUXVN25MI4UWMGFSE X-Message-ID-Hash: 3QZFN55FBMNZZEQIUXVN25MI4UWMGFSE X-MailFrom: bremner@tethera.net X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.1 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 2607:5300:201:3100::1657 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Spam-Score: 1.53 X-TUID: sUB27GDfYU3L This will be mandatory as of Xapian 1.5. The API is also more consistent with the FieldProcessor API, which helps code re-use a bit. Note that this switches to using the built-in Xapian support for prefixes on ranges (i.e. deleted code at beginning of ParseTimeRangeProcessor::operator(), added prefix to constructor). Another side effect of the migration is that we are generating smaller queries, using one OP_VALUE_RANGE instead of an AND of two OP_VALUE_* queries. --- lib/database-private.h | 6 ++-- lib/database.cc | 21 ++++++------- lib/parse-time-vrp.cc | 69 +++++++++++++++++++++--------------------- lib/parse-time-vrp.h | 18 +++++------ 4 files changed, 56 insertions(+), 58 deletions(-) diff --git a/lib/database-private.h b/lib/database-private.h index 87ae1bdf..76359007 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -218,9 +218,9 @@ struct _notmuch_database { unsigned long view; Xapian::QueryParser *query_parser; Xapian::TermGenerator *term_gen; - Xapian::ValueRangeProcessor *value_range_processor; - Xapian::ValueRangeProcessor *date_range_processor; - Xapian::ValueRangeProcessor *last_mod_range_processor; + Xapian::RangeProcessor *value_range_processor; + Xapian::RangeProcessor *date_range_processor; + Xapian::RangeProcessor *last_mod_range_processor; /* XXX it's slightly gross to use two parallel string->string maps * here, but at least they are small */ diff --git a/lib/database.cc b/lib/database.cc index 43bfac4e..2f794164 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -385,8 +385,8 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) Xapian::FieldProcessor *fp; if (STRNCMP_LITERAL (prefix->name, "date") == 0) - fp = (new DateFieldProcessor ())->release (); - else if (STRNCMP_LITERAL (prefix->name, "query") == 0) + fp = (new DateFieldProcessor(NOTMUCH_VALUE_TIMESTAMP))->release (); + else if (STRNCMP_LITERAL(prefix->name, "query") == 0) fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release (); else if (STRNCMP_LITERAL (prefix->name, "thread") == 0) fp = (new ThreadFieldProcessor (*notmuch->query_parser, notmuch))->release (); @@ -1036,17 +1036,16 @@ notmuch_database_open_verbose (const char *path, notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; notmuch->term_gen->set_stemmer (Xapian::Stem ("english")); - notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); - notmuch->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); - notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:"); - + notmuch->value_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); + notmuch->date_range_processor = new ParseTimeRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:"); + notmuch->last_mod_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:"); notmuch->query_parser->set_default_op (Xapian::Query::OP_AND); notmuch->query_parser->set_database (*notmuch->xapian_db); notmuch->query_parser->set_stemmer (Xapian::Stem ("english")); notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME); - notmuch->query_parser->add_valuerangeprocessor (notmuch->value_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_rangeprocessor (notmuch->value_range_processor); + notmuch->query_parser->add_rangeprocessor (notmuch->date_range_processor); + notmuch->query_parser->add_rangeprocessor (notmuch->last_mod_range_processor); for (i = 0; i < ARRAY_SIZE (prefix_table); i++) { const prefix_t *prefix = &prefix_table[i]; @@ -1401,8 +1400,8 @@ handle_sigalrm (unused (int signal)) */ notmuch_status_t notmuch_database_upgrade (notmuch_database_t *notmuch, - void (*progress_notify)(void *closure, - double progress), + void (*progress_notify) (void *closure, + double progress), void *closure) { void *local = talloc_new (NULL); diff --git a/lib/parse-time-vrp.cc b/lib/parse-time-vrp.cc index 168d5810..10809aa3 100644 --- a/lib/parse-time-vrp.cc +++ b/lib/parse-time-vrp.cc @@ -24,64 +24,63 @@ #include "parse-time-vrp.h" #include "parse-time-string.h" -#define PREFIX "date:" - -/* See *ValueRangeProcessor in xapian-core/api/valuerangeproc.cc */ -Xapian::valueno -ParseTimeValueRangeProcessor::operator() (std::string &begin, std::string &end) +Xapian::Query +ParseTimeRangeProcessor::operator() (const std::string &begin, const std::string &end) { - time_t t, now; - std::string b; - - /* Require date: prefix in start of the range... */ - if (STRNCMP_LITERAL (begin.c_str (), PREFIX)) - return Xapian::BAD_VALUENO; - - /* ...and remove it. */ - begin.erase (0, sizeof (PREFIX) - 1); - b = begin; + double from = DBL_MIN, to = DBL_MAX; + time_t parsed_time, now; + std::string str; /* Use the same 'now' for begin and end. */ if (time (&now) == (time_t) -1) - return Xapian::BAD_VALUENO; - - if (! begin.empty ()) { - if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN)) - return Xapian::BAD_VALUENO; + throw Xapian::QueryParserError ("unable to get current time"); - begin.assign (Xapian::sortable_serialise ((double) t)); + if (!begin.empty ()) { + if (parse_time_string (begin.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + begin + "'"); + else + from = (double) parsed_time; } - if (! end.empty ()) { - if (end == "!" && ! b.empty ()) - end = b; - - if (parse_time_string (end.c_str (), &t, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) - return Xapian::BAD_VALUENO; + if (!end.empty ()) { + if (end == "!" && ! begin.empty ()) + str = begin; + else + str = end; - end.assign (Xapian::sortable_serialise ((double) t)); + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); + else + to = (double) parsed_time; } - return valno; + return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise (from), + Xapian::sortable_serialise (to)); } /* XXX TODO: is throwing an exception the right thing to do here? */ Xapian::Query DateFieldProcessor::operator() (const std::string & str) { - time_t from, to, now; + double from = DBL_MIN, to = DBL_MAX; + time_t parsed_time, now; /* Use the same 'now' for begin and end. */ if (time (&now) == (time_t) -1) throw Xapian::QueryParserError ("Unable to get current time"); - if (parse_time_string (str.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN)) + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); + else + from = (double) parsed_time; - if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); + else + to = (double) parsed_time; - return Xapian::Query (Xapian::Query::OP_AND, - Xapian::Query (Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)), - Xapian::Query (Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to))); + return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise (from), + Xapian::sortable_serialise (to)); } diff --git a/lib/parse-time-vrp.h b/lib/parse-time-vrp.h index 9fb1af60..f495e716 100644 --- a/lib/parse-time-vrp.h +++ b/lib/parse-time-vrp.h @@ -26,21 +26,21 @@ #include /* see *ValueRangeProcessor in xapian-core/include/xapian/queryparser.h */ -class ParseTimeValueRangeProcessor : public Xapian::ValueRangeProcessor { -protected: - Xapian::valueno valno; +class ParseTimeRangeProcessor : public Xapian::RangeProcessor { public: - ParseTimeValueRangeProcessor (Xapian::valueno slot_) - : valno (slot_) - { - } + ParseTimeRangeProcessor (Xapian::valueno slot_, const std::string prefix_) + : Xapian::RangeProcessor(slot_, prefix_, 0) { } - Xapian::valueno operator() (std::string &begin, std::string &end); + Xapian::Query operator() (const std::string &begin, const std::string &end); }; class DateFieldProcessor : public Xapian::FieldProcessor { - Xapian::Query operator() (const std::string & str); +private: + Xapian::valueno slot; +public: + DateFieldProcessor(Xapian::valueno slot_) : slot(slot_) { }; + Xapian::Query operator()(const std::string & str); }; #endif /* NOTMUCH_PARSE_TIME_VRP_H */ -- 2.27.0