39 using namespace Glass;
66 string key(
"\0\xd0", 2);
100 if (p == NULL || target <= did)
117 if (
rare(value_len >
size_t(end - p))) {
123 value.assign(p, value_len);
136 auto i = changes.find(slot);
137 if (i == changes.end()) {
138 i = changes.insert(make_pair(slot, map<Xapian::docid, string>())).first;
140 i->second[did] = val;
146 auto i = changes.find(slot);
147 if (i == changes.end()) {
148 i = changes.insert(make_pair(slot, map<Xapian::docid, string>())).first;
150 i->second[did] = string();
160 cursor.reset(postlist_table->cursor_get());
161 if (!cursor.get())
RETURN(0);
167 const char * p = cursor->current_key.data();
168 const char * end = p + cursor->current_key.size();
171 if (end - p < 2 || *p++ !=
'\0' || *p++ !=
'\xd8')
RETURN(0);
187 swap(chunk, cursor->current_tag);
230 if (first_did && new_first_did != first_did) {
242 : table(table_), slot(slot_), first_did(0), last_allowed_did(0) { }
245 while (!reader.
at_end()) {
254 if (last_allowed_did && did > last_allowed_did) {
260 while (!reader.
at_end()) {
267 last_allowed_did = 0;
269 if (last_allowed_did == 0) {
273 AutoPtr<GlassCursor> cursor(table->
cursor_get());
279 Assert(!cursor->after_end());
294 ctag = cursor->current_tag;
295 reader.
assign(ctag.data(), ctag.size(), first_did);
297 if (cursor->next()) {
298 const string & key = cursor->current_key;
300 if (next_first_did) last_allowed_did = next_first_did - 1;
302 AssertRel(last_allowed_did,>=,first_did);
314 if (!value.empty()) {
316 append_to_stream(did, value);
326 if (termlist_table->is_open()) {
327 for (
auto i : slots) {
329 const string&
enc = i.second;
331 termlist_table->add(key, enc);
333 termlist_table->del(key);
339 for (
auto i : changes) {
342 const map<Xapian::docid, string>& slot_changes = i.second;
343 for (
auto j : slot_changes) {
344 updater.
update(j.first, j.second);
352 map<Xapian::valueno, ValueStats> & value_stats)
365 std::pair<map<Xapian::valueno, ValueStats>::iterator,
bool> i;
366 i = value_stats.insert(make_pair(slot,
ValueStats()));
370 get_value_stats(slot, stats);
374 if ((stats.
freq)++ == 0) {
388 add_value(did, slot, value);
389 if (termlist_table->is_open()) {
390 pack_uint(slots_used, slot - prev_slot - 1);
395 if (slots_used.empty() && slots.find(did) == slots.end()) {
398 swap(slots[did], slots_used);
404 map<Xapian::valueno, ValueStats> & value_stats)
406 Assert(termlist_table->is_open());
407 map<Xapian::docid, string>::iterator it = slots.find(did);
409 if (it != slots.end()) {
413 if (!termlist_table->get_exact_entry(
make_slot_key(did), s))
return;
414 slots.insert(make_pair(did,
string()));
416 const char * p = s.data();
417 const char * end = p + s.size();
424 slot += prev_slot + 1;
427 std::pair<map<Xapian::valueno, ValueStats>::iterator,
bool> i;
428 i = value_stats.insert(make_pair(slot,
ValueStats()));
432 get_value_stats(slot, stats);
437 if (--(stats.
freq) == 0) {
442 remove_value(did, slot);
449 map<Xapian::valueno, ValueStats> & value_stats)
467 delete_document(did, value_stats);
468 add_document(did, doc, value_stats);
474 auto i = changes.find(slot);
475 if (i != changes.end()) {
476 auto j = i->second.find(did);
477 if (j != i->second.end())
return j->second;
483 first_did = get_chunk_containing_did(slot, did, chunk);
484 if (first_did == 0)
return string();
488 if (reader.at_end() || reader.get_docid() != did)
return string();
489 return reader.get_value();
497 if (!termlist_table->is_open()) {
501 if (!postlist_table->is_open())
505 map<Xapian::docid, string>::const_iterator i = slots.find(did);
507 if (i != slots.end()) {
511 if (!termlist_table->get_exact_entry(
make_slot_key(did), s))
return;
513 const char * p = s.data();
514 const char * end = p + s.size();
521 slot += prev_slot + 1;
523 values.insert(make_pair(slot, get_value(did, slot)));
530 LOGCALL_VOID(DB,
"GlassValueManager::get_value_stats", slot);
533 get_value_stats(slot, mru_valstats);
544 const char * pos = tag.data();
545 const char * end = pos + tag.size();
562 size_t len = end - pos;
576 LOGCALL_VOID(DB,
"GlassValueManager::set_value_stats", value_stats);
577 map<Xapian::valueno, ValueStats>::const_iterator i;
578 for (i = value_stats.begin(); i != value_stats.end(); ++i) {
581 if (stats.
freq != 0) {
590 postlist_table->add(key, new_value);
592 postlist_table->del(key);
#define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS)
Class to hold statistics for a given slot.
void set_value_stats(std::map< Xapian::valueno, ValueStats > &value_stats)
Write the updated statistics to the table.
static string make_slot_key(Xapian::docid did)
Generate a key for the "used slots" data.
#define GLASS_MAX_DOCID
The largest docid value supported by glass.
#define AssertRel(A, REL, B)
Xapian::docid docid_from_key(Xapian::valueno required_slot, const std::string &key)
ValueIterator values_begin() const
Iterator for the values in this document.
Class for iterating over document values.
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Postlists in glass databases.
std::string make_valuechunk_key(Xapian::valueno slot, Xapian::docid did)
Generate a key for a value stream chunk.
void add(const std::string &key, const std::string &tag, bool already_compressed=false)
Add a key/tag pair to the table, replacing any existing pair with the same key.
std::string upper_bound
An upper bound on the values stored in the given value slot.
Xapian::docid get_chunk_containing_did(Xapian::valueno slot, Xapian::docid did, std::string &chunk) const
#define AssertRelParanoid(A, REL, B)
docid get_docid() const
Get the document id which is associated with this document (if any).
void get_value_stats(Xapian::valueno slot) const
Get the statistics for value slot slot.
Xapian::doccount freq
The number of documents which have a (non-empty) value stored in the slot.
std::string lower_bound
A lower bound on the values stored in the given value slot.
const std::string & get_value() const
Hierarchy of classes which Xapian can throw as exceptions.
RangeError indicates an attempt to access outside the bounds of a container.
void pack_uint_last(std::string &s, U value)
Append an encoded unsigned integer to a string as the last item.
Indicates an attempt to use a feature which is unavailable.
Xapian::docid new_first_did
void remove_value(Xapian::docid did, Xapian::valueno slot)
ValueUpdater(GlassPostListTable *table_, Xapian::valueno slot_)
Class for iterating over document values.
bool unpack_uint_preserving_sort(const char **p, const char *end, U *result)
Decode a "sort preserved" unsigned integer from a string.
static void throw_database_closed()
Throw an exception indicating that the database is closed.
static const size_t CHUNK_SIZE_THRESHOLD
Xapian::docid last_allowed_did
ValueIterator values_end() const
Equivalent end iterator for values_begin().
Xapian::Internal::intrusive_ptr< Internal > internal
void update(Xapian::docid did, const string &value)
void assign(const char *p_, size_t len, Xapian::docid did_)
DatabaseCorruptError indicates database corruption was detected.
void add_value(Xapian::docid did, Xapian::valueno slot, const std::string &val)
void skip_to(Xapian::docid target)
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
void pack_string(std::string &s, const std::string &value)
Append an encoded std::string to a string.
Interface to Btree cursors.
void clear()
Clear the statistics.
Xapian::docid get_docid() const
GlassCursor * cursor_get() const
Get a cursor for reading from the table.
Pack types into strings and unpack them again.
unsigned valueno
The number for a value slot in a document.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
void delete_document(Xapian::docid did, std::map< Xapian::valueno, ValueStats > &value_stats)
bool unpack_string(const char **p, const char *end, std::string &result)
Decode a std::string from a string.
A TermList in a glass database.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
const valueno BAD_VALUENO
Reserved value to indicate "no valueno".
GlassPostListTable * table
void append_to_stream(Xapian::docid did, const string &value)
void add_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &value_stats)
A handle representing a document in a Xapian database.
bool del(const std::string &key)
Delete an entry from the table.
static string make_valuestats_key(Xapian::valueno slot)
Generate a key for a value statistics item.
Wrapper around standard unique_ptr template.
void replace_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &value_stats)
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Xapian::valueno get_valueno() const
Return the value slot number for the current position.
std::string get_value(Xapian::docid did, Xapian::valueno slot) const
void pack_uint_preserving_sort(std::string &s, U value)
Append an encoded unsigned integer to a string, preserving the sort order.
void get_all_values(std::map< Xapian::valueno, std::string > &values, Xapian::docid did) const