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
00024 #include "multi_postlist.h"
00025
00026 #include "debuglog.h"
00027 #include "omassert.h"
00028 #include "utils.h"
00029
00030 #ifdef XAPIAN_ASSERTIONS_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_min() const
00056 {
00057
00058 Assert(false);
00059 return 0;
00060 }
00061
00062 Xapian::doccount
00063 MultiPostList::get_termfreq_max() const
00064 {
00065 return MultiPostList::get_termfreq_min();
00066 }
00067
00068 Xapian::doccount
00069 MultiPostList::get_termfreq_est() const
00070 {
00071 return MultiPostList::get_termfreq_min();
00072 }
00073
00074 Xapian::weight
00075 MultiPostList::get_maxweight() const
00076 {
00077 return MultiPostList::get_weight();
00078 }
00079
00080 Xapian::weight
00081 MultiPostList::get_weight() const
00082 {
00083
00084 Assert(false);
00085 return 0;
00086 }
00087
00088 Xapian::weight
00089 MultiPostList::recalc_maxweight()
00090 {
00091 return MultiPostList::get_weight();
00092 }
00093
00094 Xapian::docid
00095 MultiPostList::get_docid() const
00096 {
00097 LOGCALL(DB, Xapian::docid, "MultiPostList::get_docid", NO_ARGS);
00098 Assert(!at_end());
00099 Assert(currdoc != 0);
00100 RETURN(currdoc);
00101 }
00102
00103 Xapian::termcount
00104 MultiPostList::get_doclength() const
00105 {
00106 LOGCALL(DB, Xapian::termcount, "MultiPostList::get_doclength", NO_ARGS);
00107 Assert(!at_end());
00108 Assert(currdoc != 0);
00109 Xapian::termcount result = postlists[(currdoc - 1) % multiplier]->get_doclength();
00110 AssertEqParanoid(result, this_db.get_doclength(get_docid()));
00111 RETURN(result);
00112 }
00113
00114 Xapian::termcount
00115 MultiPostList::get_wdf() const
00116 {
00117 return postlists[(currdoc - 1) % multiplier]->get_wdf();
00118 }
00119
00120 PositionList *
00121 MultiPostList::open_position_list() const
00122 {
00123 return postlists[(currdoc - 1) % multiplier]->open_position_list();
00124 }
00125
00126 PostList *
00127 MultiPostList::next(Xapian::weight w_min)
00128 {
00129 LOGCALL(DB, PostList *, "MultiPostList::next", w_min);
00130 Assert(!at_end());
00131
00132 Xapian::docid newdoc = 0;
00133 Xapian::docid offset = 1;
00134 std::vector<LeafPostList *>::iterator i;
00135 for (i = postlists.begin(); i != postlists.end(); i++) {
00136 if (!(*i)->at_end()) {
00137 Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00138
00139 if (currdoc >= id) {
00140 (*i)->next(w_min);
00141 if (!(*i)->at_end()) {
00142 id = ((*i)->get_docid() - 1) * multiplier + offset;
00143 if (newdoc == 0 || id < newdoc) newdoc = id;
00144 }
00145 } else {
00146 if (newdoc == 0 || id < newdoc) newdoc = id;
00147 }
00148 }
00149 offset++;
00150 }
00151 if (newdoc) {
00152 LOGLINE(DB, "MultiPostList::next() newdoc=" << newdoc <<
00153 " (olddoc=" << currdoc << ")");
00154 currdoc = newdoc;
00155 } else {
00156 LOGLINE(DB, "MultiPostList::next() finished" <<
00157 " (olddoc=" << currdoc << ")");
00158 finished = true;
00159 }
00160 RETURN(NULL);
00161 }
00162
00163 PostList *
00164 MultiPostList::skip_to(Xapian::docid did, Xapian::weight w_min)
00165 {
00166 LOGCALL(DB, PostList *, "MultiPostList::skip_to", did | w_min);
00167 Assert(!at_end());
00168 Xapian::docid newdoc = 0;
00169 Xapian::docid offset = 0;
00170 Xapian::docid realdid = (did - 1) / multiplier + 2;
00171 Xapian::doccount dbnumber = (did - 1) % multiplier;
00172 std::vector<LeafPostList *>::iterator i;
00173 for (i = postlists.begin(); i != postlists.end(); i++) {
00174 if (offset == dbnumber) --realdid;
00175 ++offset;
00176 Assert((realdid - 1) * multiplier + offset >= did);
00177 Assert((realdid - 1) * multiplier + offset < did + multiplier);
00178 if (!(*i)->at_end()) {
00179 (*i)->skip_to(realdid, w_min);
00180 if (!(*i)->at_end()) {
00181 Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00182 if (newdoc == 0 || id < newdoc) newdoc = id;
00183 }
00184 }
00185 }
00186 if (newdoc) {
00187 currdoc = newdoc;
00188 } else {
00189 finished = true;
00190 }
00191 RETURN(NULL);
00192 }
00193
00194 bool
00195 MultiPostList::at_end() const
00196 {
00197 return finished;
00198 }
00199
00200 std::string
00201 MultiPostList::get_description() const
00202 {
00203 std::string desc;
00204
00205 std::vector<LeafPostList *>::const_iterator i;
00206 for (i = postlists.begin(); i != postlists.end(); i++) {
00207 if (!desc.empty()) desc += ',';
00208 desc += (*i)->get_description();
00209 }
00210
00211 return desc;
00212 }