Branch data Line data Source code
1 : : /** @file honey_version.h
2 : : * @brief HoneyVersion class
3 : : */
4 : : /* Copyright (C) 2006,2007,2008,2009,2010,2013,2014,2015,2016,2018 Olly Betts
5 : : * Copyright (C) 2011 Dan Colish
6 : : *
7 : : * This program is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License as published by
9 : : * the Free Software Foundation; either version 2 of the License, or
10 : : * (at your option) any later version.
11 : : *
12 : : * This program is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program; if not, write to the Free Software
19 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 : : */
21 : :
22 : : #ifndef XAPIAN_INCLUDED_HONEY_VERSION_H
23 : : #define XAPIAN_INCLUDED_HONEY_VERSION_H
24 : :
25 : : #include "honey_defs.h"
26 : :
27 : : #include "omassert.h"
28 : :
29 : : #include <algorithm>
30 : : #include <cstring>
31 : : #include <string>
32 : :
33 : : #include "backends/uuids.h"
34 : : #include "internaltypes.h"
35 : : #include "min_non_zero.h"
36 : : #include "xapian/types.h"
37 : :
38 : : namespace Honey {
39 : :
40 : 35760 : class RootInfo {
41 : : off_t offset;
42 : : off_t root;
43 : : honey_tablesize_t num_entries;
44 : : /// Should be >= 4 or 0 for no compression.
45 : : uint4 compress_min;
46 : : std::string fl_serialised;
47 : :
48 : : public:
49 : : void init(uint4 compress_min_);
50 : :
51 : : void serialise(std::string &s) const;
52 : :
53 : : bool unserialise(const char ** p, const char * end);
54 : :
55 : 3640 : off_t get_offset() const { return offset; }
56 : 3640 : off_t get_root() const { return root; }
57 : 3640 : honey_tablesize_t get_num_entries() const { return num_entries; }
58 : 5952 : uint4 get_compress_min() const { return compress_min; }
59 : 16 : const std::string & get_free_list() const { return fl_serialised; }
60 : :
61 : 1164 : void set_num_entries(honey_tablesize_t n) { num_entries = n; }
62 : 8 : void set_offset(off_t offset_) { offset = offset_; }
63 : 1164 : void set_root(off_t root_) { root = root_; }
64 : 16 : void set_free_list(const std::string & s) { fl_serialised = s; }
65 : : };
66 : :
67 : : }
68 : :
69 : : /** Maximum size to allow for honey version file data in single file DB. */
70 : : #define HONEY_VERSION_MAX_SIZE 1024
71 : :
72 : : /** The HoneyVersion class manages the revision files.
73 : : *
74 : : * The "iamhoney" file (currently) contains a "magic" string identifying
75 : : * that this is a honey database, a database format version number, the UUID
76 : : * of the database, the revision of the database, and the root block info for
77 : : * each table.
78 : : */
79 : : class HoneyVersion {
80 : : honey_revision_number_t rev;
81 : :
82 : : Honey::RootInfo root[Honey::MAX_];
83 : : Honey::RootInfo old_root[Honey::MAX_];
84 : :
85 : : /// The UUID of this database.
86 : : Uuid uuid;
87 : :
88 : : /** File descriptor.
89 : : *
90 : : * When committing, this hold the file descriptor of the new changes file
91 : : * between the call to the write() and sync() methods.
92 : : *
93 : : * For a single-file database (when db_dir.empty()), this holds the fd of
94 : : * that file for use in read().
95 : : */
96 : : int fd;
97 : :
98 : : /** Offset into the file at which the version data starts.
99 : : *
100 : : * Will be 0, except for an embedded multi-file database.
101 : : */
102 : : off_t offset;
103 : :
104 : : /// The database directory.
105 : : std::string db_dir;
106 : :
107 : : /// The number of documents in the database.
108 : : Xapian::doccount doccount;
109 : :
110 : : /// The total of the lengths of all documents in the database.
111 : : Xapian::totallength total_doclen;
112 : :
113 : : /// Greatest document id ever used in this database.
114 : : Xapian::docid last_docid;
115 : :
116 : : /// A lower bound on the smallest document length in this database.
117 : : Xapian::termcount doclen_lbound;
118 : :
119 : : /// An upper bound on the greatest document length in this database.
120 : : Xapian::termcount doclen_ubound;
121 : :
122 : : /// An upper bound on the greatest wdf in this database.
123 : : Xapian::termcount wdf_ubound;
124 : :
125 : : /// An upper bound on the spelling wordfreq in this database.
126 : : Xapian::termcount spelling_wordfreq_ubound;
127 : :
128 : : /// Oldest changeset removed when max_changesets is set
129 : : mutable honey_revision_number_t oldest_changeset;
130 : :
131 : : /** A lower bound on the number of unique terms in a document in this
132 : : * database.
133 : : */
134 : : Xapian::termcount uniq_terms_lbound;
135 : :
136 : : /** An upper bound on the number of unique terms in a document in this
137 : : * database.
138 : : */
139 : : Xapian::termcount uniq_terms_ubound;
140 : :
141 : : /// The serialised database stats.
142 : : std::string serialised_stats;
143 : :
144 : : // Serialise the database stats.
145 : : void serialise_stats();
146 : :
147 : : // Unserialise the database stats.
148 : : void unserialise_stats();
149 : :
150 : : public:
151 : 593 : explicit HoneyVersion(const std::string & db_dir_ = std::string())
152 : : : rev(0), fd(-1), offset(0), db_dir(db_dir_),
153 : : doccount(0), total_doclen(0), last_docid(0),
154 : : doclen_lbound(0), doclen_ubound(0),
155 : : wdf_ubound(0), spelling_wordfreq_ubound(0),
156 : : oldest_changeset(0),
157 [ + - ][ + + ]: 7709 : uniq_terms_lbound(0), uniq_terms_ubound(0) { }
[ + - ][ + + ]
[ + - ][ + - ]
[ # # # #
# # # # #
# # # # #
# # ]
158 : :
159 : : explicit HoneyVersion(int fd_);
160 : :
161 : : ~HoneyVersion();
162 : :
163 : : /** Create the version file. */
164 : : void create();
165 : :
166 : : /** Read the version file and check it's a version we understand.
167 : : *
168 : : * On failure, an exception is thrown.
169 : : */
170 : : void read();
171 : :
172 : : void cancel();
173 : :
174 : : const std::string write(honey_revision_number_t new_rev, int flags);
175 : :
176 : : bool sync(const std::string & tmpfile,
177 : : honey_revision_number_t new_rev, int flags);
178 : :
179 : 620 : honey_revision_number_t get_revision() const { return rev; }
180 : :
181 : 1820 : const Honey::RootInfo& get_root(Honey::table_type tbl) const {
182 : 1820 : return root[tbl];
183 : : }
184 : :
185 : 1164 : Honey::RootInfo* root_to_set(Honey::table_type tbl) {
186 : 1164 : return &root[tbl];
187 : : }
188 : :
189 : : /// Return pointer to 16 byte UUID.
190 : : const char * get_uuid() const {
191 : : return uuid.data();
192 : : }
193 : :
194 : : /// Return UUID in the standard 36 character string format.
195 : 10 : std::string get_uuid_string() const {
196 : 10 : return uuid.to_string();
197 : : }
198 : :
199 : 220060 : Xapian::doccount get_doccount() const { return doccount; }
200 : :
201 : 107962 : Xapian::totallength get_total_doclen() const { return total_doclen; }
202 : :
203 : 19024774 : Xapian::docid get_last_docid() const { return last_docid; }
204 : :
205 : 77026 : Xapian::termcount get_doclength_lower_bound() const {
206 : 77026 : return doclen_lbound;
207 : : }
208 : :
209 : 727 : Xapian::termcount get_doclength_upper_bound() const {
210 : 727 : return doclen_ubound;
211 : : }
212 : :
213 : 100770 : Xapian::termcount get_wdf_upper_bound() const { return wdf_ubound; }
214 : :
215 : 15 : Xapian::termcount get_spelling_wordfreq_upper_bound() const {
216 : 15 : return spelling_wordfreq_ubound;
217 : : }
218 : :
219 : : honey_revision_number_t get_oldest_changeset() const {
220 : : return oldest_changeset;
221 : : }
222 : :
223 : 583 : Xapian::termcount get_unique_terms_lower_bound() const {
224 : 583 : return uniq_terms_lbound;
225 : : }
226 : :
227 : 583 : Xapian::termcount get_unique_terms_upper_bound() const {
228 : 583 : return uniq_terms_ubound;
229 : : }
230 : :
231 : 294 : void set_last_docid(Xapian::docid did) { last_docid = did; }
232 : :
233 : : void set_oldest_changeset(honey_revision_number_t changeset) const {
234 : : oldest_changeset = changeset;
235 : : }
236 : :
237 : : void set_spelling_wordfreq_upper_bound(Xapian::termcount ub) {
238 : : spelling_wordfreq_ubound = ub;
239 : : }
240 : :
241 : 566 : void set_unique_terms_lower_bound(Xapian::termcount ub) {
242 : 566 : uniq_terms_lbound = ub;
243 : 566 : }
244 : :
245 : 566 : void set_unique_terms_upper_bound(Xapian::termcount ub) {
246 : 566 : uniq_terms_ubound = ub;
247 : 566 : }
248 : :
249 : : void add_document(Xapian::termcount doclen) {
250 : : ++doccount;
251 : : doclen_lbound = min_non_zero(doclen_lbound, doclen);
252 : : doclen_ubound = std::max(doclen_ubound, doclen);
253 : : total_doclen += doclen;
254 : : }
255 : :
256 : : void delete_document(Xapian::termcount doclen) {
257 : : --doccount;
258 : : total_doclen -= doclen;
259 : : // If the database no longer contains any postings, we can reset
260 : : // doclen_lbound, doclen_ubound and wdf_ubound.
261 : : if (total_doclen == 0) {
262 : : doclen_lbound = 0;
263 : : doclen_ubound = 0;
264 : : wdf_ubound = 0;
265 : : }
266 : : }
267 : :
268 : : void check_wdf(Xapian::termcount wdf) {
269 : : if (wdf > wdf_ubound) wdf_ubound = wdf;
270 : : }
271 : :
272 : : Xapian::docid get_next_docid() { return ++last_docid; }
273 : :
274 : : /** Merge the database stats.
275 : : *
276 : : * Used by compaction.
277 : : */
278 : : void merge_stats(const HoneyVersion & o);
279 : :
280 : : void merge_stats(Xapian::doccount o_doccount,
281 : : Xapian::termcount o_doclen_lbound,
282 : : Xapian::termcount o_doclen_ubound,
283 : : Xapian::termcount o_wdf_ubound,
284 : : Xapian::totallength o_total_doclen,
285 : : Xapian::termcount o_spelling_wordfreq_ubound,
286 : : Xapian::termcount o_uniq_terms_lbound,
287 : : Xapian::termcount o_uniq_terms_ubound);
288 : :
289 : 1780 : bool single_file() const { return db_dir.empty(); }
290 : :
291 : 32 : off_t get_offset() const { return offset; }
292 : : };
293 : :
294 : : #endif // XAPIAN_INCLUDED_HONEY_VERSION_H
|