00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "mergepostlist.h"
00026
00027 #include "multimatch.h"
00028 #include "emptypostlist.h"
00029 #include "branchpostlist.h"
00030 #include "debuglog.h"
00031 #include "omassert.h"
00032 #include "valuestreamdocument.h"
00033 #include "xapian/errorhandler.h"
00034
00035
00036
00037 MergePostList::~MergePostList()
00038 {
00039 LOGCALL_VOID(MATCH, "MergePostList::~MergePostList", NO_ARGS);
00040 std::vector<PostList *>::const_iterator i;
00041 for (i = plists.begin(); i != plists.end(); ++i) {
00042 delete *i;
00043 }
00044 }
00045
00046 PostList *
00047 MergePostList::next(Xapian::weight w_min)
00048 {
00049 LOGCALL(MATCH, PostList *, "MergePostList::next", w_min);
00050 LOGVALUE(MATCH, current);
00051 if (current == -1) current = 0;
00052 while (true) {
00053
00054
00055 try {
00056 next_handling_prune(plists[current], w_min, matcher);
00057 if (!plists[current]->at_end()) break;
00058 ++current;
00059 if (unsigned(current) >= plists.size()) break;
00060 vsdoc.new_subdb(current);
00061 } catch (Xapian::Error & e) {
00062 if (errorhandler) {
00063 LOGLINE(EXCEPTION, "Calling error handler in MergePostList::next().");
00064 (*errorhandler)(e);
00065
00066 delete plists[current];
00067 plists[current] = new EmptyPostList;
00068 } else {
00069 throw;
00070 }
00071 }
00072 if (matcher) matcher->recalc_maxweight();
00073 }
00074 LOGVALUE(MATCH, current);
00075 RETURN(NULL);
00076 }
00077
00078 PostList *
00079 MergePostList::skip_to(Xapian::docid did, Xapian::weight w_min)
00080 {
00081 LOGCALL(MATCH, PostList *, "MergePostList::skip_to", did | w_min);
00082 (void)did;
00083 (void)w_min;
00084
00085
00086 throw Xapian::InvalidOperationError("MergePostList doesn't support skip_to");
00087 }
00088
00089 Xapian::termcount
00090 MergePostList::get_wdf() const
00091 {
00092 LOGCALL(MATCH, Xapian::termcount, "MergePostList::get_wdf", NO_ARGS);
00093 RETURN(plists[current]->get_wdf());
00094 }
00095
00096 Xapian::doccount
00097 MergePostList::get_termfreq_max() const
00098 {
00099 LOGCALL(MATCH, Xapian::doccount, "MergePostList::get_termfreq_max", NO_ARGS);
00100
00101 Xapian::doccount total = 0;
00102 vector<PostList *>::const_iterator i;
00103 for (i = plists.begin(); i != plists.end(); ++i) {
00104 total += (*i)->get_termfreq_max();
00105 }
00106 return total;
00107 }
00108
00109 Xapian::doccount
00110 MergePostList::get_termfreq_min() const
00111 {
00112 LOGCALL(MATCH, Xapian::doccount, "MergePostList::get_termfreq_min", NO_ARGS);
00113
00114 Xapian::doccount total = 0;
00115 vector<PostList *>::const_iterator i;
00116 for (i = plists.begin(); i != plists.end(); ++i) {
00117 total += (*i)->get_termfreq_min();
00118 }
00119 return total;
00120 }
00121
00122 Xapian::doccount
00123 MergePostList::get_termfreq_est() const
00124 {
00125 LOGCALL(MATCH, Xapian::doccount, "MergePostList::get_termfreq_est", NO_ARGS);
00126
00127 Xapian::doccount total = 0;
00128 vector<PostList *>::const_iterator i;
00129 for (i = plists.begin(); i != plists.end(); ++i) {
00130 total += (*i)->get_termfreq_est();
00131 }
00132 return total;
00133 }
00134
00135 Xapian::docid
00136 MergePostList::get_docid() const
00137 {
00138 LOGCALL(MATCH, Xapian::docid, "MergePostList::get_docid", NO_ARGS);
00139 Assert(current != -1);
00140
00141
00142 RETURN((plists[current]->get_docid() - 1) * plists.size() + current + 1);
00143 }
00144
00145 Xapian::weight
00146 MergePostList::get_weight() const
00147 {
00148 LOGCALL(MATCH, Xapian::weight, "MergePostList::get_weight", NO_ARGS);
00149 Assert(current != -1);
00150 return plists[current]->get_weight();
00151 }
00152
00153 const string *
00154 MergePostList::get_collapse_key() const
00155 {
00156 LOGCALL(MATCH, string *, "MergePostList::get_collapse_key", NO_ARGS);
00157 Assert(current != -1);
00158 return plists[current]->get_collapse_key();
00159 }
00160
00161 Xapian::weight
00162 MergePostList::get_maxweight() const
00163 {
00164 LOGCALL(MATCH, Xapian::weight, "MergePostList::get_maxweight", NO_ARGS);
00165 return w_max;
00166 }
00167
00168 Xapian::weight
00169 MergePostList::recalc_maxweight()
00170 {
00171 LOGCALL(MATCH, Xapian::weight, "MergePostList::recalc_maxweight", NO_ARGS);
00172 w_max = 0;
00173 vector<PostList *>::iterator i;
00174 for (i = plists.begin(); i != plists.end(); ++i) {
00175 try {
00176 Xapian::weight w = (*i)->recalc_maxweight();
00177 if (w > w_max) w_max = w;
00178 } catch (Xapian::Error & e) {
00179 if (errorhandler) {
00180 LOGLINE(EXCEPTION, "Calling error handler in MergePostList::recalc_maxweight().");
00181 (*errorhandler)(e);
00182
00183 if (current == i - plists.begin()) {
00184
00185 throw;
00186 }
00187
00188 delete (*i);
00189 *i = new EmptyPostList;
00190 } else {
00191 throw;
00192 }
00193 }
00194 }
00195 return w_max;
00196 }
00197
00198 bool
00199 MergePostList::at_end() const
00200 {
00201 LOGCALL(MATCH, bool, "MergePostList::at_end", NO_ARGS);
00202 Assert(current != -1);
00203 return unsigned(current) >= plists.size();
00204 }
00205
00206 string
00207 MergePostList::get_description() const
00208 {
00209 string desc = "( Merge ";
00210 vector<PostList *>::const_iterator i;
00211 for (i = plists.begin(); i != plists.end(); ++i) {
00212 desc += (*i)->get_description() + " ";
00213 }
00214 return desc + ")";
00215 }
00216
00217 Xapian::termcount
00218 MergePostList::get_doclength() const
00219 {
00220 LOGCALL(MATCH, Xapian::termcount, "MergePostList::get_doclength", NO_ARGS);
00221 Assert(current != -1);
00222 return plists[current]->get_doclength();
00223 }
00224
00225 Xapian::termcount
00226 MergePostList::count_matching_subqs() const
00227 {
00228 LOGCALL(MATCH, Xapian::termcount, "MergePostList::count_matching_subqs", NO_ARGS);
00229 RETURN(plists[current]->count_matching_subqs());
00230 }