Branch data Line data Source code
1 : : /** @file brass_inverter.h
2 : : * @brief Inverter class which "inverts the file".
3 : : */
4 : : /* Copyright (C) 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_BRASS_INVERTER_H
22 : : #define XAPIAN_INCLUDED_BRASS_INVERTER_H
23 : :
24 : : #include "xapian/types.h"
25 : :
26 : : #include <map>
27 : : #include <string>
28 : :
29 : : #include "omassert.h"
30 : : #include "str.h"
31 : : #include "xapian/error.h"
32 : :
33 : : class BrassPostListTable;
34 : :
35 : : /** Magic wdf value used for a deleted posting. */
36 : : const Xapian::termcount DELETED_POSTING = Xapian::termcount(-1);
37 : :
38 : : /** Class which "inverts the file". */
39 : 1290 : class Inverter {
40 : : friend class BrassPostListTable;
41 : :
42 : : /// Class for storing the changes in frequencies for a term.
43 : 150878 : class PostingChanges {
44 : : friend class BrassPostListTable;
45 : :
46 : : /// Change in term frequency,
47 : : Xapian::termcount_diff tf_delta;
48 : :
49 : : /// Change in collection frequency.
50 : : Xapian::termcount_diff cf_delta;
51 : :
52 : : /// Changes to this term's postlist.
53 : : std::map<Xapian::docid, Xapian::termcount> pl_changes;
54 : :
55 : : public:
56 : : /// Constructor for an added posting.
57 : 21410 : PostingChanges(Xapian::docid did, Xapian::termcount wdf)
58 : 21410 : : tf_delta(1), cf_delta(Xapian::termcount_diff(wdf))
59 : : {
60 : 21410 : pl_changes.insert(std::make_pair(did, wdf));
61 : 21410 : }
62 : :
63 : : /// Constructor for a removed posting.
64 : 120 : PostingChanges(Xapian::docid did, Xapian::termcount wdf, bool)
65 : 120 : : tf_delta(-1), cf_delta(-Xapian::termcount_diff(wdf))
66 : : {
67 : 120 : pl_changes.insert(std::make_pair(did, DELETED_POSTING));
68 : 120 : }
69 : :
70 : : /// Constructor for an updated posting.
71 : 24 : PostingChanges(Xapian::docid did, Xapian::termcount old_wdf,
72 : : Xapian::termcount new_wdf)
73 : 24 : : tf_delta(0), cf_delta(Xapian::termcount_diff(new_wdf - old_wdf))
74 : : {
75 : 24 : pl_changes.insert(std::make_pair(did, new_wdf));
76 : 24 : }
77 : :
78 : : /// Add a posting.
79 : 755229 : void add_posting(Xapian::docid did, Xapian::termcount wdf) {
80 : 755229 : ++tf_delta;
81 : 755229 : cf_delta += wdf;
82 : : // Add did to term's postlist
83 : 755229 : pl_changes[did] = wdf;
84 : 755229 : }
85 : :
86 : : /// Remove a posting.
87 : 22188 : void remove_posting(Xapian::docid did, Xapian::termcount wdf) {
88 : 22188 : --tf_delta;
89 : 22188 : cf_delta -= wdf;
90 : : // Remove did from term's postlist.
91 : 22188 : pl_changes[did] = DELETED_POSTING;
92 : 22188 : }
93 : :
94 : : /// Update a posting.
95 : 12 : void update_posting(Xapian::docid did, Xapian::termcount old_wdf,
96 : : Xapian::termcount new_wdf) {
97 : 12 : cf_delta += new_wdf - old_wdf;
98 : 12 : pl_changes[did] = new_wdf;
99 : 12 : }
100 : :
101 : : /// Get the term frequency delta.
102 : 21855 : Xapian::termcount_diff get_tfdelta() const { return tf_delta; }
103 : :
104 : : /// Get the collection frequency delta.
105 : 21492 : Xapian::termcount_diff get_cfdelta() const { return cf_delta; }
106 : : };
107 : :
108 : : /// Buffered changes to postlists.
109 : : std::map<std::string, PostingChanges> postlist_changes;
110 : :
111 : : public:
112 : : /// Buffered changes to document lengths.
113 : : std::map<Xapian::docid, Xapian::termcount> doclen_changes;
114 : :
115 : : public:
116 : 776639 : void add_posting(Xapian::docid did, const std::string & term,
117 : : Xapian::doccount wdf) {
118 : 776639 : std::map<std::string, PostingChanges>::iterator i;
119 : 776639 : i = postlist_changes.find(term);
120 [ + + ]: 776639 : if (i == postlist_changes.end()) {
121 : : postlist_changes.insert(
122 : 21410 : std::make_pair(term, PostingChanges(did, wdf)));
123 : : } else {
124 : 755229 : i->second.add_posting(did, wdf);
125 : : }
126 : 776639 : }
127 : :
128 : 22308 : void remove_posting(Xapian::docid did, const std::string & term,
129 : : Xapian::doccount wdf) {
130 : 22308 : std::map<std::string, PostingChanges>::iterator i;
131 : 22308 : i = postlist_changes.find(term);
132 [ + + ]: 22308 : if (i == postlist_changes.end()) {
133 : : postlist_changes.insert(
134 : 120 : std::make_pair(term, PostingChanges(did, wdf, false)));
135 : : } else {
136 : 22188 : i->second.remove_posting(did, wdf);
137 : : }
138 : 22308 : }
139 : :
140 : 36 : void update_posting(Xapian::docid did, const std::string & term,
141 : : Xapian::termcount old_wdf,
142 : : Xapian::termcount new_wdf) {
143 : 36 : std::map<std::string, PostingChanges>::iterator i;
144 : 36 : i = postlist_changes.find(term);
145 [ + + ]: 36 : if (i == postlist_changes.end()) {
146 : : postlist_changes.insert(
147 : 24 : std::make_pair(term, PostingChanges(did, old_wdf, new_wdf)));
148 : : } else {
149 : 12 : i->second.update_posting(did, old_wdf, new_wdf);
150 : : }
151 : 36 : }
152 : :
153 : 152 : void clear() {
154 : 152 : doclen_changes.clear();
155 : 152 : postlist_changes.clear();
156 : 152 : }
157 : :
158 : 68295 : void set_doclength(Xapian::docid did, Xapian::termcount doclen, bool add) {
159 : : if (add) {
160 : : Assert(doclen_changes.find(did) == doclen_changes.end() || doclen_changes[did] == DELETED_POSTING);
161 : : }
162 : 68295 : doclen_changes[did] = doclen;
163 : 68295 : }
164 : :
165 : 9891 : void delete_doclength(Xapian::docid did) {
166 : : Assert(doclen_changes.find(did) == doclen_changes.end() || doclen_changes[did] != DELETED_POSTING);
167 : 9891 : doclen_changes[did] = DELETED_POSTING;
168 : 9891 : }
169 : :
170 : 72454 : bool get_doclength(Xapian::docid did, Xapian::termcount & doclen) const {
171 : 72454 : std::map<Xapian::docid, Xapian::termcount>::const_iterator i;
172 : 72454 : i = doclen_changes.find(did);
173 [ + + ]: 72454 : if (i == doclen_changes.end())
174 : 68709 : return false;
175 [ + + ]: 3745 : if (rare(i->second == DELETED_POSTING))
176 : 6 : throw Xapian::DocNotFoundError("Document not found: " + str(did));
177 : 3739 : doclen = i->second;
178 : 72448 : return true;
179 : : }
180 : :
181 : : /// Flush document length changes.
182 : : void flush_doclengths(BrassPostListTable & table);
183 : :
184 : : /// Flush postlist changes for @a term.
185 : : void flush_post_list(BrassPostListTable & table, const std::string & term);
186 : :
187 : : /// Flush postlist changes for all terms.
188 : : void flush_all_post_lists(BrassPostListTable & table);
189 : :
190 : : /// Flush postlist changes for all terms which start with @a pfx.
191 : : void flush_post_lists(BrassPostListTable & table, const std::string & pfx);
192 : :
193 : : /// Flush all changes.
194 : : void flush(BrassPostListTable & table);
195 : :
196 : 2171 : Xapian::termcount_diff get_tfdelta(const std::string & term) const {
197 : 2171 : std::map<std::string, PostingChanges>::const_iterator i;
198 : 2171 : i = postlist_changes.find(term);
199 [ + + ]: 2171 : if (i == postlist_changes.end())
200 : 1865 : return 0;
201 : 2171 : return i->second.get_tfdelta();
202 : : }
203 : :
204 : 497 : Xapian::termcount_diff get_cfdelta(const std::string & term) const {
205 : 497 : std::map<std::string, PostingChanges>::const_iterator i;
206 : 497 : i = postlist_changes.find(term);
207 [ + + ]: 497 : if (i == postlist_changes.end())
208 : 437 : return 0;
209 : 497 : return i->second.get_cfdelta();
210 : : }
211 : : };
212 : :
213 : : #endif // XAPIAN_INCLUDED_BRASS_INVERTER_H
|