Ticket #340: patch

File patch, 6.2 KB (added by Richard Boulton, 15 years ago)

Implementation of this (untested)

  • matcher/externalpostlist.cc

     
    2525
    2626#include <xapian/postingsource.h>
    2727
     28#include "multimatch.h"
    2829#include "omassert.h"
    2930#include "omdebug.h"
    3031
     
    3233
    3334ExternalPostList::ExternalPostList(const Xapian::Database & db,
    3435                                   Xapian::PostingSource *source_,
    35                                    double factor_)
    36     : source(source_), source_is_owned(false), current(0), factor(factor_)
     36                                   double factor_,
     37                                   MultiMatch * matcher_)
     38    : source(source_), source_is_owned(false), current(0), factor(factor_),
     39        matcher(matcher_)
    3740{
    3841    Assert(source);
    3942    Xapian::PostingSource * newsource = source->clone();
     
    5154    }
    5255}
    5356
     57void
     58ExternalPostList::notify_new_maxweight()
     59{
     60    matcher->recalc_maxweight();
     61}
     62
    5463Xapian::doccount
    5564ExternalPostList::get_termfreq_min() const
    5665{
  • matcher/queryoptimiser.cc

     
    6868            Assert(query->external_source);
    6969            Xapian::Database wrappeddb(new ConstDatabaseWrapper(&db));
    7070            RETURN(new ExternalPostList(wrappeddb,
    71                                         query->external_source, factor));
     71                                        query->external_source, factor,
     72                                        matcher));
    7273        }
    7374
    7475        case Xapian::Query::OP_AND:
  • matcher/externalpostlist.h

     
    2828    class PostingSource;
    2929}
    3030
     31class MultiMatch;
     32
    3133class ExternalPostList : public PostList {
    3234    Xapian::PostingSource * source;
    3335    bool source_is_owned;
     
    3638
    3739    double factor;
    3840
     41    /// The matcher to notify when maximum weights change.
     42    MultiMatch * matcher;
     43
    3944    /// Disallow copying.
    4045    ExternalPostList(const ExternalPostList &);
    4146
     
    4752  public:
    4853    ExternalPostList(const Xapian::Database & db,
    4954                     Xapian::PostingSource *source_,
    50                      double factor_);
     55                     double factor_,
     56                     MultiMatch * matcher_);
    5157    ~ExternalPostList();
    5258
     59    void notify_new_maxweight();
     60
    5361    Xapian::doccount get_termfreq_min() const;
    5462
    5563    Xapian::doccount get_termfreq_est() const;
  • docs/postingsource.rst

     
    11
    22.. Copyright (C) 2008,2009 Olly Betts
     3.. Copyright (C) 2009 Lemur Consulting Ltd
    34
    45=====================
    56Xapian::PostingSource
     
    7273These methods have default implementations which always return 0, for
    7374convenience when deriving "weight-less" subclasses.
    7475
     76If the maximum weight that can be returned by the PostingSource has decreased
     77significantly, it may be worthwhile to notify the Xapian matcher about this, so
     78that it can use this information for optmisations, allowing the match process
     79to finish faster.  You can notify the matcher about this by calling the
     80``PostingSource::notify_new_maxweight()`` method.  However, you should take
     81care not to call this method too frequently, as the resulting computation can
     82be moderately expensive.
     83
     84It is therefore advisable only to call this after a significant decrease in
     85maxweight.  Profiling your postingsource will often be the best way to
     86determine how often to call it.  If it's cheap to calculate the maxweight in
     87your posting source, a reasonable strategy is to decide a maximum number of
     88times to call this method (eg, 10) and then to call it whenever
     89``floor(new_maxweight * 10 / original_maxweight)`` changes; this ensures that
     90only reasonably significant drops result in a recalculation of the weights.
     91Alternatively, you could simply impose a lower limit on the number of documents
     92processed before re-calling this.
     93
    7594The ``at_end()`` method checks if the current iteration position is past the
    7695last entry::
    7796
  • include/xapian/postingsource.h

     
    2929#include <string>
    3030#include <map>
    3131
     32// Declaration of an opaque internal type.
     33class ExternalPostList;
     34
    3235namespace Xapian {
    3336
    3437/** Base class which provides an "external" source of postings.
     
    4346    /// Don't allow copying.
    4447    PostingSource(const PostingSource &);
    4548
     49    /// The ExternalPostList which notifications should be sent to.
     50    ExternalPostList * externalpl;
     51
     52    /// Set a pointer to the external postlist.
     53    void register_externalpl(ExternalPostList * externalpl_) {
     54        externalpl = externalpl_;
     55    }
     56
     57    // ExternalPostList needs to be able to call register_externalpl.
     58    friend class ::ExternalPostList;
     59
    4660  protected:
    4761    /// Allow subclasses to be instantiated.
    4862    PostingSource() { }
    4963
     64    /** Notify the matcher that the maximum weight has decreased.
     65     *
     66     *  This will potentially cause the maxweights throughout the query tree
     67     *  to be re-evaluated, and can therefore be quite expensive.  On the
     68     *  other hand, it will allow the new reduced maxweight to be used to
     69     *  trigger query optimisations, which can greatly reduce the query
     70     *  processing time.
     71     *
     72     *  It is therefore advisable only to call this after a significant
     73     *  decrease in maxweight.
     74     */
     75    void notify_new_maxweight();
     76
    5077  public:
    5178    // Destructor.
    5279    virtual ~PostingSource();
  • api/postingsource.cc

     
    2727
    2828#include "database.h"
    2929#include "document.h"
     30#include "matcher/externalpostlist.h"
     31
    3032#include "xapian/document.h"
    3133#include "xapian/error.h"
    3234#include "xapian/queryparser.h" // For sortable_unserialise().
     
    4042
    4143namespace Xapian {
    4244
     45void
     46PostingSource::notify_new_maxweight()
     47{
     48    externalpl->notify_new_maxweight();
     49}
     50
    4351PostingSource::~PostingSource() { }
    4452
    4553Xapian::weight