backends/multi/multi_postlist.cc

Go to the documentation of this file.
00001 /* multi_postlist.cc: interface to multiple database access
00002  *
00003  * Copyright 1999,2000,2001 BrightStation PLC
00004  * Copyright 2002,2003,2004,2005,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
00019  * USA
00020  */
00021 
00022 #include <config.h>
00023 #include <stdio.h>
00024 
00025 #include "omassert.h"
00026 #include "omdebug.h"
00027 #include "multi_postlist.h"
00028 #include "utils.h"
00029 
00030 #ifdef XAPIAN_DEBUG_PARANOID
00031 #include "xapian/database.h"
00032 #endif
00033 
00034 MultiPostList::MultiPostList(std::vector<LeafPostList *> & pls,
00035                              const Xapian::Database &this_db_)
00036         : postlists(pls),
00037           this_db(this_db_),
00038           finished(false),
00039           currdoc(0)
00040 {
00041     multiplier = pls.size();
00042 }
00043 
00044 
00045 MultiPostList::~MultiPostList()
00046 {
00047     std::vector<LeafPostList *>::iterator i;
00048     for (i = postlists.begin(); i != postlists.end(); i++) {
00049         delete *i;
00050     }
00051     postlists.clear();
00052 }
00053 
00054 Xapian::doccount
00055 MultiPostList::get_termfreq() const
00056 {
00057     // Should never get called.
00058     Assert(false);
00059     return 0;
00060 }
00061 
00062 Xapian::docid
00063 MultiPostList::get_docid() const
00064 {
00065     DEBUGCALL(DB, Xapian::docid, "MultiPostList::get_docid", "");
00066     Assert(!at_end());
00067     Assert(currdoc != 0);
00068     RETURN(currdoc);
00069 }
00070 
00071 Xapian::doclength
00072 MultiPostList::get_doclength() const
00073 {
00074     DEBUGCALL(DB, Xapian::doclength, "MultiPostList::get_doclength", "");
00075     Assert(!at_end());
00076     Assert(currdoc != 0);
00077     Xapian::doclength result = postlists[(currdoc - 1) % multiplier]->get_doclength();
00078     AssertEqParanoid(result, this_db.get_doclength(get_docid()));
00079     RETURN(result);
00080 }
00081 
00082 Xapian::termcount
00083 MultiPostList::get_wdf() const
00084 {
00085     return postlists[(currdoc - 1) % multiplier]->get_wdf();
00086 }
00087 
00088 PositionList *
00089 MultiPostList::open_position_list() const
00090 {
00091     return postlists[(currdoc - 1) % multiplier]->open_position_list();
00092 }
00093 
00094 PostList *
00095 MultiPostList::next(Xapian::weight w_min)
00096 {
00097     DEBUGCALL(DB, PostList *, "MultiPostList::next", w_min);
00098     Assert(!at_end());
00099 
00100     Xapian::docid newdoc = 0;
00101     Xapian::docid offset = 1;
00102     std::vector<LeafPostList *>::iterator i;
00103     for (i = postlists.begin(); i != postlists.end(); i++) {
00104         if (!(*i)->at_end()) {
00105             Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00106             // Check if it needs to be advanced
00107             if (currdoc >= id) {
00108                 (*i)->next(w_min);
00109                 if (!(*i)->at_end()) {
00110                     id = ((*i)->get_docid() - 1) * multiplier + offset;
00111                     if (newdoc == 0 || id < newdoc) newdoc = id;
00112                 }
00113             } else {
00114                 if (newdoc == 0 || id < newdoc) newdoc = id;
00115             }
00116         }
00117         offset++;
00118     }
00119     if (newdoc) {
00120         DEBUGLINE(DB, "MultiPostList::next() newdoc=" << newdoc <<
00121                   " (olddoc=" << currdoc << ")");
00122         currdoc = newdoc;
00123     } else {
00124         DEBUGLINE(DB, "MultiPostList::next() finished" <<
00125                   " (olddoc=" << currdoc << ")");
00126         finished = true;
00127     }
00128     RETURN(NULL);
00129 }
00130 
00131 PostList *
00132 MultiPostList::skip_to(Xapian::docid did, Xapian::weight w_min)
00133 {
00134     DEBUGCALL(DB, PostList *, "MultiPostList::skip_to", did << ", " << w_min);
00135     Assert(!at_end());
00136     Xapian::docid newdoc = 0;
00137     Xapian::docid offset = 0;
00138     Xapian::docid realdid = (did - 1) / multiplier + 2;
00139     Xapian::doccount dbnumber = (did - 1) % multiplier;
00140     std::vector<LeafPostList *>::iterator i;
00141     for (i = postlists.begin(); i != postlists.end(); i++) {    
00142         if (offset == dbnumber) --realdid;
00143         ++offset;
00144         Assert((realdid - 1) * multiplier + offset >= did);
00145         Assert((realdid - 1) * multiplier + offset < did + multiplier);
00146         if (!(*i)->at_end()) {
00147             (*i)->skip_to(realdid, w_min);
00148             if (!(*i)->at_end()) {
00149                 Xapian::docid id = ((*i)->get_docid() - 1) * multiplier + offset;
00150                 if (newdoc == 0 || id < newdoc) newdoc = id;
00151             }
00152         }
00153     }
00154     if (newdoc) {
00155         currdoc = newdoc;
00156     } else {
00157         finished = true;
00158     }
00159     RETURN(NULL);
00160 }
00161 
00162 bool
00163 MultiPostList::at_end() const
00164 {
00165     return finished;
00166 }
00167 
00168 std::string
00169 MultiPostList::get_description() const
00170 {
00171     std::string desc;
00172 
00173     std::vector<LeafPostList *>::const_iterator i;
00174     for (i = postlists.begin(); i != postlists.end(); i++) {
00175         if (!desc.empty()) desc += ',';
00176         desc += (*i)->get_description();
00177     }
00178 
00179     return desc;
00180 }

Documentation for Xapian (version 1.0.20).
Generated on 28 Apr 2010 by Doxygen 1.5.2.