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 "flint_values.h"
00027 #include "flint_utils.h"
00028 #include "utils.h"
00029 #include <xapian/error.h>
00030 using std::string;
00031 using std::make_pair;
00032
00033 #include "omdebug.h"
00034
00036 inline void
00037 make_key(string & key, Xapian::docid did)
00038 {
00039 DEBUGCALL_STATIC(DB, void, "make_key", key << ", " << did);
00040 key = flint_docid_to_key(did);
00041 }
00042
00043 void
00044 FlintValueTable::unpack_entry(const char ** pos,
00045 const char * end,
00046 Xapian::valueno * this_value_no,
00047 string & this_value)
00048 {
00049 DEBUGCALL_STATIC(DB, void, "FlintValueTable::unpack_entry",
00050 "[pos], [end], " << this_value_no << ", " << this_value);
00051 if (!unpack_uint(pos, end, this_value_no)) {
00052 if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
00053 else throw Xapian::RangeError("Value number in value table is too large");
00054 }
00055
00056 if (!unpack_string(pos, end, this_value)) {
00057 if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
00058 else throw Xapian::RangeError("Item in value table is too large");
00059 }
00060
00061 DEBUGLINE(DB, "FlintValueTable::unpack_entry(): value no " <<
00062 this_value_no << " is `" << this_value << "'");
00063 }
00064
00065 void
00066 FlintValueTable::encode_values(string & s,
00067 Xapian::ValueIterator it,
00068 const Xapian::ValueIterator & end)
00069 {
00070 DEBUGCALL(DB, void, "FlintValueTable::encode_values", "[&s], " << it << ", " << end);
00071 while (it != end) {
00072 s += pack_uint(it.get_valueno());
00073 s += pack_string(*it);
00074 ++it;
00075 }
00076 }
00077
00078 void
00079 FlintValueTable::set_encoded_values(Xapian::docid did, const string & enc)
00080 {
00081 DEBUGCALL(DB, void, "FlintValueTable::set_encoded_values", did << ", " << enc);
00082 string key;
00083 make_key(key, did);
00084 add(key, enc);
00085 }
00086
00087 void
00088 FlintValueTable::get_value(string & value,
00089 Xapian::docid did,
00090 Xapian::valueno valueno) const
00091 {
00092 DEBUGCALL(DB, void, "FlintValueTable::get_value", value << ", " << did << ", " << valueno);
00093 string key;
00094 make_key(key, did);
00095 string tag;
00096 bool found = get_exact_entry(key, tag);
00097
00098 if (found) {
00099 const char * pos = tag.data();
00100 const char * end = pos + tag.size();
00101
00102 while (pos && pos != end) {
00103 Xapian::valueno this_value_no;
00104 string this_value;
00105
00106 unpack_entry(&pos, end, &this_value_no, this_value);
00107
00108 if (this_value_no == valueno) {
00109 value = this_value;
00110 return;
00111 }
00112
00113
00114 if (this_value_no > valueno) break;
00115 }
00116 }
00117 value = "";
00118 }
00119
00120 void
00121 FlintValueTable::get_all_values(map<Xapian::valueno, string> & values,
00122 Xapian::docid did) const
00123 {
00124 DEBUGCALL(DB, void, "FlintValueTable::get_all_values", "[values], " << did);
00125 string key;
00126 make_key(key, did);
00127 string tag;
00128 bool found = get_exact_entry(key, tag);
00129
00130 values.clear();
00131 if (!found) return;
00132
00133 const char * pos = tag.data();
00134 const char * end = pos + tag.size();
00135
00136 while (pos && pos != end) {
00137 Xapian::valueno this_value_no;
00138 string this_value;
00139
00140 unpack_entry(&pos, end, &this_value_no, this_value);
00141 values.insert(make_pair(this_value_no, this_value));
00142 }
00143 }
00144
00145 void
00146 FlintValueTable::delete_all_values(Xapian::docid did)
00147 {
00148 DEBUGCALL(DB, void, "FlintValueTable::delete_all_values", did);
00149 string key;
00150 make_key(key, did);
00151 del(key);
00152 }