Ticket #295: multipostsource.patch

File multipostsource.patch, 11.7 KB (added by Richard Boulton, 16 years ago)

Patch to allow PostingSource to work with multi databases

  • xapian-core/matcher/externalpostlist.cc

     
    2929
    3030using namespace std;
    3131
    32 ExternalPostList::ExternalPostList(Xapian::PostingSource *source_,
     32ExternalPostList::ExternalPostList(const Xapian::Database & db,
     33                                   Xapian::PostingSource *source_,
    3334                                   double factor_)
    34     : source(source_), current(0), factor(factor_)
     35    : source(source_), source_is_owned(false), current(0), factor(factor_)
    3536{
    3637    Assert(source);
    37     source->reset();
     38    Xapian::PostingSource * newsource = source->clone();
     39    if (newsource != NULL) {
     40        source = newsource;
     41        source_is_owned = true;
     42    }
     43    source->reset(db);
    3844}
    3945
     46ExternalPostList::~ExternalPostList()
     47{
     48    if (source_is_owned) {
     49        delete source;
     50    }
     51}
     52
    4053Xapian::doccount
    4154ExternalPostList::get_termfreq_min() const
    4255{
  • xapian-core/matcher/queryoptimiser.cc

     
    6464
    6565        case Xapian::Query::Internal::OP_EXTERNAL_SOURCE:
    6666            Assert(query->external_source);
    67             RETURN(new ExternalPostList(query->external_source, factor));
     67            RETURN(new ExternalPostList(
     68                Xapian::Database(const_cast<Xapian::Database::Internal *>(&db)),
     69                query->external_source, factor));
    6870
    6971        case Xapian::Query::OP_AND:
    7072        case Xapian::Query::OP_FILTER:
  • xapian-core/matcher/externalpostlist.h

     
    2929
    3030class ExternalPostList : public PostList {
    3131    Xapian::PostingSource * source;
     32    bool source_is_owned;
    3233
    3334    Xapian::docid current;
    3435
     
    4344    PostList * update_after_advance();
    4445
    4546  public:
    46     ExternalPostList(Xapian::PostingSource *source_, double factor_);
     47    ExternalPostList(const Xapian::Database & db,
     48                     Xapian::PostingSource *source_,
     49                     double factor_);
     50    ~ExternalPostList();
    4751
    4852    Xapian::doccount get_termfreq_min() const;
    4953
  • xapian-core/tests/api_db.cc

     
    18871887        : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0)
    18881888    { }
    18891889
    1890     void reset() { did = 0; }
     1890    void reset(const Xapian::Database &) { did = 0; }
    18911891
    18921892    // These bounds could be better, but that's not important here.
    18931893    Xapian::doccount get_termfreq_min() const { return 0; }
     
    19811981        : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0)
    19821982    { }
    19831983
    1984     void reset() { did = 0; }
     1984    void reset(const Xapian::Database &) { did = 0; }
    19851985
    19861986    Xapian::weight get_weight() const {
    19871987        return (did % 2) ? 1000 : 0.001;
     
    20782078        : num_docs(db.get_doccount()), last_docid(db.get_lastdocid()), did(0)
    20792079    { }
    20802080
    2081     void reset() { did = 0; }
     2081    void reset(const Xapian::Database &) { did = 0; }
    20822082
    20832083    Xapian::weight get_weight() const {
    20842084        FAIL_TEST("MyDontAskWeightPostingSource::get_weight() called");
     
    21522152
    21532153// Check that valueweightsource works correctly.
    21542154DEFINE_TESTCASE(valueweightsource1, backend && !remote) {
    2155     // FIXME: PostingSource doesn't currently work well with multi databases
    2156     // but we should try to resolve that issue.
    2157     SKIP_TEST_FOR_BACKEND("multi");
    21582155    Xapian::Database db(get_database("apitest_phrase"));
    21592156    Xapian::Enquire enq(db);
    2160     Xapian::ValueWeightPostingSource src(db, 11);
     2157    Xapian::ValueWeightPostingSource src(11);
    21612158
    21622159    // Should be in descending order of length
    21632160    tout << "RAW" << endl;
     
    21892186// Check that valueweightsource gives the correct bounds for those databases
    21902187// which support value statistics.
    21912188DEFINE_TESTCASE(valueweightsource2, backend && valuestats) {
    2192     // FIXME: PostingSource doesn't currently work well with multi databases
    2193     // but we should try to resolve that issue.
    2194     SKIP_TEST_FOR_BACKEND("multi");
    21952189    Xapian::Database db(get_database("apitest_phrase"));
    2196     Xapian::ValueWeightPostingSource src(db, 11);
     2190    Xapian::ValueWeightPostingSource src(11);
     2191    src.reset(db);
    21972192    TEST_EQUAL(src.get_termfreq_min(), 17);
    21982193    TEST_EQUAL(src.get_termfreq_est(), 17);
    21992194    TEST_EQUAL(src.get_termfreq_max(), 17);
     
    22042199
    22052200// Check that valueweightsource skip_to() can stay in the same position.
    22062201DEFINE_TESTCASE(valueweightsource3, backend && valuestats) {
    2207     // FIXME: PostingSource doesn't currently work well with multi databases
    2208     // but we should try to resolve that issue.
    2209     SKIP_TEST_FOR_BACKEND("multi");
    22102202    Xapian::Database db(get_database("apitest_phrase"));
    2211     Xapian::ValueWeightPostingSource src(db, 11);
     2203    Xapian::ValueWeightPostingSource src(11);
     2204    src.reset(db);
    22122205    TEST(!src.at_end());
    22132206    src.skip_to(8, 0.0);
    22142207    TEST(!src.at_end());
  • xapian-core/tests/api_percentages.cc

     
    5555        if (wt > maxwt) maxwt = wt;
    5656    }
    5757
    58     void reset() { started = false; }
     58    void reset(const Xapian::Database &) { started = false; }
    5959
    6060    Xapian::weight get_weight() const {
    6161        return i->second;
  • xapian-core/include/xapian/postingsource.h

     
    137137    /// Return the current docid.
    138138    virtual Xapian::docid get_docid() const = 0;
    139139
     140    /** Clone the posting source.
     141     *
     142     *  FIXME - more documentation needed.
     143     *
     144     *  This may return NULL to indicate that cloning is not possible.  In this
     145     *  case, the PostingSource will work only if a single database is being
     146     *  searched.  The default implementation returns NULL.
     147     */
     148    virtual PostingSource * clone() const;
     149
    140150    /** Reset this PostingSource to its freshly constructed state.
    141151     *
    142152     *  This is called automatically by the matcher prior to each query being
    143153     *  processed.
     154     *
     155     *  FIXME - document the db parameter.
    144156     */
    145     virtual void reset() = 0;
     157    virtual void reset(const Database & db) = 0;
    146158
    147159    /** Return a string describing this object.
    148160     *
     
    196208    /// An upper bound on the value returned.
    197209    double max_value;
    198210
     211    /// Upper bound on the value returned specified in constructor.
     212    double specified_max_value;
     213
    199214  public:
    200215    /** Construct a ValueWeightPostingSource.
    201216     *
    202217     *  @param db_ The database to read values from.
    203218     *  @param valno_ The value slot to read values from.
    204219     */
    205     ValueWeightPostingSource(Xapian::Database db_, Xapian::valueno valno_);
     220    ValueWeightPostingSource(Xapian::valueno valno_);
    206221
    207222    /** Construct a ValueWeightPostingSource.
    208223     *
     
    214229     *  constructor need only be used if more accurate information is
    215230     *  available.
    216231     */
    217     ValueWeightPostingSource(Xapian::Database db_, Xapian::valueno valno_,
    218                              double max_weight_);
     232    ValueWeightPostingSource(Xapian::valueno valno_, double max_weight_);
    219233
    220234    Xapian::doccount get_termfreq_min() const;
    221235    Xapian::doccount get_termfreq_est() const;
     
    232246
    233247    Xapian::docid get_docid() const;
    234248
    235     void reset();
     249    ValueWeightPostingSource * clone() const;
     250    void reset(const Database & db_);
    236251
    237252    std::string get_description() const;
    238253};
  • xapian-core/api/postingsource.cc

     
    6767    return true;
    6868}
    6969
     70PostingSource *
     71PostingSource::clone() const
     72{
     73    return NULL;
     74}
     75
     76
    7077std::string
    7178PostingSource::get_description() const
    7279{
     
    7481}
    7582
    7683
    77 ValueWeightPostingSource::ValueWeightPostingSource(Xapian::Database db_,
    78                                                    Xapian::valueno valno_)
    79         : db(db_),
    80           valno(valno_),
    81           current_docid(0),
    82           last_docid(db.get_lastdocid()),
    83           current_value(0.0)
     84ValueWeightPostingSource::ValueWeightPostingSource(Xapian::valueno valno_)
     85        : valno(valno_),
     86          specified_max_value(DBL_MAX)
    8487{
    85     try {
    86         termfreq_max = db.get_value_freq(valno);
    87         termfreq_est = termfreq_max;
    88         termfreq_min = termfreq_max;
    89         max_value = sortable_unserialise(db.get_value_upper_bound(valno));
    90     } catch (const Xapian::UnimplementedError &) {
    91         termfreq_max = db.get_doccount();
    92         termfreq_est = termfreq_max / 2;
    93         termfreq_min = 0;
    94         max_value = DBL_MAX;
    95     }
    9688}
    9789
    98 ValueWeightPostingSource::ValueWeightPostingSource(Xapian::Database db_,
    99                                                    Xapian::valueno valno_,
     90ValueWeightPostingSource::ValueWeightPostingSource(Xapian::valueno valno_,
    10091                                                   double max_weight_)
    101         : db(db_),
    102           valno(valno_),
    103           current_docid(0),
    104           last_docid(db.get_lastdocid()),
    105           current_value(0.0),
    106           max_value(max_weight_)
     92        : valno(valno_),
     93          specified_max_value(max_weight_)
    10794{
    108     try {
    109         termfreq_max = db.get_value_freq(valno);
    110         termfreq_est = termfreq_max;
    111         termfreq_min = termfreq_max;
    112         max_value = std::min(max_value,
    113                              sortable_unserialise(db.get_value_upper_bound(valno)));
    114     } catch (const Xapian::UnimplementedError &) {
    115         termfreq_max = db.get_doccount();
    116         termfreq_est = termfreq_max / 2;
    117         termfreq_min = 0;
    118     }
    11995}
    12096
    12197Xapian::doccount
     
    232208    return current_docid;
    233209}
    234210
     211ValueWeightPostingSource *
     212ValueWeightPostingSource::clone() const
     213{
     214    return new ValueWeightPostingSource(valno, specified_max_value);
     215}
     216
    235217void
    236 ValueWeightPostingSource::reset()
     218ValueWeightPostingSource::reset(const Database & db_)
    237219{
     220    db = db_;
    238221    current_docid = 0;
     222    current_value = 0.0;
     223    last_docid = db.get_lastdocid();
     224    try {
     225        termfreq_max = db.get_value_freq(valno);
     226        termfreq_est = termfreq_max;
     227        termfreq_min = termfreq_max;
     228        max_value = std::min(specified_max_value,
     229                        sortable_unserialise(db.get_value_upper_bound(valno)));
     230    } catch (const Xapian::UnimplementedError &) {
     231        termfreq_max = db.get_doccount();
     232        termfreq_est = termfreq_max / 2;
     233        termfreq_min = 0;
     234        max_value = specified_max_value;
     235    }
    239236}
    240237
    241238std::string
  • xapian-bindings/python/pythontest2.py

     
    912912            xapian.PostingSource.__init__(self)
    913913            self.max = max
    914914
    915         def reset(self):
     915        def reset(self, db):
    916916            self.current = -1
    917917
    918918        def get_termfreq_min(self): return 0
     
    953953        doc.add_value(1, xapian.sortable_serialise(vals[id]))
    954954        db.add_document(doc)
    955955
    956     source = xapian.ValueWeightPostingSource(db, 1)
     956    source = xapian.ValueWeightPostingSource(1)
    957957    query = xapian.Query(source)
    958958    # del source # Check that query keeps a reference to it.
    959959
  • xapian-bindings/xapian.i

     
    194194
    195195#ifdef XAPIAN_SWIG_DIRECTORS
    196196%feature("director") Xapian::PostingSource;
     197%ignore Xapian::PostingSource::clone;
    197198%include <xapian/postingsource.h>
    198199#else
    199200%ignore Xapian::Query(Xapian::PostingSource *);