00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023 #include <stdio.h>
00024
00025 #include "omassert.h"
00026 #include "omdebug.h"
00027 #include "multi_postlist.h"
00028 #include "utils.h"
00029
00030 #ifdef XAPIAN_DEBUG_PARANOID
00031 #include "xapian/database.h"
00032 #endif
00033
00034 MultiPostList::MultiPostList(std::vector<LeafPostList *> & pls,
00035 const Xapian::Database &this_db_)
00036 : postlists(pls),
00037 this_db(this_db_),
00038 finished(false),
00039 currdoc(0)
00040 {
00041 multiplier = pls.size();
00042 }
00043
00044
00045 MultiPostList::~MultiPostList()
00046 {
00047 std::vector<LeafPostList *>::iterator i;
00048 for (i = postlists.begin(); i != postlists.end(); i++) {
00049 delete *i;
00050 }
00051 postlists.clear();
00052 }
00053
00054 Xapian::doccount
00055 MultiPostList::get_termfreq() const
00056 {
00057
00058 Assert(false);
00059 return 0;
00060 }
00061
00062 Xapian::docid
00063 MultiPostList::get_docid() const
00064 {
00065 DEBUGCALL(DB, Xapian::docid, "MultiPostList::get_docid", "");
00066 Assert(!at_end());
00067 Assert(currdoc != 0);
00068 RETURN(currdoc);
00069 }
00070
00071 Xapian::doclength
00072 MultiPostList::get_doclength() const
00073 {
00074 DEBUGCALL(DB, Xapian::doclength, "MultiPostList::get_doclength", "");
00075 Assert(!at_end());
00076 Assert(currdoc != 0);
00077 Xapian::doclength result = postlists[(currdoc - 1) % multiplier]->get_doclength();
00078 AssertEqParanoid(result, this_db.get_doclength(get_docid()));
00079 RETURN(result);
00080 }
00081
00082 Xapian::termcount
00083 MultiPostList::get_wdf() const
00084 {
00085 return postlists[(currdoc - 1) % multiplier]->get_wdf();
00086 }
00087
00088 PositionList *
00089 MultiPostList::open_position_list() const
00090 {
00091 return postlists[(currdoc - 1) % multiplier]->open_position_list();
00092 }
00093
00094 PostList *
00095 MultiPostList::next(Xapian::weight w_min)
00096 {
00097 DEBUGCALL(DB, PostList *, "MultiPostList::next", w_min);
00098 Assert(!at_end());
00099
00100 Xapian::docid newdoc = 0;
00101 Xapian::docid offset = 1;
00102 std::vector<LeafPostList *>::iterator i;
00103 for (i = postlists.begin(); i != postlists.end(); i++) {
00104 if (!(*i)->at_end()) {
00105 Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00106
00107 if (currdoc >= id) {
00108 (*i)->next(w_min);
00109 if (!(*i)->at_end()) {
00110 id = ((*i)->get_docid() - 1) * multiplier + offset;
00111 if (newdoc == 0 || id < newdoc) newdoc = id;
00112 }
00113 } else {
00114 if (newdoc == 0 || id < newdoc) newdoc = id;
00115 }
00116 }
00117 offset++;
00118 }
00119 if (newdoc) {
00120 DEBUGLINE(DB, "MultiPostList::next() newdoc=" << newdoc <<
00121 " (olddoc=" << currdoc << ")");
00122 currdoc = newdoc;
00123 } else {
00124 DEBUGLINE(DB, "MultiPostList::next() finished" <<
00125 " (olddoc=" << currdoc << ")");
00126 finished = true;
00127 }
00128 RETURN(NULL);
00129 }
00130
00131 PostList *
00132 MultiPostList::skip_to(Xapian::docid did, Xapian::weight w_min)
00133 {
00134 DEBUGCALL(DB, PostList *, "MultiPostList::skip_to", did << ", " << w_min);
00135 Assert(!at_end());
00136 Xapian::docid newdoc = 0;
00137 Xapian::docid offset = 0;
00138 Xapian::docid realdid = (did - 1) / multiplier + 2;
00139 Xapian::doccount dbnumber = (did - 1) % multiplier;
00140 std::vector<LeafPostList *>::iterator i;
00141 for (i = postlists.begin(); i != postlists.end(); i++) {
00142 if (offset == dbnumber) --realdid;
00143 ++offset;
00144 Assert((realdid - 1) * multiplier + offset >= did);
00145 Assert((realdid - 1) * multiplier + offset < did + multiplier);
00146 if (!(*i)->at_end()) {
00147 (*i)->skip_to(realdid, w_min);
00148 if (!(*i)->at_end()) {
00149 Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00150 if (newdoc == 0 || id < newdoc) newdoc = id;
00151 }
00152 }
00153 }
00154 if (newdoc) {
00155 currdoc = newdoc;
00156 } else {
00157 finished = true;
00158 }
00159 RETURN(NULL);
00160 }
00161
00162 bool
00163 MultiPostList::at_end() const
00164 {
00165 return finished;
00166 }
00167
00168 std::string
00169 MultiPostList::get_description() const
00170 {
00171 std::string desc;
00172
00173 std::vector<LeafPostList *>::const_iterator i;
00174 for (i = postlists.begin(); i != postlists.end(); i++) {
00175 if (!desc.empty()) desc += ',';
00176 desc += (*i)->get_description();
00177 }
00178
00179 return desc;
00180 }