expand/ortermlist.cc

Go to the documentation of this file.
00001 
00004 /* Copyright (C) 2007 Olly Betts
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include "omassert.h"
00024 #include "omdebug.h"
00025 
00026 #include "ortermlist.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     DEBUGCALL(EXPAND, Xapian::termcount, "OrTermList::get_approx_size", "");
00049     // This is actually the upper bound, but we only use this to order the
00050     // binary tree of OrTermList objects so it's probably not worth trying
00051     // to be more sophisticated.
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     DEBUGCALL(EXPAND, void, "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     DEBUGCALL(EXPAND, string, "OrTermList::get_termname", "");
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     DEBUGCALL(EXPAND, Xapian::termcount, "OrTermList::get_wdf", "");
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     DEBUGCALL(EXPAND, Xapian::doccount, "OrTermList::get_termfreq", "");
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     DEBUGCALL(EXPAND, Xapian::termcount, "OrTermList::get_collection_freq", "");
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 // Helper function.
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     DEBUGCALL(EXPAND, TermList *, "OrTermList::next", "");
00119     // If we've not started yet, both left_current and right_current will be
00120     // empty, so we'll take the third case below which is what we want to do to
00121     // get started.
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             // right->at_end() may also be true, but our parent will deal with
00144             // that.
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 bool
00161 OrTermList::at_end() const
00162 {
00163     DEBUGCALL(EXPAND, bool, "OrTermList::at_end", "");
00164     check_started();
00165     // next() should have pruned if either child is at_end().
00166     Assert(!left->at_end());
00167     Assert(!right->at_end());
00168     RETURN(false);
00169 }
00170 
00171 Xapian::termcount
00172 OrTermList::positionlist_count() const
00173 {
00174     Assert(false);
00175     return 0;
00176 }
00177 
00178 Xapian::PositionIterator
00179 OrTermList::positionlist_begin() const
00180 {
00181     Assert(false);
00182     return Xapian::PositionIterator(NULL);
00183 }
00184 
00185 
00186 Xapian::doccount
00187 FreqAdderOrTermList::get_termfreq() const
00188 {
00189     DEBUGCALL(EXPAND, Xapian::doccount, "FreqAdderOrTermList::get_termfreq", "");
00190     check_started();
00191     if (left_current < right_current) RETURN(left->get_termfreq());
00192     if (left_current > right_current) RETURN(right->get_termfreq());
00193     RETURN(left->get_termfreq() + right->get_termfreq());
00194 }

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.