backends/quartz/quartz_positionlist.cc

Go to the documentation of this file.
00001 /* quartz_positionlist.cc
00002  *
00003  * ----START-LICENCE----
00004  * Copyright 1999,2000,2001 BrightStation PLC
00005  * Copyright 2002 Ananova Ltd
00006  * Copyright 2002,2003,2004 Olly Betts
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA
00022  * -----END-LICENCE-----
00023  */
00024 
00025 #include <config.h>
00026 #include "omdebug.h"
00027 #include "quartz_positionlist.h"
00028 #include "quartz_utils.h"
00029 #include "utils.h"
00030 
00031 using std::string;
00032 
00033 static inline void
00034 make_key(Xapian::docid did, const string & tname, string & key)
00035 {
00036     key = pack_uint(did) + tname;
00037 }
00038 
00039 void
00040 QuartzPositionList::read_data(const Btree * table,
00041                               Xapian::docid did,
00042                               const string & tname)
00043 {
00044     DEBUGCALL(DB, void, "QuartzPositionList::read_data",
00045               table << ", " << did << ", " << tname);
00046 
00047     string key;
00048     string tag;
00049     make_key(did, tname, key);
00050     if (!table->get_exact_entry(key, tag)) {
00051         // This isn't an error, since position list not be present simply
00052         // implies that there is no positional information available.
00053         data = "";
00054         pos = data.data();
00055         end = pos;
00056         is_at_end = false;
00057         have_started = false;
00058         current_pos = 0;
00059         number_of_entries = 0;
00060         return;
00061     }
00062 
00063     // FIXME: Unwanted copy
00064     data = tag;
00065 
00066     pos = data.data();
00067     end = pos + data.size();
00068     is_at_end = false;
00069     have_started = false;
00070     current_pos = 0;
00071 
00072     bool success = unpack_uint(&pos, end, &number_of_entries);
00073     if (! success) {
00074         if (pos == 0) {
00075             // data ran out
00076             throw Xapian::DatabaseCorruptError("Data ran out when reading position list length.");
00077         } else {
00078             // overflow
00079             throw Xapian::RangeError("Position list length too large.");
00080         }
00081     }
00082 }
00083 
00084 void
00085 QuartzPositionList::next_internal()
00086 {
00087     DEBUGCALL(DB, void, "QuartzPositionList::next_internal", "");
00088     if (pos == end) {
00089         is_at_end = true;
00090         return;
00091     }
00092 
00093     Xapian::termpos pos_increment;
00094     bool success = unpack_uint(&pos, end, &pos_increment);
00095     if (! success) {
00096         if (pos == 0) {
00097             // data ran out
00098             throw Xapian::DatabaseCorruptError("Data ran out when reading position list entry.");
00099         } else {
00100             // overflow
00101             throw Xapian::RangeError("Position list length too large.");
00102         }
00103     }
00104     Assert(pos != 0);
00105     current_pos += pos_increment + 1;
00106 }
00107 
00108 void
00109 QuartzPositionList::next()
00110 {
00111     DEBUGCALL(DB, void, "QuartzPositionList::next", "");
00112     Assert(!is_at_end);
00113     next_internal();
00114     have_started = true;
00115     DEBUGLINE(DB, string("QuartzPositionList - moved to ") <<
00116               (is_at_end ? string("end.") : std::string("position = ") +
00117                om_tostring(current_pos) + "."));
00118 }
00119 
00120 void
00121 QuartzPositionList::skip_to(Xapian::termpos termpos)
00122 {
00123     DEBUGCALL(DB, void, "QuartzPositionList::skip_to", termpos);
00124     if (!have_started) {
00125         next_internal();
00126         have_started = true;
00127     }
00128     while (!is_at_end && current_pos < termpos) next_internal();
00129     DEBUGLINE(DB, string("QuartzPositionList - skipped to ") <<
00130               (is_at_end ? string("end.") : std::string("position = ") +
00131                om_tostring(current_pos) + "."));
00132 }
00133 
00134 // Methods modifying position lists
00135 
00136 void
00137 QuartzPositionListTable::set_positionlist(Xapian::docid did,
00138                         const string & tname,
00139                         Xapian::PositionIterator pos,
00140                         const Xapian::PositionIterator &pos_end)
00141 {
00142     DEBUGCALL(DB, void, "QuartzPositionList::set_positionlist", did << ", " << tname << ", " << pos << ", " << pos_end);
00143     string key;
00144 
00145     make_key(did, tname, key);
00146     string tag;
00147 
00148     Xapian::termpos prevpos = 0;
00149     unsigned int size = 0;
00150     for ( ; pos != pos_end; ++pos) {
00151         tag += pack_uint(*pos - prevpos - 1);
00152         prevpos = *pos;
00153         size++;
00154     }
00155     tag = pack_uint(size) + tag;
00156     add(key, tag);
00157 }
00158 
00159 void
00160 QuartzPositionListTable::delete_positionlist(Xapian::docid did,
00161                         const string & tname)
00162 {
00163     DEBUGCALL(DB, void, "QuartzPositionList::delete_positionlist", did << ", " << tname);
00164     string key;
00165     make_key(did, tname, key);
00166     del(key);
00167 }

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