43 using namespace Honey;
83 if (
p == NULL || target <= did)
103 if (
rare(value_len >
size_t(end -
p))) {
110 value.assign(
p, value_len);
123 auto i = changes.find(slot);
124 if (i == changes.end()) {
125 i = changes.insert(make_pair(slot, map<Xapian::docid, string>())).first;
127 i->second[did] = val;
133 auto i = changes.find(slot);
134 if (i == changes.end()) {
135 i = changes.insert(make_pair(slot, map<Xapian::docid, string>())).first;
137 i->second[did] = string();
147 cursor.reset(postlist_table.cursor_get());
158 chunk = cursor->current_tag;
201 if (last_did && new_last_did != last_did) {
213 : table(table_), slot(slot_), last_did(0), last_allowed_did(0) { }
216 while (!reader.
at_end()) {
225 if (last_allowed_did && did > last_allowed_did) {
231 while (!reader.
at_end()) {
238 last_allowed_did = 0;
240 if (last_allowed_did == 0) {
244 unique_ptr<HoneyCursor> cursor(table.
cursor_get());
250 Assert(!cursor->after_end());
265 ctag = cursor->current_tag;
266 reader.
assign(ctag.data(), ctag.size(), last_did);
268 if (cursor->next()) {
269 const string& key = cursor->current_key;
274 const char*
p = cursor->current_tag.data();
275 const char* e =
p + cursor->current_tag.size();
281 last_allowed_did = next_first_did - 1;
296 if (!value.empty()) {
298 append_to_stream(did, value);
308 for (
auto&& i : changes) {
311 for (
auto&& j : i.second) {
312 updater.
update(j.first, j.second);
320 map<Xapian::valueno, ValueStats>& val_stats)
325 auto i = slots.find(did);
326 if (i != slots.end()) {
328 i->second = string();
341 const string& value = *it;
344 auto i = val_stats.insert(make_pair(slot,
ValueStats()));
348 get_value_stats(slot, stats);
352 if ((stats.
freq)++ == 0) {
371 add_value(did, slot, value);
376 if (!termlist_table.is_open()) {
384 slots_used.
encode(first_slot, last_slot);
385 slots_used.
encode(count - 2, last_slot - first_slot);
389 return slots_used.
freeze();
394 map<Xapian::valueno, ValueStats>& val_stats)
396 Assert(termlist_table.is_open());
397 auto it = slots.find(did);
399 if (it != slots.end()) {
404 if (!termlist_table.get_exact_entry(termlist_table.make_key(did), s))
406 slots.insert(make_pair(did,
string()));
409 const char*
p = s.data();
410 const char* end =
p + s.size();
411 size_t slot_enc_size;
415 if (slot_enc_size == 0)
418 end =
p + slot_enc_size;
431 while (slot != last_slot) {
432 auto i = val_stats.insert(make_pair(slot,
ValueStats()));
436 get_value_stats(slot, stats);
441 if (--(stats.
freq) == 0) {
446 remove_value(did, slot);
456 auto i = val_stats.insert(make_pair(slot,
ValueStats()));
460 get_value_stats(slot, stats);
465 if (--(stats.
freq) == 0) {
470 remove_value(did, slot);
478 map<Xapian::valueno, ValueStats>& val_stats)
495 doc.
internal->ensure_values_fetched();
497 delete_document(did, val_stats);
498 return add_document(did, doc, val_stats);
504 auto i = changes.find(slot);
505 if (i != changes.end()) {
506 auto j = i->second.find(did);
507 if (j != i->second.end())
return j->second;
513 last_did = get_chunk_containing_did(slot, did, chunk);
514 if (last_did == 0)
return string();
527 if (!termlist_table.is_open()) {
531 if (!postlist_table.is_open())
537 if (!termlist_table.get_exact_entry(termlist_table.make_key(did), s))
540 const char*
p = s.data();
541 const char* end =
p + s.size();
542 size_t slot_enc_size = *
p++;
544 if ((slot_enc_size & 0x80) == 0) {
547 while (slot_enc_size) {
548 if (slot_enc_size & 1) {
549 values.insert(make_pair(slot, get_value(did, slot)));
557 slot_enc_size &= 0x7f;
558 if (slot_enc_size == 0) {
564 end =
p + slot_enc_size;
577 while (slot != last_slot) {
578 values.insert(make_pair(slot, get_value(did, slot)));
582 values.insert(make_pair(last_slot, get_value(did, last_slot)));
588 LOGCALL_VOID(DB,
"HoneyValueManager::get_value_stats", slot);
591 get_value_stats(slot, mru_valstats);
603 const char*
pos = tag.data();
604 const char* end =
pos + tag.size();
622 size_t len = end -
pos;
636 LOGCALL_VOID(DB,
"HoneyValueManager::set_value_stats", val_stats);
637 for (
auto&& i : val_stats) {
640 if (stats.
freq != 0) {
645 postlist_table.del(key);
Classes to encode/decode a bitstream.
HoneyCursor * cursor_get() const
void add(std::string_view key, const char *val, size_t val_size, bool compressed=false)
bool del(const std::string &)
static void throw_database_closed()
void add_value(Xapian::docid did, Xapian::valueno slot, const std::string &val)
void get_all_values(std::map< Xapian::valueno, std::string > &values, Xapian::docid did) const
std::string get_value(Xapian::docid did, Xapian::valueno slot) const
void remove_value(Xapian::docid did, Xapian::valueno slot)
void set_value_stats(std::map< Xapian::valueno, ValueStats > &val_stats)
Write the updated statistics to the table.
std::string add_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &val_stats)
void get_value_stats(Xapian::valueno slot) const
Get the statistics for value slot slot.
void delete_document(Xapian::docid did, std::map< Xapian::valueno, ValueStats > &val_stats)
std::string replace_document(Xapian::docid did, const Xapian::Document &doc, std::map< Xapian::valueno, ValueStats > &val_stats)
Xapian::docid get_chunk_containing_did(Xapian::valueno slot, Xapian::docid did, std::string &chunk) const
Move the cursor to the chunk containing did.
void assign(const char *p_, size_t len, Xapian::docid last_did)
const std::string & get_value() const
void skip_to(Xapian::docid target)
Xapian::docid get_docid() const
void append_to_stream(Xapian::docid did, const string &value)
ValueUpdater(HoneyPostListTable &table_, Xapian::valueno slot_)
Xapian::docid last_allowed_did
HoneyPostListTable & table
void update(Xapian::docid did, const string &value)
Xapian::docid new_last_did
Read a stream created by BitWriter.
Xapian::termpos decode(Xapian::termpos outof, bool force=false)
void decode_interpolative(int j, int k, Xapian::termpos pos_j, Xapian::termpos pos_k)
Perform interpolative decoding between elements between j and k.
Xapian::termpos decode_interpolative_next()
Perform on-demand interpolative decoding.
Create a stream to which non-byte-aligned values can be written.
void encode(Xapian::termpos value, Xapian::termpos outof)
Encode value, known to be less than outof.
std::string & freeze()
Finish encoding and return the encoded data as a std::string.
void encode_interpolative(const Xapian::VecCOW< Xapian::termpos > &pos, int j, int k)
Perform interpolative encoding of pos elements between j and k.
DatabaseCorruptError indicates database corruption was detected.
Class representing a document.
Xapian::docid get_docid() const
Get the document ID this document came from.
Xapian::Internal::intrusive_ptr_nonnull< Internal > internal
ValueIterator values_begin() const
Start iterating the values in this document.
ValueIterator values_end() const noexcept
End iterator corresponding to values_begin().
Indicates an attempt to use a feature which is unavailable.
RangeError indicates an attempt to access outside the bounds of a container.
Class for iterating over document values.
Xapian::valueno get_valueno() const
Return the value slot number for the current position.
Suitable for "simple" type T.
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Abstract base class for a document.
Hierarchy of classes which Xapian can throw as exceptions.
#define HONEY_MAX_DOCID
The largest docid value supported by honey.
PostList in a honey database.
Subclass of HoneyTable which holds postlists.
A TermList in a honey database.
Subclass of HoneyTable which holds termlists.
static const size_t CHUNK_SIZE_THRESHOLD
static std::string encode_valuestats(Xapian::doccount freq, const std::string &lbound, const std::string &ubound)
std::string make_valuechunk_key(Xapian::valueno slot, Xapian::docid last_did)
Generate a key for a value stream chunk.
Xapian::docid docid_from_key(const std::string &key)
std::string make_valuestats_key(Xapian::valueno slot)
const valueno BAD_VALUENO
Reserved value to indicate "no valueno".
unsigned valueno
The number for a value slot in a document.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
#define AssertRelParanoid(A, REL, B)
#define AssertRel(A, REL, B)
Pack types into strings and unpack them again.
bool unpack_string(const char **p, const char *end, std::string &result)
Decode a std::string from a string.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
void pack_string(std::string &s, std::string_view value)
Append an encoded std::string to a string.
Class to hold statistics for a given slot.
std::string lower_bound
A lower bound on the values stored in the given value slot.
std::string upper_bound
An upper bound on the values stored in the given value slot.
void clear()
Clear the statistics.
Xapian::doccount freq
The number of documents which have a (non-empty) value stored in the slot.
Class for iterating over document values.