Branch data Line data Source code
1 : : /** @file flint_spelling.h
2 : : * @brief Spelling correction data for a flint database.
3 : : */
4 : : /* Copyright (C) 2007,2008,2009,2010 Olly Betts
5 : : *
6 : : * This program is free software; you can redistribute it and/or modify
7 : : * it under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 2 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * This program is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this program; if not, write to the Free Software
18 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : : */
20 : :
21 : : #ifndef XAPIAN_INCLUDED_FLINT_SPELLING_H
22 : : #define XAPIAN_INCLUDED_FLINT_SPELLING_H
23 : :
24 : : #include <xapian/types.h>
25 : :
26 : : #include "flint_table.h"
27 : : #include "termlist.h"
28 : :
29 : : #include <map>
30 : : #include <set>
31 : : #include <string>
32 : : #include <cstring> // For memcpy() and memcmp().
33 : :
34 : : struct F_fragment {
35 : : char data[4];
36 : :
37 : : // Default constructor.
38 : 114 : F_fragment() { }
39 : :
40 : : // Allow implicit conversion.
41 : : F_fragment(char data_[4]) { std::memcpy(data, data_, 4); }
42 : :
43 : 1155 : char & operator[] (unsigned i) { return data[i]; }
44 : : const char & operator[] (unsigned i) const { return data[i]; }
45 : :
46 : 583 : operator std::string () const {
47 [ + + ]: 583 : return std::string(data, data[0] == 'M' ? 4 : 3);
48 : : }
49 : : };
50 : :
51 : 1198 : inline bool operator<(const F_fragment &a, const F_fragment &b) {
52 : 1198 : return std::memcmp(a.data, b.data, 4) < 0;
53 : : }
54 : :
55 : 2193 : class FlintSpellingTable : public FlintTable {
56 : : void toggle_fragment(F_fragment frag, const std::string & word);
57 : :
58 : : std::map<std::string, Xapian::termcount> wordfreq_changes;
59 : : std::map<F_fragment, std::set<std::string> > termlist_deltas;
60 : :
61 : : public:
62 : : /** Create a new FlintSpellingTable object.
63 : : *
64 : : * This method does not create or open the table on disk - you
65 : : * must call the create() or open() methods respectively!
66 : : *
67 : : * @param dbdir The directory the flint database is stored in.
68 : : * @param readonly true if we're opening read-only, else false.
69 : : */
70 : 2193 : FlintSpellingTable(const std::string & dbdir, bool readonly)
71 : 2193 : : FlintTable("spelling", dbdir + "/spelling.", readonly, Z_DEFAULT_STRATEGY, true) { }
72 : :
73 : : // Merge in batched-up changes.
74 : : void merge_changes();
75 : :
76 : : void add_word(const std::string & word, Xapian::termcount freqinc);
77 : : void remove_word(const std::string & word, Xapian::termcount freqdec);
78 : :
79 : : TermList * open_termlist(const std::string & word);
80 : :
81 : : Xapian::doccount get_word_frequency(const std::string & word) const;
82 : :
83 : : /** Override methods of FlintTable.
84 : : *
85 : : * NB: these aren't virtual, but we always call them on the subclass in
86 : : * cases where it matters).
87 : : * @{
88 : : */
89 : :
90 : 679 : bool is_modified() const {
91 [ + + ][ + + ]: 679 : return !wordfreq_changes.empty() || FlintTable::is_modified();
92 : : }
93 : :
94 : 305 : void create_and_open(unsigned int blocksize) {
95 : : // The spelling table is created lazily, but erase it in case we're
96 : : // overwriting an existing database and it already exists.
97 : 305 : FlintTable::erase();
98 : 305 : FlintTable::set_block_size(blocksize);
99 : 305 : }
100 : :
101 : 460 : void flush_db() {
102 : 460 : merge_changes();
103 : 460 : FlintTable::flush_db();
104 : 460 : }
105 : :
106 : 149 : void cancel() {
107 : : // Discard batched-up changes.
108 : 149 : wordfreq_changes.clear();
109 : 149 : termlist_deltas.clear();
110 : :
111 : 149 : FlintTable::cancel();
112 : 149 : }
113 : :
114 : : // @}
115 : : };
116 : :
117 : : /** The list of words containing a particular trigram. */
118 [ + - ][ # # ]: 163 : class FlintSpellingTermList : public TermList {
119 : : /// The encoded data.
120 : : std::string data;
121 : :
122 : : /// Position in the data.
123 : : unsigned p;
124 : :
125 : : /// The current term.
126 : : std::string current_term;
127 : :
128 : : /// Copying is not allowed.
129 : : FlintSpellingTermList(const FlintSpellingTermList &);
130 : :
131 : : /// Assignment is not allowed.
132 : : void operator=(const FlintSpellingTermList &);
133 : :
134 : : public:
135 : : /// Constructor.
136 : 163 : FlintSpellingTermList(const std::string & data_)
137 : 163 : : data(data_), p(0) { }
138 : :
139 : : Xapian::termcount get_approx_size() const;
140 : :
141 : : std::string get_termname() const;
142 : :
143 : : Xapian::termcount get_wdf() const;
144 : :
145 : : Xapian::doccount get_termfreq() const;
146 : :
147 : : Xapian::termcount get_collection_freq() const;
148 : :
149 : : TermList * next();
150 : :
151 : : TermList * skip_to(const std::string & term);
152 : :
153 : : bool at_end() const;
154 : :
155 : : Xapian::termcount positionlist_count() const;
156 : :
157 : : Xapian::PositionIterator positionlist_begin() const;
158 : : };
159 : :
160 : : #endif // XAPIAN_INCLUDED_FLINT_SPELLING_H
|