Ticket #400: badopt.patch

File badopt.patch, 7.6 KB (added by Richard Boulton, 15 years ago)

Optimisation for AND_MAYBE which doesn't quite work right.

  • matcher/andmaybepostlist.cc

     
    4242    lhead = l->get_docid();
    4343    if (lhead <= rhead) RETURN(NULL);
    4444
     45    if (rmax == 0) {
     46        // If RHS can't supply any weight, it can be ignored for the AndMaybe,
     47        // so we decay to be just the LHS.
     48        PostList *tmp = l;
     49        l = NULL;
     50        RETURN(tmp);
     51    }
     52
    4553    bool valid;
    4654    check_handling_prune(r, lhead, w_min - lmax, matcher, valid);
    4755    if (r->at_end()) {
  • tests/api_queryopt.cc

     
     1/** @file api_queryopt.cc
     2 * @brief Tests of the query optimiser.
     3 */
     4/* Copyright (C) 2009 Lemur Consulting Ltd
     5 *
     6 * This program is free software; you can redistribute it and/or
     7 * modify it under the terms of the GNU General Public License as
     8 * published by the Free Software Foundation; either version 2 of the
     9 * License, or (at your option) any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 * GNU General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
     19 * USA
     20 */
     21
     22#include <config.h>
     23
     24#include "api_queryopt.h"
     25
     26#include <xapian.h>
     27
     28#include "testsuite.h"
     29#include "testutils.h"
     30#include "utils.h"
     31
     32#include "apitest.h"
     33#include <vector>
     34
     35using namespace std;
     36
     37class MyDontUsePostingSource : public Xapian::PostingSource {
     38  public:
     39    MyDontUsePostingSource() : Xapian::PostingSource() {}
     40    PostingSource * clone() const { return new MyDontUsePostingSource(); }
     41    void init(const Xapian::Database &) {
     42        return;
     43    }
     44
     45    Xapian::weight get_weight() const {
     46        FAIL_TEST("MyDontUsePostingSource::get_weight() called");
     47    }
     48
     49    // These bounds could be better, but that's not important here.
     50    Xapian::doccount get_termfreq_min() const {
     51        FAIL_TEST("MyDontUsePostingSource::get_termfreq_min() called");
     52    }
     53    Xapian::doccount get_termfreq_est() const {
     54        FAIL_TEST("MyDontUsePostingSource::get_termfreq_est() called");
     55    }
     56    Xapian::doccount get_termfreq_max() const {
     57        FAIL_TEST("MyDontUsePostingSource::get_termfreq_max() called");
     58    }
     59
     60    void next(Xapian::weight) {
     61        FAIL_TEST("MyDontUsePostingSource::next() called");
     62    }
     63
     64    void skip_to(Xapian::docid, Xapian::weight) {
     65        FAIL_TEST("MyDontUsePostingSource::skip_to() called");
     66    }
     67
     68    bool at_end() const {
     69        FAIL_TEST("MyDontUsePostingSource::at_end() called");
     70    }
     71
     72    Xapian::docid get_docid() const {
     73        FAIL_TEST("MyDontUsePostingSource::get_docid() called");
     74    }
     75
     76    string get_description() const {
     77        return "MyDontUsePostingSource";
     78    }
     79};
     80
     81/// Test that ANDMAYBE branches are ignored if their weight factor is 0.
     82DEFINE_TESTCASE(boolandmaybe1, backend && !remote) {
     83    MyDontUsePostingSource src;
     84    Xapian::Query qsrc(&src);
     85
     86    {
     87        Xapian::Enquire enquire(get_database("etext"));
     88        Xapian::Query query = Xapian::Query::MatchAll;
     89        query = Xapian::Query(query.OP_AND_MAYBE, query, qsrc);
     90        query = Xapian::Query(query.OP_SCALE_WEIGHT, query, 0.0);
     91        enquire.set_query(query);
     92        enquire.get_mset(0, 10);
     93    }
     94
     95    {
     96        Xapian::Enquire enquire(get_database("etext"));
     97        Xapian::Query query = Xapian::Query::MatchAll;
     98        query = Xapian::Query(query.OP_AND_MAYBE, query, qsrc);
     99        enquire.set_weighting_scheme(Xapian::BoolWeight());
     100        enquire.set_query(query);
     101        enquire.get_mset(0, 10);
     102    }
     103
     104    return true;
     105}
     106
     107/** Test that ANDMAYBE branches return same documents and lists of matching
     108 *  terms when their weight factor is 0.
     109 */
     110DEFINE_TESTCASE(boolandmaybe2, backend) {
     111    Xapian::Query query(query.OP_AND_MAYBE,
     112                        Xapian::Query("last"), Xapian::Query("day"));
     113    Xapian::MSet mset1, mset2, mset3;
     114    Xapian::Database db(get_database("etext"));
     115    Xapian::Enquire enquire1(db), enquire2(db), enquire3(db);
     116
     117    {
     118        Xapian::Query query1(query.OP_SCALE_WEIGHT, query, 0.0);
     119        enquire1.set_query(query1);
     120        mset1 = enquire1.get_mset(0, 1000);
     121    }
     122
     123    {
     124        enquire2.set_query(query);
     125        enquire2.set_weighting_scheme(Xapian::BoolWeight());
     126        mset2 = enquire2.get_mset(0, 1000);
     127    }
     128
     129    TEST(mset_range_is_same(mset1, 0, mset2, 0, mset1.size()));
     130
     131    {
     132        enquire3.set_query(query);
     133        mset3 = enquire3.get_mset(0, 1000);
     134    }
     135
     136    vector<Xapian::docid> docs1, docs2, docs3;
     137    for (Xapian::doccount i = 0; i != mset1.size(); ++i) {
     138        docs1.push_back(*mset1[i]);
     139        docs2.push_back(*mset2[i]);
     140        docs3.push_back(*mset3[i]);
     141    }
     142    sort(docs1.begin(), docs1.end());
     143    sort(docs3.begin(), docs3.end());
     144    TEST_EQUAL(docs1, docs3);
     145
     146    for (Xapian::doccount i = 0; i != mset1.size(); ++i) {
     147        Xapian::TermIterator ti1(enquire1.get_matching_terms_begin(docs1[i]));
     148        Xapian::TermIterator tie1(enquire1.get_matching_terms_end(docs1[i]));
     149        Xapian::TermIterator ti2(enquire2.get_matching_terms_begin(docs2[i]));
     150        Xapian::TermIterator tie2(enquire2.get_matching_terms_end(docs2[i]));
     151        Xapian::TermIterator ti3(enquire3.get_matching_terms_begin(docs3[i]));
     152        Xapian::TermIterator tie3(enquire3.get_matching_terms_end(docs3[i]));
     153
     154        while(ti1 != tie1) {
     155            TEST(ti2 != tie2);
     156            TEST(ti3 != tie3);
     157            TEST_EQUAL(*ti1, *ti2);
     158            TEST_EQUAL(*ti2, *ti3);
     159
     160            ++ti1;
     161            ++ti2;
     162            ++ti3;
     163        }
     164        TEST(ti2 == tie2);
     165        TEST(ti3 == tie3);
     166    }
     167
     168    return true;
     169}
  • tests/Makefile.am

     
    123123 api_posdb.cc \
    124124 api_postingsource.cc \
    125125 api_query.cc \
     126 api_queryopt.cc \
    126127 api_replicate.cc \
    127128 api_scalability.cc \
    128129 api_serialise.cc \