Ticket #52: revpostlist.patch

File revpostlist.patch, 22.4 KB (added by Olly Betts, 18 years ago)

Patch to implement this for quartz

  • backends/quartz/quartz_database.cc

    RCS file: /usr/data/cvs/xapian/xapian-core/backends/quartz/quartz_database.cc,v
    retrieving revision 1.145
    diff -p -u -r1.145 quartz_database.cc
    QuartzDatabase::do_open_post_list(const  
    585585                              tname));
    586586}
    587587
     588LeafPostList *
     589QuartzDatabase::do_open_post_list_rev(const string& tname) const
     590{
     591    DEBUGCALL(DB, LeafPostList *, "QuartzDatabase::do_open_post_list_rev",
     592              tname);
     593    Assert(!tname.empty());
     594
     595    Xapian::Internal::RefCntPtr<const QuartzDatabase> ptrtothis(this);
     596    return(new QuartzRevPostList(ptrtothis,
     597                                 &postlist_table,
     598                                 &positionlist_table,
     599                                 tname));
     600}
     601
    588602LeafTermList *
    589603QuartzDatabase::open_term_list(Xapian::docid did) const
    590604{
    QuartzWritableDatabase::do_open_post_lis  
    11021116                              &database_ro.postlist_table,
    11031117                              &database_ro.positionlist_table,
    11041118                              tname));
     1119}
     1120
     1121LeafPostList *
     1122QuartzWritableDatabase::do_open_post_list_rev(const string& tname) const
     1123{
     1124    DEBUGCALL(DB, LeafPostList *, "QuartzWritableDatabase::do_open_post_list_rev", tname);
     1125    Assert(!tname.empty());
     1126
     1127    // Need to flush iff we've got buffered changes to this term's postlist.
     1128    map<string, map<docid, pair<char, termcount> > >::const_iterator j;
     1129    j = mod_plists.find(tname);
     1130    if (j != mod_plists.end()) do_flush_const();
     1131
     1132    Xapian::Internal::RefCntPtr<const QuartzWritableDatabase> ptrtothis(this);
     1133    return(new QuartzRevPostList(ptrtothis,
     1134                                 &database_ro.postlist_table,
     1135                                 &database_ro.positionlist_table,
     1136                                 tname));
    11051137}
    11061138
    11071139LeafTermList *
  • backends/quartz/quartz_database.h

    RCS file: /usr/data/cvs/xapian/xapian-core/backends/quartz/quartz_database.h,v
    retrieving revision 1.78
    diff -p -u -r1.78 quartz_database.h
    class QuartzDatabase : public Xapian::Da  
    210210        bool term_exists(const string & tname) const;
    211211
    212212        LeafPostList * do_open_post_list(const string & tname) const;
     213        LeafPostList * do_open_post_list_rev(const string & tname) const;
    213214        LeafTermList * open_term_list(Xapian::docid did) const;
    214215        Xapian::Document::Internal * open_document(Xapian::docid did, bool lazy = false) const;
    215216        PositionList * open_position_list(Xapian::docid did,
    class QuartzWritableDatabase : public Xa  
    289290        bool term_exists(const string & tname) const;
    290291
    291292        LeafPostList * do_open_post_list(const string & tname) const;
     293        LeafPostList * do_open_post_list_rev(const string & tname) const;
    292294        LeafTermList * open_term_list(Xapian::docid did) const;
    293295        Xapian::Document::Internal * open_document(Xapian::docid did, bool lazy = false) const;
    294296        PositionList * open_position_list(Xapian::docid did,
  • backends/quartz/quartz_postlist.cc

    RCS file: /usr/data/cvs/xapian/xapian-core/backends/quartz/quartz_postlist.cc,v
    retrieving revision 1.82
    diff -p -u -r1.82 quartz_postlist.cc
    PostlistChunkWriter::flush(Btree *table)  
    604604    }
    605605}
    606606
     607/*****************************************************************************/
     608
    607609/** Read the number of entries in the posting list.
    608610 *  This must only be called when *posptr is pointing to the start of
    609611 *  the first chunk of the posting list.
    QuartzPostList::get_description() const  
    913915{
    914916    return tname + ":" + om_tostring(number_of_entries);
    915917}
     918
     919/*****************************************************************************/
     920
     921QuartzRevPostList::QuartzRevPostList(Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> this_db_,
     922                               const Btree * table_,
     923                               const Btree * positiontable_,
     924                               const string & tname_)
     925        : this_db(this_db_),
     926          table(table_),
     927          positiontable(positiontable_),
     928          tname(tname_),
     929          cursor(table->cursor_get()),
     930          is_at_end(false),
     931          have_started(false)
     932{
     933    DEBUGCALL(DB, void, "QuartzRevPostList::QuartzRevPostList",
     934              this_db_.get() << ", " << table_ << ", " <<
     935              positiontable_ << ", " << tname_);
     936    string key;
     937    make_key(tname, key);
     938    int found = cursor->find_entry(key);
     939    if (!found) {
     940        number_of_entries = 0;
     941        collection_freq = 0;
     942        is_at_end = true;
     943        pos = 0;
     944        end = 0;
     945        first_did_in_chunk = 0;
     946        last_did_in_chunk = 0;
     947        return;
     948    }
     949    cursor->read_tag();
     950    pos = cursor->current_tag.data();
     951    end = pos + cursor->current_tag.size();
     952
     953    did = read_start_of_first_chunk(&pos, end,
     954                              &number_of_entries, &collection_freq);
     955    first_did_in_chunk = did;
     956    last_did_in_chunk = read_start_of_chunk(&pos, end, first_did_in_chunk,
     957                                            &is_last_chunk);
     958    read_wdf_and_length(&pos, end, &wdf, &doclength);
     959    if (!is_last_chunk) {
     960        make_key(tname, (Xapian::docid)-1, key);
     961        (void) cursor->find_entry(key);
     962        const char * keypos = cursor->current_key.data();
     963        const char * keyend = keypos + cursor->current_key.size();
     964        if (!check_tname_in_key_lite(&keypos, keyend, tname)) {
     965            throw Xapian::DatabaseCorruptError("Chunk for wrong term");
     966        }
     967
     968        if (!unpack_uint_preserving_sort(&keypos, keyend, &first_did_in_chunk)) {
     969            report_read_error(keypos);
     970        }
     971
     972        cursor->read_tag();
     973        pos = cursor->current_tag.data();
     974        end = pos + cursor->current_tag.size();
     975
     976        last_did_in_chunk = read_start_of_chunk(&pos, end, first_did_in_chunk,
     977                                                &is_last_chunk);
     978        read_wdf_and_length(&pos, end, &wdf, &doclength);
     979    }
     980
     981    buffer.clear();
     982    did = first_did_in_chunk;
     983    while (pos != end) {
     984        buffer.push_back(PLEntry(did, wdf, doclength));
     985        read_did_increase(&pos, end, &did);
     986        read_wdf_and_length(&pos, end, &wdf, &doclength);
     987        // Either not at last doc in chunk, or pos == end, but not both.
     988        Assert(did <= last_did_in_chunk);
     989        Assert(did < last_did_in_chunk || pos == end);
     990        Assert(pos != end || did == last_did_in_chunk);
     991    }
     992}
     993
     994QuartzRevPostList::~QuartzRevPostList()
     995{
     996    DEBUGCALL(DB, void, "QuartzRevPostList::~QuartzRevPostList", "");
     997}
     998
     999bool
     1000QuartzRevPostList::next_in_chunk()
     1001{
     1002    DEBUGCALL(DB, bool, "QuartzRevPostList::next_in_chunk", "");
     1003    if (buffer.empty()) RETURN(false);
     1004
     1005    did = buffer.back().did;
     1006    wdf = buffer.back().wdf;
     1007    doclength = buffer.back().doclength;
     1008    buffer.pop_back();
     1009
     1010    RETURN(true);
     1011}
     1012
     1013void
     1014QuartzRevPostList::next_chunk()
     1015{
     1016    DEBUGCALL(DB, void, "QuartzRevPostList::next_chunk", "");
     1017    if (is_last_chunk) {
     1018        is_at_end = true;
     1019        return;
     1020    }
     1021   
     1022    cursor->prev();
     1023    const char * keypos = cursor->current_key.data();
     1024    const char * keyend = keypos + cursor->current_key.size();
     1025    if (!check_tname_in_key_lite(&keypos, keyend, tname)) {
     1026        throw Xapian::DatabaseCorruptError("Chunk for wrong term");
     1027    }
     1028
     1029    if (keypos == keyend) {
     1030        is_last_chunk = true;
     1031        first_did_in_chunk = read_start_of_first_chunk(&pos, end,
     1032                &number_of_entries, &collection_freq);
     1033    } else {
     1034        if (!unpack_uint_preserving_sort(&keypos, keyend, &first_did_in_chunk)) {
     1035            report_read_error(keypos);
     1036        }
     1037
     1038        cursor->read_tag();
     1039        pos = cursor->current_tag.data();
     1040        end = pos + cursor->current_tag.size();
     1041
     1042        last_did_in_chunk = read_start_of_chunk(&pos, end, first_did_in_chunk,
     1043                                                &is_last_chunk);
     1044    }
     1045    read_wdf_and_length(&pos, end, &wdf, &doclength);
     1046    buffer.clear();
     1047    did = first_did_in_chunk;
     1048    while (pos != end) {
     1049        buffer.push_back(PLEntry(did, wdf, doclength));
     1050        read_did_increase(&pos, end, &did);
     1051        read_wdf_and_length(&pos, end, &wdf, &doclength);
     1052        // Either not at last doc in chunk, or pos == end, but not both.
     1053        Assert(did <= last_did_in_chunk);
     1054        Assert(did < last_did_in_chunk || pos == end);
     1055        Assert(pos != end || did == last_did_in_chunk);
     1056    }
     1057}
     1058
     1059PositionList *
     1060QuartzRevPostList::read_position_list()
     1061{
     1062    DEBUGCALL(DB, PositionList *, "QuartzRevPostList::read_position_list", "");
     1063
     1064    positionlist.read_data(positiontable, did, tname);
     1065
     1066    RETURN(&positionlist);
     1067}
     1068
     1069PositionList *
     1070QuartzRevPostList::open_position_list() const
     1071{
     1072    DEBUGCALL(DB, PositionList *, "QuartzRevPostList::open_position_list", "");
     1073
     1074    AutoPtr<QuartzPositionList> poslist(new QuartzPositionList());
     1075    poslist->read_data(positiontable, did, tname);
     1076
     1077    RETURN(poslist.release());
     1078}
     1079
     1080PostList *
     1081QuartzRevPostList::next(Xapian::weight w_min)
     1082{
     1083    DEBUGCALL(DB, PostList *, "QuartzRevPostList::next", w_min);
     1084    (void)w_min; // no warning
     1085
     1086    if (!have_started) {
     1087        have_started = true;
     1088    } else {
     1089        if (!next_in_chunk()) next_chunk();
     1090    }
     1091
     1092    DEBUGLINE(DB, string("Moved to ") <<
     1093              (is_at_end ? string("end.") : string("docid, wdf, doclength = ") +
     1094               om_tostring(did) + ", " + om_tostring(wdf) + ", " +
     1095               om_tostring(doclength)));
     1096
     1097    RETURN(NULL);
     1098}
     1099
     1100bool
     1101QuartzRevPostList::current_chunk_contains(Xapian::docid desired_did)
     1102{
     1103    DEBUGCALL(DB, bool, "QuartzRevPostList::current_chunk_contains", desired_did);
     1104    if (desired_did >= first_did_in_chunk &&
     1105        desired_did <= last_did_in_chunk) {
     1106        RETURN(true);
     1107    }
     1108    RETURN(false);
     1109}
     1110
     1111void
     1112QuartzRevPostList::move_to_chunk_containing(Xapian::docid desired_did)
     1113{
     1114    DEBUGCALL(DB, void,
     1115              "QuartzRevPostList::move_to_chunk_containing", desired_did);
     1116    string key;
     1117    make_key(tname, desired_did, key);
     1118    (void) cursor->find_entry(key);
     1119    Assert(!cursor->after_end());
     1120
     1121    const char * keypos = cursor->current_key.data();
     1122    const char * keyend = keypos + cursor->current_key.size();
     1123    // Check we're still in same postlist
     1124    if (!check_tname_in_key_lite(&keypos, keyend, tname)) {
     1125        // This should only happen if the postlist doesn't exist at all.
     1126        is_at_end = true;
     1127        is_last_chunk = true;
     1128        return;
     1129    }
     1130    is_at_end = false;
     1131
     1132    cursor->read_tag();
     1133    pos = cursor->current_tag.data();
     1134    end = pos + cursor->current_tag.size();
     1135
     1136    if (keypos == keyend) {
     1137        // In first chunk
     1138#ifdef XAPIAN_DEBUG
     1139        Xapian::termcount old_number_of_entries = number_of_entries;
     1140        Xapian::termcount old_collection_freq = collection_freq;
     1141        first_did_in_chunk = read_start_of_first_chunk(&pos, end, &number_of_entries,
     1142                                        &collection_freq);
     1143        Assert(old_number_of_entries == number_of_entries);
     1144        Assert(old_collection_freq == collection_freq);
     1145#else
     1146        first_did_in_chunk = read_start_of_first_chunk(&pos, end, 0, 0);
     1147#endif
     1148    } else {
     1149        // In normal chunk
     1150        if (!unpack_uint_preserving_sort(&keypos, keyend, &first_did_in_chunk)) {
     1151            report_read_error(keypos);
     1152        }
     1153    }
     1154
     1155    last_did_in_chunk = read_start_of_chunk(&pos, end, first_did_in_chunk,
     1156                                            &is_last_chunk);
     1157    read_wdf_and_length(&pos, end, &wdf, &doclength);
     1158    buffer.clear();
     1159    did = first_did_in_chunk;
     1160    while (pos != end) {
     1161        buffer.push_back(PLEntry(did, wdf, doclength));
     1162        read_did_increase(&pos, end, &did);
     1163        read_wdf_and_length(&pos, end, &wdf, &doclength);
     1164        // Either not at last doc in chunk, or pos == end, but not both.
     1165        Assert(did <= last_did_in_chunk);
     1166        Assert(did < last_did_in_chunk || pos == end);
     1167        Assert(pos != end || did == last_did_in_chunk);
     1168    }
     1169}
     1170
     1171bool
     1172QuartzRevPostList::move_forward_in_chunk_to_at_least(Xapian::docid desired_did)
     1173{
     1174    DEBUGCALL(DB, bool,
     1175              "QuartzRevPostList::move_forward_in_chunk_to_at_least", desired_did);
     1176    if (desired_did > last_did_in_chunk) {
     1177        pos = end;
     1178        RETURN(false);
     1179    }
     1180    while (did < desired_did) {
     1181        // FIXME: perhaps we don't need to decode the wdf and document length
     1182        // for documents we're skipping past.
     1183        bool at_end_of_chunk = !next_in_chunk();
     1184        if (at_end_of_chunk) RETURN(false);
     1185    }
     1186    RETURN(true);
     1187}
     1188
     1189PostList *
     1190QuartzRevPostList::skip_to(Xapian::docid desired_did, Xapian::weight w_min)
     1191{
     1192    DEBUGCALL(DB, PostList *,
     1193              "QuartzRevPostList::skip_to", desired_did << ", " << w_min);
     1194    (void)w_min; // no warning
     1195    // We've started now - if we hadn't already, we're already positioned
     1196    // at start so there's no need to actually do anything.
     1197    have_started = true;
     1198
     1199    // Don't skip back, and don't need to do anything if already there.
     1200    if (desired_did <= did) RETURN(NULL);
     1201
     1202    // Move to correct chunk
     1203    if (!current_chunk_contains(desired_did)) {
     1204        move_to_chunk_containing(desired_did);
     1205        // Might be at_end now - this is why we need the test before moving
     1206        // forward in chunk.
     1207    }
     1208
     1209    // Move to correct position in chunk
     1210    if (!is_at_end) {
     1211#ifdef XAPIAN_DEBUG
     1212        bool have_document =
     1213#else
     1214                (void)
     1215#endif
     1216                move_forward_in_chunk_to_at_least(desired_did);
     1217        Assert(have_document);
     1218    }
     1219
     1220    DEBUGLINE(DB, string("Skipped to ") <<
     1221              (is_at_end ? string("end.") : string("docid, wdf, doclength = ") +
     1222               om_tostring(did) + ", " + om_tostring(wdf) + ", " +
     1223               om_tostring(doclength) + "."));
     1224
     1225    RETURN(NULL);
     1226}
     1227
     1228string
     1229QuartzRevPostList::get_description() const
     1230{
     1231    return tname + ":" + om_tostring(number_of_entries);
     1232}
     1233
     1234/*****************************************************************************/
    9161235
    9171236// Returns the last did to allow in this chunk.
    9181237Xapian::docid
  • backends/quartz/quartz_postlist.h

    RCS file: /usr/data/cvs/xapian/xapian-core/backends/quartz/quartz_postlist.h,v
    retrieving revision 1.33
    diff -p -u -r1.33 quartz_postlist.h
    class QuartzPostList : public LeafPostLi  
    247247                                           Xapian::termcount * collection_freq_ptr);
    248248};
    249249
     250/** A postlist in a quartz database.
     251 */
     252class QuartzRevPostList : public LeafPostList {
     253    private:
     254        /** The database we are searching.  This pointer is held so that the
     255         *  database doesn't get deleted before us.
     256         */
     257        Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> this_db;
     258
     259        /// The table containing the postlist.
     260        const Btree * table;
     261
     262        /// The table containing positionlists.
     263        const Btree * positiontable;
     264
     265        /// The termname for this postlist.
     266        string tname;
     267
     268        /// Cursor pointing to current chunk of postlist.
     269        AutoPtr<Bcursor> cursor;
     270
     271        /// True if this is the last chunk.
     272        bool is_last_chunk;
     273
     274        /// The first document id in this chunk.
     275        Xapian::docid first_did_in_chunk;
     276
     277        /// The last document id in this chunk.
     278        Xapian::docid last_did_in_chunk;
     279
     280        /// Position of iteration through current chunk.
     281        const char * pos;
     282
     283        /// Pointer to byte after end of current chunk.
     284        const char * end;
     285
     286        /// Document id we're currently at.
     287        Xapian::docid did;
     288
     289        /// The (absolute) length of the current document.
     290        quartz_doclen_t doclength;
     291
     292        /// The wdf of the current document.
     293        Xapian::termcount wdf;
     294
     295        /// Whether we've run off the end of the list yet.
     296        bool is_at_end;
     297
     298        /// Whether we've started reading the list yet.
     299        bool have_started;
     300
     301        /// The number of entries in the posting list.
     302        Xapian::doccount number_of_entries;
     303
     304        /// The number of occurrences of the term in the posting list.
     305        Xapian::termcount collection_freq;
     306
     307        /// The position list object for this posting list.
     308        QuartzPositionList positionlist;
     309
     310        struct PLEntry {
     311            Xapian::docid did;
     312            Xapian::doccount wdf;
     313            Xapian::termcount doclength;
     314            PLEntry(Xapian::docid did_, Xapian::termcount wdf_, quartz_doclen_t doclength_) : did(did_), wdf(wdf_), doclength(doclength_) { }
     315        };
     316
     317        vector<PLEntry> buffer;
     318
     319        /// Copying is not allowed.
     320        QuartzRevPostList(const QuartzRevPostList &);
     321
     322        /// Assignment is not allowed.
     323        void operator=(const QuartzRevPostList &);
     324
     325        /** Move to the next item in the chunk, if possible.
     326         *  If already at the end of the chunk, returns false.
     327         */
     328        bool next_in_chunk();
     329
     330        /** Move to the next chunk.
     331         *
     332         *  If there are no more chunks in this postlist, this will set
     333         *  is_at_end to true.
     334         */
     335        void next_chunk();
     336
     337        /** Return true if the given document ID lies in the range covered
     338         *  by the current chunk.  This does not say whether the document ID
     339         *  is actually present.  It will return false if the document ID
     340         *  is greater than the last document ID in the chunk, even if it is
     341         *  less than the first document ID in the next chunk: it is possible
     342         *  for no chunk to contain a particular document ID.
     343         */
     344        bool current_chunk_contains(Xapian::docid desired_did);
     345
     346        /** Move to chunk containing the specified document ID.
     347         *
     348         *  This moves to the chunk whose starting document ID is
     349         *  <= desired_did, but such that the next chunk's starting
     350         *  document ID is > desired_did.
     351         *
     352         *  It is thus possible that current_chunk_contains(desired_did)
     353         *  will return false after this call, since the document ID
     354         *  might lie after the end of this chunk, but before the start
     355         *  of the next chunk.
     356         */
     357        void move_to_chunk_containing(Xapian::docid desired_did);
     358
     359        /** Scan forward in the current chunk for the specified document ID.
     360         *
     361         *  This is particularly efficient if the desired document ID is
     362         *  greater than the last in the chunk - it then skips straight
     363         *  to the end.
     364         *
     365         *  @return true if we moved to a valid document,
     366         *          false if we reached the end of the chunk.
     367         */
     368        bool move_forward_in_chunk_to_at_least(Xapian::docid desired_did);
     369
     370    public:
     371        /// Default constructor.
     372        QuartzRevPostList(Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> this_db_,
     373                       const Btree * table_,
     374                       const Btree * positiontable_,
     375                       const string & tname);
     376
     377        /// Destructor.
     378        ~QuartzRevPostList();
     379
     380        /** Returns number of docs indexed by this term.
     381         *
     382         *  This is the length of the postlist.
     383         */
     384        Xapian::doccount get_termfreq() const { return number_of_entries; }
     385
     386        /** Returns the number of occurrences of the term in the database.
     387         *
     388         *  This is the sum of the wdfs in the postlist.
     389         */
     390        Xapian::termcount get_collection_freq() const { return collection_freq; }
     391
     392        /// Returns the current docid.
     393        Xapian::docid get_docid() const { Assert(have_started); return did; }
     394
     395        /// Returns the length of current document.
     396        Xapian::doclength get_doclength() const {
     397            Assert(have_started);
     398            return static_cast<Xapian::doclength>(doclength);
     399        }
     400
     401        /** Returns the Within Document Frequency of the term in the current
     402         *  document.
     403         */
     404        Xapian::termcount get_wdf() const { Assert(have_started); return wdf; }
     405
     406        /** Get the list of positions of the term in the current document.
     407         */
     408        PositionList *read_position_list();
     409
     410        /** Get the list of positions of the term in the current document.
     411         */
     412        PositionList * open_position_list() const;
     413
     414        /// Move to the next document.
     415        PostList * next(Xapian::weight w_min);
     416
     417        /// Skip to next document with docid >= docid.
     418        PostList * skip_to(Xapian::docid desired_did, Xapian::weight w_min);
     419
     420        /// Return true if and only if we're off the end of the list.
     421        bool at_end() const { return is_at_end; }
     422
     423        /// Get a description of the document.
     424        std::string get_description() const;
     425};
     426
    250427#endif /* OM_HGUARD_QUARTZ_POSTLIST_H */
  • common/database.h

    RCS file: /usr/data/cvs/xapian/xapian-core/common/database.h,v
    retrieving revision 1.138
    diff -p -u -r1.138 database.h
    class Database::Internal : public Xapian  
    8989         *                use.
    9090         */
    9191        virtual LeafPostList * do_open_post_list(const string & tname) const = 0;
     92        virtual LeafPostList * do_open_post_list_rev(const string & tname) const = 0;
    9293
    9394    public:
    9495        /** Destroy the database.
    class Database::Internal : public Xapian  
    189190         *                This object must be deleted by the caller after
    190191         *                use.
    191192         */
    192         LeafPostList * open_post_list(const string & tname) const {
     193        LeafPostList * open_post_list(const string & tname, bool rev = false) const {
    193194            if (!term_exists(tname)) {
    194195                DEBUGLINE(MATCH, tname + " is not in database.");
    195196                // Term doesn't exist in this database.  However, we create
    class Database::Internal : public Xapian  
    197198                // cleaner (term might exist in other databases).
    198199                return new EmptyPostList();
    199200            }
    200             return do_open_post_list(tname);
     201            return rev ? do_open_post_list_rev(tname) : do_open_post_list(tname);
    201202        }
    202203
    203204        /** Open a term list.
  • common/multimatch.h

    RCS file: /usr/data/cvs/xapian/xapian-core/common/multimatch.h,v
    retrieving revision 1.75
    diff -p -u -r1.75 multimatch.h
    class MultiMatch  
    143143         *  and the maxweight now possible is smaller.
    144144         */
    145145        void recalc_maxweight();
     146
     147        /** Called by LocalSubMatch to find out the sort direction so it
     148         * can decide whether to use reverse postlists or not.
     149         */
     150        bool get_sort_forward() const { return sort_forward; }
    146151};
    147152
    148153#endif /* OM_HGUARD_MULTIMATCH_H */
  • matcher/localmatch.cc

    RCS file: /usr/data/cvs/xapian/xapian-core/matcher/localmatch.cc,v
    retrieving revision 1.119
    diff -p -u -r1.119 localmatch.cc
    LocalSubMatch::postlist_from_query(const  
    410410            }
    411411
    412412            // MULTI
    413             LeafPostList * pl = db->open_post_list(query->tname);
     413            LeafPostList * pl;
     414            pl = db->open_post_list(query->tname, !matcher->get_sort_forward());
    414415            pl->set_termweight(wt);
    415416            RETURN(pl);
    416417        }
  • matcher/multimatch.cc

    RCS file: /usr/data/cvs/xapian/xapian-core/matcher/multimatch.cc,v
    retrieving revision 1.171
    diff -p -u -r1.171 multimatch.cc
    MultiMatch::get_mset(Xapian::doccount fi  
    738738                if (!sort_bands && items.size() == max_msize) {
    739739                    // We're done if this is a forward boolean match
    740740                    // (bodgetastic, FIXME better if we can)
    741                     if (max_weight == 0 && sort_forward) break;
     741                    if (max_weight == 0) break;
    742742                }
    743743            }
    744744        }