33 #include "../prefix_compressed_strings.h"
41 #include <string_view>
43 using namespace Honey;
49 for (
auto i : termlist_deltas) {
50 const string& key = i.first;
51 const set<string>& changes = i.second;
53 auto d = changes.begin();
54 if (d == changes.end())
continue;
59 if (get_exact_entry(key, current)) {
61 updated.reserve(current.size());
62 while (!in.
at_end() && d != changes.end()) {
63 const string& word = *in;
64 Assert(d != changes.end());
65 int cmp = word.compare(*d);
86 while (d != changes.end()) {
89 if (!updated.empty()) {
95 termlist_deltas.clear();
97 for (
auto j = wordfreq_changes.begin(); j != wordfreq_changes.end(); ++j) {
104 if (wordfreq > wordfreq_upper_bound)
105 wordfreq_upper_bound = wordfreq;
110 wordfreq_changes.clear();
116 auto i = termlist_deltas.find(frag);
117 if (i == termlist_deltas.end()) {
118 i = termlist_deltas.insert(make_pair(frag, set<string>())).first;
122 auto res = i->second.insert(word);
125 i->second.erase(res.first);
132 if (word.size() <= 1)
return;
134 auto i = wordfreq_changes.find(word);
135 if (i != wordfreq_changes.end()) {
138 i->second += freqinc;
149 const char*
p = data.data();
153 wordfreq_changes[word] = freq + freqinc;
156 wordfreq_changes[word] = freqinc;
166 if (word.size() <= 1)
return freqdec;
168 auto i = wordfreq_changes.find(word);
169 if (i != wordfreq_changes.end()) {
170 if (i->second == 0) {
175 if (freqdec < i->second) {
176 i->second -= freqdec;
179 freqdec -= i->second;
191 const char*
p = data.data();
195 if (freqdec < freq) {
196 wordfreq_changes[word] = freq - freqdec;
202 wordfreq_changes[word] = 0;
216 if (word.size() <= 4) {
225 buf[2] = word[word.size() - 1];
226 toggle_fragment(buf, word);
233 toggle_fragment(buf, word);
237 buf[1] = word[word.size() - 2];
238 buf[2] = word[word.size() - 1];
239 toggle_fragment(buf, word);
241 if (word.size() > 2) {
245 for (
size_t start = 0; start <= word.size() - 3; ++start) {
246 memcpy(buf.
data + 1, word.data() + start, 3);
249 if (done.insert(buf).second)
250 toggle_fragment(buf, word);
269 if (!wordfreq_changes.empty()) merge_changes();
271 vector<TermList*> termlists;
276 if (word.size() <= 4) {
284 buf[2] = word[word.size() - 1];
285 if (get_exact_entry(
string(buf), data))
293 if (get_exact_entry(
string(buf), data))
296 if (word.size() == 2) {
303 if (get_exact_entry(
string(buf), data))
306 if (get_exact_entry(
string(buf), data))
312 buf[1] = word[word.size() - 2];
313 buf[2] = word[word.size() - 1];
314 if (get_exact_entry(
string(buf), data))
317 if (word.size() > 2) {
320 for (
size_t start = 0; start <= word.size() - 3; ++start) {
321 memcpy(buf.
data + 1, word.data() + start, 3);
322 if (get_exact_entry(
string(buf), data))
326 if (word.size() == 3) {
333 if (get_exact_entry(
string(buf), data))
339 if (get_exact_entry(
string(buf), data))
348 for (
auto& t : termlists) {
358 auto i = wordfreq_changes.find(word);
359 if (i != wordfreq_changes.end()) {
368 const char*
p = data.data();
385 return clamp_cast<Xapian::termcount>(data.size());
403 if (
p == data.size()) {
408 if (
rare(tail < 0)) {
410 keep = current_term.size() - tail;
411 }
else if (
usual(!current_term.empty())) {
415 if (
p == data.size() ||
420 if (
rare(keep + tail > current_term.size())) {
423 string tail_string(current_term, current_term.size() - tail);
424 current_term.replace(keep, string::npos, data.data() +
p + 1, add);
425 current_term += tail_string;
427 current_term.replace(keep, current_term.size() - tail - keep,
428 data.data() +
p + 1, add);
438 while (current_term <
term) {
450 "positionlist_count() "
459 "positionlist_begin() "
Cast a value to a type, clamping out of range values.
void merge_changes()
Merge in batched-up changes.
void toggle_word(const std::string &word)
Xapian::termcount remove_word(const std::string &word, Xapian::termcount freqdec)
void toggle_fragment(Honey::fragment frag, const std::string &word)
TermList * open_termlist(std::string_view word)
Xapian::doccount get_word_frequency(std::string_view word) const
void add_word(const std::string &word, Xapian::termcount freqinc)
The list of words containing a particular trigram.
TermList * next()
Advance the current position to the next term in the termlist.
Xapian::termcount positionlist_count() const
Return the length of the position list for the current position.
Xapian::termcount get_wdf() const
Return the wdf for the term at the current position.
PositionList * positionlist_begin() const
Return PositionList for the current position.
TermList * skip_to(std::string_view term)
Skip forward to the specified term.
Xapian::doccount get_termfreq() const
Return the term frequency for the term at the current position.
Xapian::termcount get_approx_size() const
Return approximate size of this termlist.
void append(const std::string &word)
DatabaseCorruptError indicates database corruption was detected.
Abstract base class for iterating term positions in a document.
Abstract base class for termlists.
virtual Xapian::termcount get_approx_size() const =0
Return approximate size of this termlist.
UnimplementedError indicates an attempt to use an unimplemented feature.
Hierarchy of classes which Xapian can throw as exceptions.
Collate statistics and calculate the term weights for the ESet.
Spelling correction data for a honey database.
const unsigned KEY_PREFIX_MIDDLE
const unsigned KEY_PREFIX_TAIL
std::string make_spelling_wordlist_key(std::string_view word)
const unsigned KEY_PREFIX_BOOKEND
const unsigned KEY_PREFIX_HEAD
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
Various assertion macros.
#define AssertRel(A, REL, B)
Pack types into strings and unpack them again.
bool unpack_uint_last(const char **p, const char *end, U *result)
Decode an unsigned integer as the last item in a string.
void pack_uint_last(std::string &s, U value)
Append an encoded unsigned integer to a string as the last item.
bool operator()(const TermList *a, const TermList *b) const
Build tree to merge TermList objects.
TermList * make_termlist_merger(std::vector< TermList * > &termlists)