00001
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 "multiandpostlist.h"
00025 #include "omassert.h"
00026 #include "debuglog.h"
00027
00028 void
00029 MultiAndPostList::allocate_plist_and_max_wt()
00030 {
00031 plist = new PostList * [n_kids];
00032 try {
00033 max_wt = new Xapian::weight [n_kids];
00034 } catch (...) {
00035 delete [] plist;
00036 plist = NULL;
00037 throw;
00038 }
00039 }
00040
00041 MultiAndPostList::~MultiAndPostList()
00042 {
00043 if (plist) {
00044 for (size_t i = 0; i < n_kids; ++i) {
00045 delete plist[i];
00046 }
00047 delete [] plist;
00048 }
00049 delete [] max_wt;
00050 }
00051
00052 Xapian::doccount
00053 MultiAndPostList::get_termfreq_min() const
00054 {
00055
00056
00057
00058 Xapian::doccount sum = plist[0]->get_termfreq_min();
00059 if (sum) {
00060 for (size_t i = 1; i < n_kids; ++i) {
00061 Xapian::doccount sum_old = sum;
00062 sum += plist[i]->get_termfreq_min();
00063
00064
00065
00066 if (sum >= sum_old && sum <= db_size) {
00067
00068 return 0;
00069 }
00070 sum -= db_size;
00071 }
00072 AssertRelParanoid(sum,<=,MultiAndPostList::get_termfreq_est());
00073 }
00074 return sum;
00075 }
00076
00077 Xapian::doccount
00078 MultiAndPostList::get_termfreq_max() const
00079 {
00080
00081 Xapian::doccount result = plist[0]->get_termfreq_max();
00082 for (size_t i = 1; i < n_kids; ++i) {
00083 Xapian::doccount tf = plist[i]->get_termfreq_max();
00084 if (tf < result) result = tf;
00085 }
00086 return result;
00087 }
00088
00089 Xapian::doccount
00090 MultiAndPostList::get_termfreq_est() const
00091 {
00092 if (rare(db_size == 0))
00093 RETURN(0);
00094
00095
00096
00097 double result(plist[0]->get_termfreq_est());
00098 for (size_t i = 1; i < n_kids; ++i) {
00099 result = (result * plist[i]->get_termfreq_est()) / db_size;
00100 }
00101 return static_cast<Xapian::doccount>(result + 0.5);
00102 }
00103
00104 TermFreqs
00105 MultiAndPostList::get_termfreq_est_using_stats(
00106 const Xapian::Weight::Internal & stats) const
00107 {
00108 LOGCALL(MATCH, TermFreqs, "MultiAndPostList::get_termfreq_est_using_stats", stats);
00109
00110
00111
00112 TermFreqs freqs(plist[0]->get_termfreq_est_using_stats(stats));
00113
00114 double freqest = double(freqs.termfreq);
00115 double relfreqest = double(freqs.reltermfreq);
00116
00117
00118 Assert(stats.collection_size);
00119
00120 for (size_t i = 1; i < n_kids; ++i) {
00121 freqs = plist[i]->get_termfreq_est_using_stats(stats);
00122
00123
00124
00125 freqest = (freqest * freqs.termfreq) / stats.collection_size;
00126
00127
00128
00129 if (stats.rset_size != 0)
00130 relfreqest = (relfreqest * freqs.reltermfreq) / stats.rset_size;
00131 }
00132
00133 RETURN(TermFreqs(static_cast<Xapian::doccount>(freqest + 0.5),
00134 static_cast<Xapian::doccount>(relfreqest + 0.5)));
00135 }
00136
00137 Xapian::weight
00138 MultiAndPostList::get_maxweight() const
00139 {
00140 return max_total;
00141 }
00142
00143 Xapian::docid
00144 MultiAndPostList::get_docid() const
00145 {
00146 return did;
00147 }
00148
00149 Xapian::termcount
00150 MultiAndPostList::get_doclength() const
00151 {
00152 Assert(did);
00153 Xapian::termcount doclength = plist[0]->get_doclength();
00154 for (size_t i = 1; i < n_kids; ++i) {
00155 AssertEq(doclength, plist[i]->get_doclength());
00156 }
00157 return doclength;
00158 }
00159
00160 Xapian::weight
00161 MultiAndPostList::get_weight() const
00162 {
00163 Assert(did);
00164 Xapian::weight result = 0;
00165 for (size_t i = 0; i < n_kids; ++i) {
00166 result += plist[i]->get_weight();
00167 }
00168 return result;
00169 }
00170
00171 bool
00172 MultiAndPostList::at_end() const
00173 {
00174 return (did == 0);
00175 }
00176
00177 Xapian::weight
00178 MultiAndPostList::recalc_maxweight()
00179 {
00180 max_total = 0.0;
00181 for (size_t i = 0; i < n_kids; ++i) {
00182 Xapian::weight new_max = plist[i]->recalc_maxweight();
00183 max_wt[i] = new_max;
00184 max_total += new_max;
00185 }
00186 return max_total;
00187 }
00188
00189 PostList *
00190 MultiAndPostList::find_next_match(Xapian::weight w_min)
00191 {
00192 advanced_plist0:
00193 if (plist[0]->at_end()) {
00194 did = 0;
00195 return NULL;
00196 }
00197 did = plist[0]->get_docid();
00198 for (size_t i = 1; i < n_kids; ++i) {
00199 bool valid;
00200 check_helper(i, did, w_min, valid);
00201 if (!valid) {
00202 next_helper(0, w_min);
00203 goto advanced_plist0;
00204 }
00205 if (plist[i]->at_end()) {
00206 did = 0;
00207 return NULL;
00208 }
00209 Xapian::docid new_did = plist[i]->get_docid();
00210 if (new_did != did) {
00211 skip_to_helper(0, new_did, w_min);
00212 goto advanced_plist0;
00213 }
00214 }
00215 return NULL;
00216 }
00217
00218 PostList *
00219 MultiAndPostList::next(Xapian::weight w_min)
00220 {
00221 next_helper(0, w_min);
00222 return find_next_match(w_min);
00223 }
00224
00225 PostList *
00226 MultiAndPostList::skip_to(Xapian::docid did_min, Xapian::weight w_min)
00227 {
00228 skip_to_helper(0, did_min, w_min);
00229 return find_next_match(w_min);
00230 }
00231
00232 std::string
00233 MultiAndPostList::get_description() const
00234 {
00235 string desc("(");
00236 desc += plist[0]->get_description();
00237 for (size_t i = 1; i < n_kids; ++i) {
00238 desc += " AND ";
00239 desc += plist[i]->get_description();
00240 }
00241 desc += ')';
00242 return desc;
00243 }
00244
00245 Xapian::termcount
00246 MultiAndPostList::get_wdf() const
00247 {
00248 Xapian::termcount totwdf = 0;
00249 for (size_t i = 0; i < n_kids; ++i) {
00250 totwdf += plist[i]->get_wdf();
00251 }
00252 return totwdf;
00253 }
00254
00255 Xapian::termcount
00256 MultiAndPostList::count_matching_subqs() const
00257 {
00258 Xapian::termcount total = 0;
00259 for (size_t i = 0; i < n_kids; ++i) {
00260 total += plist[i]->count_matching_subqs();
00261 }
00262 return total;
00263 }