00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef XAPIAN_INCLUDED_BRASS_VALUES_H
00023 #define XAPIAN_INCLUDED_BRASS_VALUES_H
00024
00025 #include "pack.h"
00026 #include "valuestats.h"
00027
00028 #include "xapian/error.h"
00029 #include "xapian/types.h"
00030
00031 #include <map>
00032 #include <string>
00033
00034 namespace Brass {
00035
00037 inline std::string
00038 make_valuechunk_key(Xapian::valueno slot, Xapian::docid did)
00039 {
00040 std::string key("\0\xd8", 2);
00041 pack_uint(key, slot);
00042 pack_uint_preserving_sort(key, did);
00043 return key;
00044 }
00045
00046 inline Xapian::docid
00047 docid_from_key(Xapian::valueno required_slot, const std::string & key)
00048 {
00049 const char * p = key.data();
00050 const char * end = p + key.length();
00051
00052 if (end - p < 2 || *p++ != '\0' || *p++ != '\xd8') return 0;
00053 Xapian::valueno slot;
00054 if (!unpack_uint(&p, end, &slot))
00055 throw Xapian::DatabaseCorruptError("bad value key");
00056
00057 if (slot != required_slot) return 0;
00058 Xapian::docid did;
00059 if (!unpack_uint_preserving_sort(&p, end, &did))
00060 throw Xapian::DatabaseCorruptError("bad value key");
00061 return did;
00062 }
00063
00064 }
00065
00066 namespace Xapian {
00067 class Document;
00068 }
00069
00070 class BrassPostListTable;
00071 class BrassTermListTable;
00072 struct ValueStats;
00073
00074 class BrassValueManager {
00080 mutable Xapian::valueno mru_slot;
00081
00083 mutable ValueStats mru_valstats;
00084
00085 BrassPostListTable * postlist_table;
00086
00087 BrassTermListTable * termlist_table;
00088
00089 std::map<Xapian::docid, std::string> slots;
00090
00091 std::map<Xapian::valueno, std::map<Xapian::docid, std::string> > changes;
00092
00093 void add_value(Xapian::docid did, Xapian::valueno slot,
00094 const std::string & val);
00095
00096 void remove_value(Xapian::docid did, Xapian::valueno slot);
00097
00098 Xapian::docid get_chunk_containing_did(Xapian::valueno slot,
00099 Xapian::docid did,
00100 std::string &chunk) const;
00101
00103 void get_value_stats(Xapian::valueno slot) const;
00104
00105 void get_value_stats(Xapian::valueno slot, ValueStats & stats) const;
00106
00107 public:
00109 BrassValueManager(BrassPostListTable * postlist_table_,
00110 BrassTermListTable * termlist_table_)
00111 : mru_slot(Xapian::BAD_VALUENO),
00112 postlist_table(postlist_table_),
00113 termlist_table(termlist_table_) { }
00114
00115
00116 void merge_changes();
00117
00118 void add_document(Xapian::docid did, const Xapian::Document &doc,
00119 std::map<Xapian::valueno, ValueStats> & value_stats);
00120
00121 void delete_document(Xapian::docid did,
00122 std::map<Xapian::valueno, ValueStats> & value_stats);
00123
00124 void replace_document(Xapian::docid did, const Xapian::Document &doc,
00125 std::map<Xapian::valueno, ValueStats> & value_stats);
00126
00127 std::string get_value(Xapian::docid did, Xapian::valueno slot) const;
00128
00129 void get_all_values(std::map<Xapian::valueno, std::string> & values,
00130 Xapian::docid did) const;
00131
00132 Xapian::doccount get_value_freq(Xapian::valueno slot) const {
00133 if (mru_slot != slot) get_value_stats(slot);
00134 return mru_valstats.freq;
00135 }
00136
00137 std::string get_value_lower_bound(Xapian::valueno slot) const {
00138 if (mru_slot != slot) get_value_stats(slot);
00139 return mru_valstats.lower_bound;
00140 }
00141
00142 std::string get_value_upper_bound(Xapian::valueno slot) const {
00143 if (mru_slot != slot) get_value_stats(slot);
00144 return mru_valstats.upper_bound;
00145 }
00146
00154 void set_value_stats(std::map<Xapian::valueno, ValueStats> & value_stats);
00155
00156 void reset() {
00158 mru_slot = Xapian::BAD_VALUENO;
00159 }
00160
00161 bool is_modified() const {
00162 return !changes.empty();
00163 }
00164
00165 void cancel() {
00166
00167 slots.clear();
00168 changes.clear();
00169 }
00170 };
00171
00172 namespace Brass {
00173
00174 class ValueChunkReader {
00175 const char *p;
00176 const char *end;
00177
00178 Xapian::docid did;
00179
00180 std::string value;
00181
00182 public:
00184 ValueChunkReader() : p(NULL) { }
00185
00186 ValueChunkReader(const char * p_, size_t len, Xapian::docid did_) {
00187 assign(p_, len, did_);
00188 }
00189
00190 void assign(const char * p_, size_t len, Xapian::docid did_);
00191
00192 bool at_end() const { return p == NULL; }
00193
00194 Xapian::docid get_docid() const { return did; }
00195
00196 const std::string & get_value() const { return value; }
00197
00198 void next();
00199
00200 void skip_to(Xapian::docid target);
00201 };
00202
00203 }
00204
00205 #endif // XAPIAN_INCLUDED_BRASS_VALUES_H