00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024 #include "flint_values.h"
00025 #include "flint_utils.h"
00026 #include "utils.h"
00027 #include <xapian/error.h>
00028 using std::string;
00029 using std::make_pair;
00030
00031 #include "debuglog.h"
00032
00034 inline void
00035 make_key(string & key, Xapian::docid did)
00036 {
00037 LOGCALL_STATIC_VOID(DB, "make_key", key | did);
00038 key = flint_docid_to_key(did);
00039 }
00040
00041 void
00042 FlintValueTable::unpack_entry(const char ** pos,
00043 const char * end,
00044 Xapian::valueno * this_value_no,
00045 string & this_value)
00046 {
00047 LOGCALL_STATIC_VOID(DB, "FlintValueTable::unpack_entry", pos | (void*)end | this_value_no | this_value);
00048 if (!F_unpack_uint(pos, end, this_value_no)) {
00049 if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
00050 else throw Xapian::RangeError("Value number in value table is too large");
00051 }
00052
00053 if (!F_unpack_string(pos, end, this_value)) {
00054 if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
00055 else throw Xapian::RangeError("Item in value table is too large");
00056 }
00057
00058 LOGLINE(DB, "FlintValueTable::unpack_entry(): value no " <<
00059 this_value_no << " is `" << this_value << "'");
00060 }
00061
00062 void
00063 FlintValueTable::encode_values(string & s,
00064 Xapian::ValueIterator it,
00065 const Xapian::ValueIterator & end)
00066 {
00067 LOGCALL_VOID(DB, "FlintValueTable::encode_values", s | it | end);
00068 while (it != end) {
00069 s += F_pack_uint(it.get_valueno());
00070 s += F_pack_string(*it);
00071 ++it;
00072 }
00073 }
00074
00075 void
00076 FlintValueTable::set_encoded_values(Xapian::docid did, const string & enc)
00077 {
00078 LOGCALL_VOID(DB, "FlintValueTable::set_encoded_values", did | enc);
00079 string key;
00080 make_key(key, did);
00081 add(key, enc);
00082 }
00083
00084 void
00085 FlintValueTable::get_value(string & value,
00086 Xapian::docid did,
00087 Xapian::valueno slot) const
00088 {
00089 LOGCALL_VOID(DB, "FlintValueTable::get_value", value | did | slot);
00090 string key;
00091 make_key(key, did);
00092 string tag;
00093 bool found = get_exact_entry(key, tag);
00094
00095 if (found) {
00096 const char * pos = tag.data();
00097 const char * end = pos + tag.size();
00098
00099 while (pos && pos != end) {
00100 Xapian::valueno this_value_no;
00101 string this_value;
00102
00103 unpack_entry(&pos, end, &this_value_no, this_value);
00104
00105 if (this_value_no == slot) {
00106 value = this_value;
00107 return;
00108 }
00109
00110
00111 if (this_value_no > slot) break;
00112 }
00113 }
00114 value = string();
00115 }
00116
00117 void
00118 FlintValueTable::get_all_values(map<Xapian::valueno, string> & values,
00119 Xapian::docid did) const
00120 {
00121 LOGCALL_VOID(DB, "FlintValueTable::get_all_values", values | did);
00122 string key;
00123 make_key(key, did);
00124 string tag;
00125 bool found = get_exact_entry(key, tag);
00126
00127 values.clear();
00128 if (!found) return;
00129
00130 const char * pos = tag.data();
00131 const char * end = pos + tag.size();
00132
00133 while (pos && pos != end) {
00134 Xapian::valueno this_value_no;
00135 string this_value;
00136
00137 unpack_entry(&pos, end, &this_value_no, this_value);
00138 values.insert(make_pair(this_value_no, this_value));
00139 }
00140 }
00141
00142 void
00143 FlintValueTable::delete_all_values(Xapian::docid did)
00144 {
00145 LOGCALL_VOID(DB, "FlintValueTable::delete_all_values", did);
00146 string key;
00147 make_key(key, did);
00148 del(key);
00149 }