65 string key(
"\0\xd0", 2);
99 if (p == NULL || target <= did)
116 if (
rare(value_len >
size_t(end - p))) {
122 value.assign(p, value_len);
135 map<Xapian::valueno, map<Xapian::docid, string> >::iterator i;
136 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 map<Xapian::valueno, map<Xapian::docid, string> >::iterator i;
147 i = changes.find(slot);
148 if (i == changes.end()) {
149 i = changes.insert(make_pair(slot, map<Xapian::docid, string>())).first;
151 i->second[did] = string();
161 cursor.reset(postlist_table->cursor_get());
162 if (!cursor.get())
RETURN(0);
168 const char * p = cursor->current_key.data();
169 const char * end = p + cursor->current_key.size();
172 if (end - p < 2 || *p++ !=
'\0' || *p++ !=
'\xd8')
RETURN(0);
188 swap(chunk, cursor->current_tag);
229 if (first_did && new_first_did != first_did) {
241 : table(table_), slot(slot_), first_did(0), last_allowed_did(0) { }
244 while (!reader.
at_end()) {
253 if (last_allowed_did && did > last_allowed_did) {
259 while (!reader.
at_end()) {
266 last_allowed_did = 0;
268 if (last_allowed_did == 0) {
272 AutoPtr<ChertCursor> cursor(table->
cursor_get());
278 Assert(!cursor->after_end());
293 ctag = cursor->current_tag;
294 reader.
assign(ctag.data(), ctag.size(), first_did);
296 if (cursor->next()) {
297 const string & key = cursor->current_key;
299 if (next_first_did) last_allowed_did = next_first_did - 1;
301 AssertRel(last_allowed_did,>=,first_did);
313 if (!value.empty()) {
315 append_to_stream(did, value);
323 if (termlist_table->is_open()) {
324 map<Xapian::docid, string>::const_iterator i;
325 for (i = slots.begin(); i != slots.end(); ++i) {
326 const string &
enc = i->second;
329 termlist_table->add(key, i->second);
331 termlist_table->del(key);
338 map<Xapian::valueno, map<Xapian::docid, string> >::const_iterator i;
339 for (i = changes.begin(); i != changes.end(); ++i) {
342 const map<Xapian::docid, string> & slot_changes = i->second;
343 map<Xapian::docid, string>::const_iterator j;
344 for (j = slot_changes.begin(); j != slot_changes.end(); ++j) {
345 updater.
update(j->first, j->second);
354 map<Xapian::valueno, ValueStats> & value_stats)
367 std::pair<map<Xapian::valueno, ValueStats>::iterator,
bool> i;
368 i = value_stats.insert(make_pair(slot,
ValueStats()));
372 get_value_stats(slot, stats);
376 if ((stats.
freq)++ == 0) {
390 add_value(did, slot, value);
391 if (termlist_table->is_open()) {
392 pack_uint(slots_used, slot - prev_slot - 1);
397 if (slots_used.empty() && slots.find(did) == slots.end()) {
400 swap(slots[did], slots_used);
406 map<Xapian::valueno, ValueStats> & value_stats)
408 Assert(termlist_table->is_open());
409 map<Xapian::docid, string>::iterator it = slots.find(did);
411 if (it != slots.end()) {
415 if (!termlist_table->get_exact_entry(
make_slot_key(did), s))
return;
416 slots.insert(make_pair(did,
string()));
418 const char * p = s.data();
419 const char * end = p + s.size();
426 slot += prev_slot + 1;
429 std::pair<map<Xapian::valueno, ValueStats>::iterator,
bool> i;
430 i = value_stats.insert(make_pair(slot,
ValueStats()));
434 get_value_stats(slot, stats);
439 if (--(stats.
freq) == 0) {
444 remove_value(did, slot);
451 map<Xapian::valueno, ValueStats> & value_stats)
457 delete_document(did, value_stats);
458 add_document(did, doc, value_stats);
464 map<Xapian::valueno, map<Xapian::docid, string> >::const_iterator i;
465 i = changes.find(slot);
466 if (i != changes.end()) {
467 map<Xapian::docid, string>::const_iterator j;
468 j = i->second.find(did);
469 if (j != i->second.end())
return j->second;
475 first_did = get_chunk_containing_did(slot, did, chunk);
476 if (first_did == 0)
return string();
480 if (reader.at_end() || reader.get_docid() != did)
return string();
481 return reader.get_value();
489 if (!termlist_table->is_open()) {
492 if (!postlist_table->is_open())
496 map<Xapian::docid, string>::const_iterator i = slots.find(did);
498 if (i != slots.end()) {
502 if (!termlist_table->get_exact_entry(
make_slot_key(did), s))
return;
504 const char * p = s.data();
505 const char * end = p + s.size();
512 slot += prev_slot + 1;
514 values.insert(make_pair(slot, get_value(did, slot)));
521 LOGCALL_VOID(DB,
"ChertValueManager::get_value_stats", slot);
524 get_value_stats(slot, mru_valstats);
537 const char * pos = tag.data();
538 const char * end = pos + tag.size();
556 size_t len = end - pos;
572 LOGCALL_VOID(DB,
"ChertValueManager::set_value_stats", value_stats);
573 map<Xapian::valueno, ValueStats>::const_iterator i;
574 for (i = value_stats.begin(); i != value_stats.end(); ++i) {
577 if (stats.
freq != 0) {
586 postlist_table->add(key, new_value);
588 postlist_table->del(key);
#define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS)
Class to hold statistics for a given slot.
ValueUpdater(ChertPostListTable *table_, Xapian::valueno slot_)
std::string get_value(Xapian::docid did, Xapian::valueno slot) const
void add_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &value_stats)
#define AssertRel(A, REL, B)
void get_all_values(std::map< Xapian::valueno, std::string > &values, Xapian::docid did) const
static string make_valuestats_key(Xapian::valueno slot)
Generate a key for a value statistics item.
void set_value_stats(std::map< Xapian::valueno, ValueStats > &value_stats)
Write the updated statistics to the table.
ValueIterator values_begin() const
Iterator for the values in this document.
std::string make_valuechunk_key(Xapian::valueno slot, Xapian::docid did)
Generate a key for a value stream chunk.
Class for iterating over document values.
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
std::string upper_bound
An upper bound on the values stored in the given value slot.
static string make_slot_key(Xapian::docid did)
Generate a key for the "used slots" data.
#define AssertRelParanoid(A, REL, B)
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.
Hierarchy of classes which Xapian can throw as exceptions.
bool del(const std::string &key)
Delete an entry from the table.
ChertPostListTable * table
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.
static const size_t CHUNK_SIZE_THRESHOLD
const std::string & get_value() const
Indicates an attempt to use a feature which is unavailable.
void C_pack_uint_preserving_sort(std::string &s, U value)
Append an encoded unsigned integer to a string, preserving the sort order.
bool C_unpack_uint_preserving_sort(const char **p, const char *end, U *result)
Decode an "sort preserved" unsigned integer from a string.
Interface to Btree cursors.
void replace_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &value_stats)
void add_value(Xapian::docid did, Xapian::valueno slot, const std::string &val)
#define CHERT_MAX_DOCID
The largest docid value supported by chert.
void skip_to(Xapian::docid target)
Class for iterating over document values.
void remove_value(Xapian::docid did, Xapian::valueno slot)
ChertCursor * cursor_get() const
Get a cursor for reading from the table.
Xapian::docid docid_from_key(Xapian::valueno required_slot, const std::string &key)
void assign(const char *p_, size_t len, Xapian::docid did_)
ValueIterator values_end() const
Equivalent end iterator for values_begin().
Xapian::Internal::intrusive_ptr< Internal > internal
void get_value_stats(Xapian::valueno slot) const
Get the statistics for value slot slot.
A TermList in a chert database.
void append_to_stream(Xapian::docid did, const string &value)
DatabaseCorruptError indicates database corruption was detected.
void add(const std::string &key, std::string tag, bool already_compressed=false)
Add a key/tag pair to the table, replacing any existing pair with the same key.
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
Xapian::docid get_chunk_containing_did(Xapian::valueno slot, Xapian::docid did, std::string &chunk) const
void pack_string(std::string &s, const std::string &value)
Append an encoded std::string to a string.
void update(Xapian::docid did, const string &value)
Xapian::docid new_first_did
void clear()
Clear the statistics.
Postlists in chert databases.
Pack types into strings and unpack them again.
unsigned valueno
The number for a value slot in a document.
Xapian::docid last_allowed_did
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.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Xapian::docid get_docid() const
const valueno BAD_VALUENO
Reserved value to indicate "no valueno".
static void throw_database_closed()
Throw an exception indicating that the database is closed.
A handle representing a document in a Xapian database.
Wrapper around standard unique_ptr template.
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Xapian::valueno get_valueno() const
Return the value slot number for the current position.