Factor out UUID handling into new uuid class
[xapian.git] / xapian-core / backends / glass / glass_version.h
blob4eacc029c4cd8a6a2110252b84121900b3c34573
1 /** @file glass_version.h
2 * @brief GlassVersion class
3 */
4 /* Copyright (C) 2006,2007,2008,2009,2010,2013,2014,2015,2016,2018 Olly Betts
5 * Copyright (C) 2011 Dan Colish
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.
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.
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
22 #ifndef XAPIAN_INCLUDED_GLASS_VERSION_H
23 #define XAPIAN_INCLUDED_GLASS_VERSION_H
25 #include "glass_changes.h"
26 #include "glass_defs.h"
28 #include "omassert.h"
30 #include <cstring>
31 #include <string>
33 #include "backends/uuids.h"
34 #include "internaltypes.h"
35 #include "xapian/types.h"
37 namespace Glass {
39 class RootInfo {
40 glass_block_t root;
41 unsigned level;
42 glass_tablesize_t num_entries;
43 bool root_is_fake;
44 bool sequential;
45 unsigned blocksize;
46 /// Should be >= 4 or 0 for no compression.
47 uint4 compress_min;
48 std::string fl_serialised;
50 public:
51 void init(unsigned blocksize_, uint4 compress_min_);
53 void serialise(std::string &s) const;
55 bool unserialise(const char ** p, const char * end);
57 glass_block_t get_root() const { return root; }
58 int get_level() const { return int(level); }
59 glass_tablesize_t get_num_entries() const { return num_entries; }
60 bool get_root_is_fake() const { return root_is_fake; }
61 bool get_sequential() const { return sequential; }
62 unsigned get_blocksize() const {
63 AssertRel(blocksize,>=,GLASS_MIN_BLOCKSIZE);
64 AssertRel(blocksize,<=,GLASS_MAX_BLOCKSIZE);
65 return blocksize;
67 uint4 get_compress_min() const { return compress_min; }
68 const std::string & get_free_list() const { return fl_serialised; }
70 void set_level(int level_) { level = unsigned(level_); }
71 void set_num_entries(glass_tablesize_t n) { num_entries = n; }
72 void set_root_is_fake(bool f) { root_is_fake = f; }
73 void set_sequential(bool f) { sequential = f; }
74 void set_root(glass_block_t root_) { root = root_; }
75 void set_blocksize(unsigned b) {
76 AssertRel(b,>=,GLASS_MIN_BLOCKSIZE);
77 AssertRel(b,<=,GLASS_MAX_BLOCKSIZE);
78 blocksize = b;
80 void set_free_list(const std::string & s) { fl_serialised = s; }
85 using Glass::RootInfo;
87 /** The GlassVersion class manages the revision files.
89 * The "iamglass" file (currently) contains a "magic" string identifying
90 * that this is a glass database, a database format version number, the UUID
91 * of the database, the revision of the database, and the root block info for
92 * each table.
94 class GlassVersion {
95 glass_revision_number_t rev;
97 RootInfo root[Glass::MAX_];
98 RootInfo old_root[Glass::MAX_];
100 /// The UUID of this database.
101 Uuid uuid;
103 /** File descriptor.
105 * When committing, this hold the file descriptor of the new changes file
106 * between the call to the write() and sync() methods.
108 * For a single-file database (when db_dir.empty()), this holds the fd of
109 * that file for use in read().
111 int fd;
113 /** Offset into the file at which the version data starts.
115 * Will be 0, except for an embedded multi-file database.
117 off_t offset;
119 /// The database directory.
120 std::string db_dir;
122 GlassChanges * changes;
124 /// The number of documents in the database.
125 Xapian::doccount doccount;
127 /// The total of the lengths of all documents in the database.
128 Xapian::totallength total_doclen;
130 /// Greatest document id ever used in this database.
131 Xapian::docid last_docid;
133 /// A lower bound on the smallest document length in this database.
134 Xapian::termcount doclen_lbound;
136 /// An upper bound on the greatest document length in this database.
137 Xapian::termcount doclen_ubound;
139 /// An upper bound on the greatest wdf in this database.
140 Xapian::termcount wdf_ubound;
142 /// An upper bound on the spelling wordfreq in this database.
143 Xapian::termcount spelling_wordfreq_ubound;
145 /// Oldest changeset removed when max_changesets is set
146 mutable glass_revision_number_t oldest_changeset;
148 /// The serialised database stats.
149 std::string serialised_stats;
151 // Serialise the database stats.
152 void serialise_stats();
154 // Unserialise the database stats.
155 void unserialise_stats();
157 public:
158 explicit GlassVersion(const std::string & db_dir_ = std::string())
159 : rev(0), fd(-1), offset(0), db_dir(db_dir_), changes(NULL),
160 doccount(0), total_doclen(0), last_docid(0),
161 doclen_lbound(0), doclen_ubound(0),
162 wdf_ubound(0), spelling_wordfreq_ubound(0),
163 oldest_changeset(0) { }
165 explicit GlassVersion(int fd_);
167 ~GlassVersion();
169 /** Create the version file. */
170 void create(unsigned blocksize);
172 void set_changes(GlassChanges * changes_) { changes = changes_; }
174 /** Read the version file and check it's a version we understand.
176 * On failure, an exception is thrown.
178 void read();
180 void cancel();
182 const std::string write(glass_revision_number_t new_rev, int flags);
184 bool sync(const std::string & tmpfile,
185 glass_revision_number_t new_rev, int flags);
187 glass_revision_number_t get_revision() const { return rev; }
189 const RootInfo & get_root(Glass::table_type tbl) const {
190 return root[tbl];
193 RootInfo * root_to_set(Glass::table_type tbl) {
194 return &root[tbl];
197 /// Return pointer to 16 byte UUID.
198 const char * get_uuid() const {
199 return uuid.data();
202 /// Return UUID in the standard 36 character string format.
203 std::string get_uuid_string() const {
204 return uuid.to_string();
207 Xapian::doccount get_doccount() const { return doccount; }
209 Xapian::totallength get_total_doclen() const { return total_doclen; }
211 Xapian::docid get_last_docid() const { return last_docid; }
213 Xapian::termcount get_doclength_lower_bound() const {
214 return doclen_lbound;
217 Xapian::termcount get_doclength_upper_bound() const {
218 return doclen_ubound;
221 Xapian::termcount get_wdf_upper_bound() const { return wdf_ubound; }
223 Xapian::termcount get_spelling_wordfreq_upper_bound() const {
224 return spelling_wordfreq_ubound;
227 glass_revision_number_t get_oldest_changeset() const {
228 return oldest_changeset;
231 void set_last_docid(Xapian::docid did) { last_docid = did; }
233 void set_oldest_changeset(glass_revision_number_t changeset) const {
234 oldest_changeset = changeset;
237 void set_spelling_wordfreq_upper_bound(Xapian::termcount ub) {
238 spelling_wordfreq_ubound = ub;
241 void add_document(Xapian::termcount doclen) {
242 ++doccount;
243 if (total_doclen == 0 || (doclen && doclen < doclen_lbound))
244 doclen_lbound = doclen;
245 if (doclen > doclen_ubound)
246 doclen_ubound = doclen;
247 total_doclen += doclen;
250 void delete_document(Xapian::termcount doclen) {
251 --doccount;
252 total_doclen -= doclen;
253 // If the database no longer contains any postings, we can reset
254 // doclen_lbound, doclen_ubound and wdf_ubound.
255 if (total_doclen == 0) {
256 doclen_lbound = 0;
257 doclen_ubound = 0;
258 wdf_ubound = 0;
262 void check_wdf(Xapian::termcount wdf) {
263 if (wdf > wdf_ubound) wdf_ubound = wdf;
266 Xapian::docid get_next_docid() { return ++last_docid; }
268 /** Merge the database stats.
270 * Used by compaction.
272 void merge_stats(const GlassVersion & o);
274 bool single_file() const { return db_dir.empty(); }
276 off_t get_offset() const { return offset; }
279 #endif // XAPIAN_INCLUDED_GLASS_VERSION_H