Ticket #295: multipostsource.patch

File multipostsource.patch, 11.7 kB (added by richard, 4 months 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 *);