32 #include "../prefix_compressed_strings.h"
41 using namespace Glass;
47 for (
auto i : termlist_deltas) {
48 const string& key = i.first;
49 const set<string>& changes = i.second;
51 auto d = changes.begin();
52 if (d == changes.end())
continue;
57 if (get_exact_entry(key, current)) {
59 updated.reserve(current.size());
60 while (!in.
at_end() && d != changes.end()) {
61 const string & word = *in;
62 Assert(d != changes.end());
63 int cmp = word.compare(*d);
84 while (d != changes.end()) {
87 if (!updated.empty()) {
93 termlist_deltas.clear();
95 map<string, Xapian::termcount>::const_iterator j;
96 for (j = wordfreq_changes.begin(); j != wordfreq_changes.end(); ++j) {
97 string key =
"W" + j->first;
103 if (wordfreq > wordfreq_upper_bound)
104 wordfreq_upper_bound = wordfreq;
109 wordfreq_changes.clear();
115 auto i = termlist_deltas.find(frag);
116 if (i == termlist_deltas.end()) {
117 i = termlist_deltas.insert(make_pair(frag, set<string>())).first;
121 auto res = i->second.insert(word);
124 i->second.erase(res.first);
131 if (word.size() <= 1)
return;
133 map<string, Xapian::termcount>::iterator i = wordfreq_changes.find(word);
134 if (i != wordfreq_changes.end()) {
137 i->second += freqinc;
144 string key =
"W" + word;
146 if (get_exact_entry(key, data)) {
149 const char * p = data.data();
153 wordfreq_changes[word] = freq + freqinc;
156 wordfreq_changes[word] = freqinc;
166 if (word.size() <= 1)
return;
168 map<string, Xapian::termcount>::iterator 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;
183 string key =
"W" + word;
185 if (!get_exact_entry(key, data)) {
191 const char *p = data.data();
195 if (freqdec < freq) {
196 wordfreq_changes[word] = freq - freqdec;
200 wordfreq_changes[word] = 0;
216 toggle_fragment(buf, word);
220 buf[1] = word[word.size() - 2];
221 buf[2] = word[word.size() - 1];
223 toggle_fragment(buf, word);
225 if (word.size() <= 4) {
235 toggle_fragment(buf, word);
237 if (word.size() > 2) {
241 for (
size_t start = 0; start <= word.size() - 3; ++start) {
242 memcpy(buf.
data + 1, word.data() + start, 3);
245 if (done.insert(buf).second)
246 toggle_fragment(buf, word);
265 if (!wordfreq_changes.empty()) merge_changes();
278 if (get_exact_entry(
string(buf), data))
283 buf[1] = word[word.size() - 2];
284 buf[2] = word[word.size() - 1];
285 if (get_exact_entry(
string(buf), data))
288 if (word.size() <= 4) {
297 if (get_exact_entry(
string(buf), data))
300 if (word.size() > 2) {
303 for (
size_t start = 0; start <= word.size() - 3; ++start) {
304 memcpy(buf.
data + 1, word.data() + start, 3);
305 if (get_exact_entry(
string(buf), data))
309 if (word.size() == 3) {
316 if (get_exact_entry(
string(buf), data))
322 if (get_exact_entry(
string(buf), data))
334 if (get_exact_entry(
string(buf), data))
337 if (get_exact_entry(
string(buf), data))
341 if (pq.empty())
return NULL;
350 while (pq.size() > 1) {
356 termlist =
new OrTermList(pq.top(), termlist);
365 while (!pq.empty()) {
376 map<string, Xapian::termcount>::const_iterator i;
377 i = wordfreq_changes.find(word);
378 if (i != wordfreq_changes.end()) {
383 string key =
"W" + word;
385 if (get_exact_entry(key, data)) {
388 const char *p = data.data();
429 if (p == data.size()) {
434 if (!current_term.empty()) {
438 if (p == data.size() ||
441 current_term.append(data.data() + p + 1, add);
449 while (!data.empty() && current_term < term) {
TermList * open_termlist(const std::string &word)
void merge_changes()
Merge in batched-up changes.
void toggle_fragment(Glass::fragment frag, const std::string &word)
void remove_word(const std::string &word, Xapian::termcount freqdec)
void toggle_word(const std::string &word)
void add_word(const std::string &word, Xapian::termcount freqinc)
Xapian::doccount get_word_frequency(const std::string &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(const std::string &term)
Skip forward to the specified term.
std::string get_termname() const
Return the termname at the current position.
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.
Xapian::PositionIterator positionlist_begin() const
Return a PositionIterator for the current position.
bool at_end() const
Return true if the current position is past the last term in this list.
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.
Class for iterating over term positions.
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)
Merge two TermList objects using an OR operation.
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