33 #include "../prefix_compressed_strings.h"
41 #include <string_view>
43 using namespace Glass;
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) {
98 string key =
"W" + j.first;
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.emplace(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;
145 string key =
"W"s.append(word);
147 if (get_exact_entry(key, data)) {
150 const char *
p = data.data();
154 wordfreq_changes.emplace(word, freq + freqinc);
157 wordfreq_changes.emplace(word, freqinc);
167 if (word.size() <= 1)
return freqdec;
169 auto i = wordfreq_changes.find(word);
170 if (i != wordfreq_changes.end()) {
171 if (i->second == 0) {
176 if (freqdec < i->second) {
177 i->second -= freqdec;
180 freqdec -= i->second;
185 string key =
"W"s.append(word);
187 if (!get_exact_entry(key, data)) {
193 const char *
p = data.data();
197 if (freqdec < freq) {
198 wordfreq_changes.emplace(word, freq - freqdec);
204 wordfreq_changes.emplace(word, 0);
222 toggle_fragment(buf, word);
226 buf[1] = word[word.size() - 2];
227 buf[2] = word[word.size() - 1];
229 toggle_fragment(buf, word);
231 if (word.size() <= 4) {
241 toggle_fragment(buf, word);
243 if (word.size() > 2) {
247 for (
size_t start = 0; start <= word.size() - 3; ++start) {
248 memcpy(buf.
data + 1, word.data() + start, 3);
251 if (done.insert(buf).second)
252 toggle_fragment(buf, word);
271 if (!wordfreq_changes.empty()) merge_changes();
273 vector<TermList*> termlists;
282 if (get_exact_entry(
string(buf), data))
287 buf[1] = word[word.size() - 2];
288 buf[2] = word[word.size() - 1];
289 if (get_exact_entry(
string(buf), data))
292 if (word.size() <= 4) {
301 if (get_exact_entry(
string(buf), data))
304 if (word.size() > 2) {
307 for (
size_t start = 0; start <= word.size() - 3; ++start) {
308 memcpy(buf.
data + 1, word.data() + start, 3);
309 if (get_exact_entry(
string(buf), data))
313 if (word.size() == 3) {
320 if (get_exact_entry(
string(buf), data))
326 if (get_exact_entry(
string(buf), data))
338 if (get_exact_entry(
string(buf), data))
341 if (get_exact_entry(
string(buf), data))
349 for (
auto& t : termlists) {
359 auto i = wordfreq_changes.find(word);
360 if (i != wordfreq_changes.end()) {
365 string key =
"W"s.append(word);
367 if (get_exact_entry(key, data)) {
370 const char *
p = data.data();
387 return clamp_cast<Xapian::termcount>(data.size());
405 if (
p == data.size()) {
408 if (!current_term.empty()) {
412 if (
p == data.size() ||
415 current_term.append(data.data() +
p + 1, add);
423 while (current_term <
term) {
Cast a value to a type, clamping out of range values.
Xapian::termcount remove_word(std::string_view word, Xapian::termcount freqdec)
void merge_changes()
Merge in batched-up changes.
TermList * open_termlist(std::string_view word)
void toggle_fragment(Glass::fragment frag, std::string_view word)
void toggle_word(std::string_view word)
void add_word(std::string_view word, Xapian::termcount freqinc)
Xapian::doccount get_word_frequency(std::string_view word) const
The list of words containing a particular trigram.
Xapian::doccount get_termfreq() const
Return the term frequency for the term at the current position.
TermList * skip_to(std::string_view term)
Skip forward to the specified term.
Xapian::termcount positionlist_count() const
Return the length of the position list for the current position.
TermList * next()
Advance the current position to the next term in the termlist.
Xapian::termcount get_approx_size() const
Return approximate size of this termlist.
PositionList * positionlist_begin() const
Return PositionList for the current position.
Xapian::termcount get_wdf() const
Return the wdf for the term at the current position.
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 glass database.
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)