37 #include <sys/types.h>
52 #define GLASS_FORMAT_VERSION DATE_TO_VERSION(2016,03,14)
58 #define DATE_TO_VERSION(Y,M,D) \
59 ((unsigned(Y) - 2014) << 9 | unsigned(M) << 5 | unsigned(D))
60 #define VERSION_TO_YEAR(V) ((unsigned(V) >> 9) + 2014)
61 #define VERSION_TO_MONTH(V) ((unsigned(V) >> 5) & 0x0f)
62 #define VERSION_TO_DAY(V) (unsigned(V) & 0x1f)
64 #define GLASS_VERSION_MAGIC_LEN 14
65 #define GLASS_VERSION_MAGIC_AND_VERSION_LEN 16
68 '\x0f',
'\x0d',
'X',
'a',
'p',
'i',
'a',
'n',
' ',
'G',
'l',
'a',
's',
's',
73 :
rev(0), fd(fd_), offset(0), db_dir(), changes(NULL),
74 doccount(0), total_doclen(0), last_docid(0),
75 doclen_lbound(0), doclen_ubound(0),
76 wdf_ubound(0), spelling_wordfreq_ubound(0),
81 string msg =
"lseek failed on file descriptor ";
103 string msg =
"Failed to rewind file descriptor ";
110 filename +=
"/iamglass";
112 if (
rare(fd_in < 0)) {
113 string msg = filename;
114 msg +=
": Failed to open glass revision file for reading";
115 if (errno == ENOENT || errno == ENOTDIR) {
125 const char * p = buf;
126 const char * end = p +
io_read(fd_in, buf,
sizeof(buf), 33);
141 msg +=
"Database is format version ";
145 msg +=
" but I only understand ";
159 for (
unsigned table_no = 0; table_no <
Glass::MAX_; ++table_no) {
160 if (!
root[table_no].unserialise(&p, end)) {
217 "Bad serialised DB stats (overflowed)" :
218 "Bad serialised DB stats (out of data)";
244 if (o_doclen_lbound > 0) {
264 for (
unsigned table_no = 0; table_no <
Glass::MAX_; ++table_no) {
273 LOGCALL(DB,
const string,
"GlassVersion::write", new_rev|flags);
280 for (
unsigned table_no = 0; table_no <
Glass::MAX_; ++table_no) {
293 tmpfile +=
"/iamglass";
316 changes_buf +=
'\xfe';
340 int fd_to_close =
fd;
346 int save_errno = errno;
347 (void)
close(fd_to_close);
348 if (!tmpfile.empty())
349 (
void)unlink(tmpfile.c_str());
354 if (
close(fd_to_close) != 0) {
355 if (!tmpfile.empty()) {
356 int save_errno = errno;
357 (void)unlink(tmpfile.c_str());
363 if (!tmpfile.empty()) {
370 for (
unsigned table_no = 0; table_no <
Glass::MAX_; ++table_no) {
401 for (
unsigned table_no = 0; table_no <
Glass::MAX_; ++table_no) {
426 unsigned val =
level << 2;
446 auto level_ = val >> 2;
456 (b & (b - 1)) != 0)) {
void write_block(const char *p, size_t len)
The GlassVersion class manages the revision files.
glass_revision_number_t oldest_changeset
Oldest changeset removed when max_changesets is set.
Xapian::termcount spelling_wordfreq_ubound
An upper bound on the spelling wordfreq in this database.
GlassVersion(const std::string &db_dir_)
RootInfo old_root[Glass::MAX_]
Xapian::termcount doclen_ubound
An upper bound on the greatest document length in this database.
off_t offset
Offset into the file at which the version data starts.
const std::string write(glass_revision_number_t new_rev, int flags)
std::string db_dir
The database directory.
Xapian::termcount get_doclength_lower_bound() const
Xapian::docid last_docid
Greatest document id ever used in this database.
Xapian::termcount get_spelling_wordfreq_upper_bound() const
std::string serialised_stats
The serialised database stats.
Uuid uuid
The UUID of this database.
glass_revision_number_t rev
Xapian::totallength total_doclen
The total of the lengths of all documents in the database.
bool sync(const std::string &tmpfile, glass_revision_number_t new_rev, int flags)
Xapian::doccount get_doccount() const
void merge_stats(const GlassVersion &o)
Merge the database stats.
Xapian::termcount get_wdf_upper_bound() const
Xapian::termcount doclen_lbound
A lower bound on the smallest document length in this database.
Xapian::termcount wdf_ubound
An upper bound on the greatest wdf in this database.
Xapian::doccount doccount
The number of documents in the database.
void create(unsigned blocksize)
Create the version file.
RootInfo root[Glass::MAX_]
void read()
Read the version file and check it's a version we understand.
Xapian::totallength get_total_doclen() const
Xapian::termcount get_doclength_upper_bound() const
void init(unsigned blocksize_, uint4 compress_min_)
void serialise(std::string &s) const
bool unserialise(const char **p, const char *end)
std::string fl_serialised
glass_tablesize_t num_entries
uint4 compress_min
Should be >= 4 or 0 for no compression.
static constexpr unsigned BINARY_SIZE
The size of a UUID in bytes.
void assign(const char *p)
const char * data() const
DatabaseCorruptError indicates database corruption was detected.
DatabaseError indicates some sort of database related error.
Indicates an attempt to access a database not present.
DatabaseOpeningError indicates failure to open a database.
DatabaseVersionError indicates that a database is in an unsupported format.
Constants in the Xapian namespace.
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Hierarchy of classes which Xapian can throw as exceptions.
Wrapper class around a file descriptor to avoid leaks.
#define GLASS_BTREE_CURSOR_LEVELS
Allow for this many levels in the B-tree.
#define GLASS_MIN_BLOCKSIZE
Minimum B-tree block size.
uint4 glass_revision_number_t
The revision number of a glass database.
#define GLASS_MAX_BLOCKSIZE
Maximum B-tree block size.
static const char GLASS_VERSION_MAGIC[GLASS_VERSION_MAGIC_AND_VERSION_LEN]
const size_t COMPRESS_MIN
#define GLASS_VERSION_MAGIC_AND_VERSION_LEN
#define VERSION_TO_MONTH(V)
#define VERSION_TO_DAY(V)
#define VERSION_TO_YEAR(V)
#define GLASS_FORMAT_VERSION
Glass format version (date of change):
#define GLASS_VERSION_MAGIC_LEN
static const uint4 compress_min_tab[]
void io_write(int fd, const char *p, size_t n)
Write n bytes from block pointed to by p to file descriptor fd.
size_t io_read(int fd, char *p, size_t n, size_t min)
Read n bytes (or until EOF) into block pointed to by p from file descriptor fd.
bool io_tmp_rename(const std::string &tmp_file, const std::string &real_file)
Rename a temporary file to its final position.
Wrappers for low-level POSIX I/O routines.
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
bool io_full_sync(int fd)
string str(int value)
Convert int to std::string.
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
XAPIAN_REVISION_TYPE rev
Revision number of a database.
const int DB_NO_SYNC
Don't attempt to ensure changes have hit disk.
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
const int DB_FULL_SYNC
Try to ensure changes are really written to disk.
const int DB_DANGEROUS
Update the database in-place.
Various assertion macros.
#define AssertRel(A, REL, B)
Pack types into strings and unpack them again.
bool unpack_string(const char **p, const char *end, std::string &result)
Decode a std::string from a string.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
void pack_string(std::string &s, const std::string &value)
Append an encoded std::string to a string.
Provides wrappers with POSIXy semantics.
include <fcntl.h>, but working around broken platforms.
include <sys/stat.h> with portability enhancements
<unistd.h>, but with compat.
Convert types to std::string.
Various handy helpers which std::string really should provide.
Class for handling UUIDs.