00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00052
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
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
00076 throw Xapian::DatabaseCorruptError("Data ran out when reading position list length.");
00077 } else {
00078
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
00098 throw Xapian::DatabaseCorruptError("Data ran out when reading position list entry.");
00099 } else {
00100
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
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 }