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 "andnotpostlist.h"
00026
00027 #include "debuglog.h"
00028 #include "omassert.h"
00029
00030 PostList *
00031 AndNotPostList::advance_to_next_match(Xapian::weight w_min, PostList *ret)
00032 {
00033 LOGCALL(MATCH, PostList *, "AndNotPostList::advance_to_next_match", w_min | ret);
00034 handle_prune(l, ret);
00035 if (l->at_end()) {
00036 lhead = 0;
00037 RETURN(NULL);
00038 }
00039 lhead = l->get_docid();
00040
00041 while (rhead <= lhead) {
00042 if (lhead == rhead) {
00043 next_handling_prune(l, w_min, matcher);
00044 if (l->at_end()) {
00045 lhead = 0;
00046 RETURN(NULL);
00047 }
00048 lhead = l->get_docid();
00049 }
00050 skip_to_handling_prune(r, lhead, 0, matcher);
00051 if (r->at_end()) {
00052 ret = l;
00053 l = NULL;
00054 RETURN(ret);
00055 }
00056 rhead = r->get_docid();
00057 }
00058 RETURN(NULL);
00059 }
00060
00061 AndNotPostList::AndNotPostList(PostList *left_,
00062 PostList *right_,
00063 MultiMatch *matcher_,
00064 Xapian::doccount dbsize_)
00065 : BranchPostList(left_, right_, matcher_),
00066 lhead(0), rhead(0), dbsize(dbsize_)
00067 {
00068 LOGCALL_CTOR(MATCH, "AndNotPostList", left_ | right_ | matcher_ | dbsize_);
00069 }
00070
00071 PostList *
00072 AndNotPostList::next(Xapian::weight w_min)
00073 {
00074 LOGCALL(MATCH, PostList *, "AndNotPostList::next", w_min);
00075 RETURN(advance_to_next_match(w_min, l->next(w_min)));
00076 }
00077
00078 PostList *
00079 AndNotPostList::sync_and_skip_to(Xapian::docid id,
00080 Xapian::weight w_min,
00081 Xapian::docid lh,
00082 Xapian::docid rh)
00083 {
00084 LOGCALL(MATCH, PostList *, "AndNotPostList::sync_and_skip_to", id | w_min | lh | rh);
00085 lhead = lh;
00086 rhead = rh;
00087 RETURN(skip_to(id, w_min));
00088 }
00089
00090 PostList *
00091 AndNotPostList::skip_to(Xapian::docid did, Xapian::weight w_min)
00092 {
00093 LOGCALL(MATCH, PostList *, "AndNotPostList::skip_to", did | w_min);
00094 if (did <= lhead) RETURN(NULL);
00095 RETURN(advance_to_next_match(w_min, l->skip_to(did, w_min)));
00096 }
00097
00098 Xapian::doccount
00099 AndNotPostList::get_termfreq_max() const
00100 {
00101 LOGCALL(MATCH, Xapian::doccount, "AndNotPostList::get_termfreq_max", NO_ARGS);
00102
00103 RETURN(l->get_termfreq_max());
00104 }
00105
00106 Xapian::doccount
00107 AndNotPostList::get_termfreq_min() const
00108 {
00109 LOGCALL(MATCH, Xapian::doccount, "AndNotPostList::get_termfreq_min", NO_ARGS);
00110
00111 Xapian::doccount l_min = l->get_termfreq_min();
00112 Xapian::doccount r_max = r->get_termfreq_max();
00113 if (l_min > r_max) RETURN(l_min - r_max);
00114 RETURN(0u);
00115 }
00116
00117 Xapian::doccount
00118 AndNotPostList::get_termfreq_est() const
00119 {
00120 LOGCALL(MATCH, Xapian::doccount, "AndNotPostList::get_termfreq_est", NO_ARGS);
00121 if (rare(dbsize == 0))
00122 RETURN(0);
00123
00124
00125
00126 double est = l->get_termfreq_est() *
00127 (1.0 - double(r->get_termfreq_est()) / dbsize);
00128 RETURN(static_cast<Xapian::doccount>(est + 0.5));
00129 }
00130
00131 TermFreqs
00132 AndNotPostList::get_termfreq_est_using_stats(
00133 const Xapian::Weight::Internal & stats) const
00134 {
00135 LOGCALL(MATCH, TermFreqs, "AndNotPostList::get_termfreq_est_using_stats", stats);
00136
00137
00138
00139 TermFreqs lfreqs(l->get_termfreq_est_using_stats(stats));
00140 TermFreqs rfreqs(r->get_termfreq_est_using_stats(stats));
00141
00142 double freqest, relfreqest;
00143
00144
00145 Assert(stats.collection_size);
00146
00147 freqest = lfreqs.termfreq *
00148 (1.0 - (double(rfreqs.termfreq) / stats.collection_size));
00149
00150 if (stats.rset_size == 0) {
00151 relfreqest = 0;
00152 } else {
00153 relfreqest = lfreqs.reltermfreq *
00154 (1.0 - (double(rfreqs.reltermfreq) / stats.rset_size));
00155 }
00156
00157 RETURN(TermFreqs(static_cast<Xapian::doccount>(freqest + 0.5),
00158 static_cast<Xapian::doccount>(relfreqest + 0.5)));
00159 }
00160
00161 Xapian::docid
00162 AndNotPostList::get_docid() const
00163 {
00164 LOGCALL(MATCH, Xapian::docid, "AndNotPostList::get_docid", NO_ARGS);
00165 RETURN(lhead);
00166 }
00167
00168
00169 Xapian::weight
00170 AndNotPostList::get_weight() const
00171 {
00172 LOGCALL(MATCH, Xapian::weight, "AndNotPostList::get_weight", NO_ARGS);
00173 RETURN(l->get_weight());
00174 }
00175
00176
00177 Xapian::weight
00178 AndNotPostList::get_maxweight() const
00179 {
00180 LOGCALL(MATCH, Xapian::weight, "AndNotPostList::get_maxweight", NO_ARGS);
00181 RETURN(l->get_maxweight());
00182 }
00183
00184 Xapian::weight
00185 AndNotPostList::recalc_maxweight()
00186 {
00187 LOGCALL(MATCH, Xapian::weight, "AndNotPostList::recalc_maxweight", NO_ARGS);
00188
00189
00190 RETURN(l->recalc_maxweight());
00191 }
00192
00193 bool
00194 AndNotPostList::at_end() const
00195 {
00196 LOGCALL(MATCH, bool, "AndNotPostList::at_end", NO_ARGS);
00197 RETURN(lhead == 0);
00198 }
00199
00200 std::string
00201 AndNotPostList::get_description() const
00202 {
00203 return "(" + l->get_description() + " AndNot " + r->get_description() + ")";
00204 }
00205
00206 Xapian::termcount
00207 AndNotPostList::get_doclength() const
00208 {
00209 LOGCALL(MATCH, Xapian::termcount, "AndNotPostList::get_doclength", NO_ARGS);
00210 RETURN(l->get_doclength());
00211 }
00212
00213 Xapian::termcount
00214 AndNotPostList::get_wdf() const
00215 {
00216 LOGCALL(MATCH, Xapian::termcount, "AndNotPostList::get_wdf", NO_ARGS);
00217 RETURN(l->get_wdf());
00218 }
00219
00220 Xapian::termcount
00221 AndNotPostList::count_matching_subqs() const
00222 {
00223 LOGCALL(MATCH, Xapian::termcount, "AndNotPostList::count_matching_subqs", NO_ARGS);
00224 RETURN(l->count_matching_subqs());
00225 }