From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id CAuiIur46V7eFgAA0tVLHw (envelope-from ) for ; Wed, 17 Jun 2020 11:05:14 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id YMp1Hur46V4KfQAAbx9fmQ (envelope-from ) for ; Wed, 17 Jun 2020 11:05:14 +0000 Received: from arlo.cworth.org (arlo.cworth.org [50.126.95.6]) (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 13DE8940223 for ; Wed, 17 Jun 2020 11:05:14 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 699E96DE0ED6; Wed, 17 Jun 2020 04:05:04 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 86Q3RTVHSPBr; Wed, 17 Jun 2020 04:05:03 -0700 (PDT) Received: from arlo.cworth.org (localhost [IPv6:::1]) by arlo.cworth.org (Postfix) with ESMTP id A50396DE0F34; Wed, 17 Jun 2020 04:04:54 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 26E576DE092F for ; Wed, 17 Jun 2020 04:04:52 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gIIGpCv4_-8i for ; Wed, 17 Jun 2020 04:04:51 -0700 (PDT) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by arlo.cworth.org (Postfix) with ESMTPS id F04E56DE023F for ; Wed, 17 Jun 2020 04:04:50 -0700 (PDT) Received: from remotemail by fethera.tethera.net with local (Exim 4.92) (envelope-from ) id 1jlVsA-00026y-55; Wed, 17 Jun 2020 07:04:50 -0400 Received: (nullmailer pid 1262762 invoked by uid 1000); Wed, 17 Jun 2020 11:04:45 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [PATCH 2/3] lib: migrate from Xapian ValueRangeProcessor to RangeProcessor Date: Wed, 17 Jun 2020 08:04:40 -0300 Message-Id: <20200617110441.1262683-3-david@tethera.net> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200617110441.1262683-1-david@tethera.net> References: <20200617110441.1262683-1-david@tethera.net> MIME-Version: 1.0 X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: notmuch-bounces@notmuchmail.org Sender: "notmuch" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 50.126.95.6 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Spam-Score: -0.01 X-TUID: qkvXB5yK3O61 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 | 62 +++++++++++++++++++++--------------------- lib/parse-time-vrp.h | 18 ++++++------ 4 files changed, 53 insertions(+), 54 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..d2495500 100644 --- a/lib/parse-time-vrp.cc +++ b/lib/parse-time-vrp.cc @@ -24,45 +24,47 @@ #include "parse-time-vrp.h" #include "parse-time-string.h" -#define PREFIX "date:" +static Xapian::Query _make_query (Xapian::valueno slot, time_t from, time_t to) { + if (to < 0) { + return Xapian::Query (Xapian::Query::OP_VALUE_GE, slot, + Xapian::sortable_serialise ((double) from)); + } else if (from < 0) { + return Xapian::Query (Xapian::Query::OP_VALUE_LE, slot, + Xapian::sortable_serialise ((double) to)); + } else { + return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise ((double) from), + Xapian::sortable_serialise ((double) to)); + } +} -/* 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; + time_t from = -1, to = -1, now = -1; + 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 (), &from, &now, PARSE_TIME_ROUND_DOWN)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + begin + "'"); - 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 (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); } - return valno; + return _make_query (slot, from, to); } /* XXX TODO: is throwing an exception the right thing to do here? */ @@ -81,7 +83,5 @@ DateFieldProcessor::operator() (const std::string & str) if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); - 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 _make_query (slot, from, 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