00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include "ortermlist.h"
00024
00025 #include "debuglog.h"
00026 #include "omassert.h"
00027
00028 #include <xapian/positioniterator.h>
00029
00030 using namespace std;
00031
00032 void
00033 OrTermList::check_started() const
00034 {
00035 Assert(!left_current.empty());
00036 Assert(!right_current.empty());
00037 }
00038
00039 OrTermList::~OrTermList()
00040 {
00041 delete left;
00042 delete right;
00043 }
00044
00045 Xapian::termcount
00046 OrTermList::get_approx_size() const
00047 {
00048 LOGCALL(EXPAND, Xapian::termcount, "OrTermList::get_approx_size", NO_ARGS);
00049
00050
00051
00052 RETURN(left->get_approx_size() + right->get_approx_size());
00053 }
00054
00055 void
00056 OrTermList::accumulate_stats(Xapian::Internal::ExpandStats & stats) const
00057 {
00058 LOGCALL_VOID(EXPAND, "OrTermList::accumulate_stats", stats);
00059 check_started();
00060 if (left_current <= right_current) left->accumulate_stats(stats);
00061 if (left_current >= right_current) right->accumulate_stats(stats);
00062 }
00063
00064 string
00065 OrTermList::get_termname() const
00066 {
00067 LOGCALL(EXPAND, string, "OrTermList::get_termname", NO_ARGS);
00068 check_started();
00069 if (left_current < right_current) RETURN(left_current);
00070 RETURN(right_current);
00071 }
00072
00073 Xapian::termcount
00074 OrTermList::get_wdf() const
00075 {
00076 LOGCALL(EXPAND, Xapian::termcount, "OrTermList::get_wdf", NO_ARGS);
00077 check_started();
00078 if (left_current < right_current) RETURN(left->get_wdf());
00079 if (left_current > right_current) RETURN(right->get_wdf());
00080 RETURN(left->get_wdf() + right->get_wdf());
00081 }
00082
00083 Xapian::doccount
00084 OrTermList::get_termfreq() const
00085 {
00086 LOGCALL(EXPAND, Xapian::doccount, "OrTermList::get_termfreq", NO_ARGS);
00087 check_started();
00088 if (left_current < right_current) RETURN(left->get_termfreq());
00089 Assert(left_current > right_current || left->get_termfreq() == right->get_termfreq());
00090 RETURN(right->get_termfreq());
00091 }
00092
00093 #if 0 // This method isn't actually used anywhere currently.
00094 Xapian::termcount
00095 OrTermList::get_collection_freq() const
00096 {
00097 LOGCALL(EXPAND, Xapian::termcount, "OrTermList::get_collection_freq", NO_ARGS);
00098 check_started();
00099 if (left_current < right_current) RETURN(left->get_collection_freq());
00100 Assert(left_current > right_current || left->get_collection_freq() == right->get_collection_freq());
00101 RETURN(right->get_collection_freq());
00102 }
00103 #endif
00104
00105
00106 inline void
00107 handle_prune(TermList *& old, TermList * result)
00108 {
00109 if (result) {
00110 delete old;
00111 old = result;
00112 }
00113 }
00114
00115 TermList *
00116 OrTermList::next()
00117 {
00118 LOGCALL(EXPAND, TermList *, "OrTermList::next", NO_ARGS);
00119
00120
00121
00122 if (left_current < right_current) {
00123 handle_prune(left, left->next());
00124 if (left->at_end()) {
00125 TermList *ret = right;
00126 right = NULL;
00127 RETURN(ret);
00128 }
00129 left_current = left->get_termname();
00130 } else if (left_current > right_current) {
00131 handle_prune(right, right->next());
00132 if (right->at_end()) {
00133 TermList *ret = left;
00134 left = NULL;
00135 RETURN(ret);
00136 }
00137 right_current = right->get_termname();
00138 } else {
00139 AssertEq(left_current, right_current);
00140 handle_prune(left, left->next());
00141 handle_prune(right, right->next());
00142 if (left->at_end()) {
00143
00144
00145 TermList *ret = right;
00146 right = NULL;
00147 RETURN(ret);
00148 }
00149 if (right->at_end()) {
00150 TermList *ret = left;
00151 left = NULL;
00152 RETURN(ret);
00153 }
00154 left_current = left->get_termname();
00155 right_current = right->get_termname();
00156 }
00157 RETURN(NULL);
00158 }
00159
00160 TermList *
00161 OrTermList::skip_to(const string & term)
00162 {
00163 LOGCALL(EXPAND, TermList *, "OrTermList::skip_to", term);
00164
00165
00166
00167 if (left_current < right_current) {
00168 handle_prune(left, left->skip_to(term));
00169 if (left->at_end()) {
00170 TermList *ret = right;
00171 right = NULL;
00172 RETURN(ret);
00173 }
00174 left_current = left->get_termname();
00175 } else if (left_current > right_current) {
00176 handle_prune(right, right->skip_to(term));
00177 if (right->at_end()) {
00178 TermList *ret = left;
00179 left = NULL;
00180 RETURN(ret);
00181 }
00182 right_current = right->get_termname();
00183 } else {
00184 AssertEq(left_current, right_current);
00185 handle_prune(left, left->skip_to(term));
00186 handle_prune(right, right->skip_to(term));
00187 if (left->at_end()) {
00188
00189
00190 TermList *ret = right;
00191 right = NULL;
00192 RETURN(ret);
00193 }
00194 if (right->at_end()) {
00195 TermList *ret = left;
00196 left = NULL;
00197 RETURN(ret);
00198 }
00199 left_current = left->get_termname();
00200 right_current = right->get_termname();
00201 }
00202 RETURN(NULL);
00203 }
00204
00205 bool
00206 OrTermList::at_end() const
00207 {
00208 LOGCALL(EXPAND, bool, "OrTermList::at_end", NO_ARGS);
00209 check_started();
00210
00211 Assert(!left->at_end());
00212 Assert(!right->at_end());
00213 RETURN(false);
00214 }
00215
00216 Xapian::termcount
00217 OrTermList::positionlist_count() const
00218 {
00219 Assert(false);
00220 return 0;
00221 }
00222
00223 Xapian::PositionIterator
00224 OrTermList::positionlist_begin() const
00225 {
00226 Assert(false);
00227 return Xapian::PositionIterator();
00228 }
00229
00230
00231 Xapian::doccount
00232 FreqAdderOrTermList::get_termfreq() const
00233 {
00234 LOGCALL(EXPAND, Xapian::doccount, "FreqAdderOrTermList::get_termfreq", NO_ARGS);
00235 check_started();
00236 if (left_current < right_current) RETURN(left->get_termfreq());
00237 if (left_current > right_current) RETURN(right->get_termfreq());
00238 RETURN(left->get_termfreq() + right->get_termfreq());
00239 }