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";
302 if (flags & Xapian::DB_DANGEROUS)
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) {
409 RootInfo::init(
unsigned blocksize_,
uint4 compress_min_)
417 blocksize = blocksize_;
418 compress_min = compress_min_;
419 fl_serialised.resize(0);
423 RootInfo::serialise(
string &s)
const 426 unsigned val = level << 2;
427 if (sequential) val |= 0x02;
428 if (root_is_fake) val |= 0x01;
437 RootInfo::unserialise(
const char ** p,
const char * end)
446 auto level_ = val >> 2;
450 sequential = val & 0x02;
451 root_is_fake = val & 0x01;
456 (b & (b - 1)) != 0)) {
462 if (compress_min == 4) {
#define GLASS_VERSION_MAGIC_LEN
Xapian::termcount get_doclength_upper_bound() const
void create(unsigned blocksize)
Create the version file.
bool sync(const std::string &tmpfile, glass_revision_number_t new_rev, int flags)
void io_write(int fd, const char *p, size_t n)
Write n bytes from block pointed to by p to file descriptor fd.
glass_revision_number_t oldest_changeset
Oldest changeset removed when max_changesets is set.
XAPIAN_REVISION_TYPE rev
Revision number of a database.
Xapian::termcount wdf_ubound
An upper bound on the greatest wdf in this database.
off_t offset
Offset into the file at which the version data starts.
#define AssertRel(A, REL, B)
#define VERSION_TO_YEAR(V)
DatabaseOpeningError indicates failure to open a database.
Uuid uuid
The UUID of this database.
RootInfo root[Glass::MAX_]
#define GLASS_MIN_BLOCKSIZE
Minimum B-tree block size.
uint4 glass_revision_number_t
The revision number of a glass database.
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
Provides wrappers with POSIXy semantics.
Constants in the Xapian namespace.
The GlassVersion class manages the revision files.
GlassVersion(const std::string &db_dir_)
void assign(const char *p)
const int DB_FULL_SYNC
Try to ensure changes are really written to disk.
glass_revision_number_t rev
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Convert types to std::string.
#define VERSION_TO_MONTH(V)
static const char GLASS_VERSION_MAGIC[GLASS_VERSION_MAGIC_AND_VERSION_LEN]
#define GLASS_FORMAT_VERSION
Glass format version (date of change):
include <sys/stat.h> with portability enhancements
Hierarchy of classes which Xapian can throw as exceptions.
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
Xapian::termcount get_wdf_upper_bound() const
Xapian::totallength total_doclen
The total of the lengths of all documents in the database.
bool io_full_sync(int fd)
void merge_stats(const GlassVersion &o)
Merge the database stats.
Xapian::termcount get_doclength_lower_bound() const
string str(int value)
Convert int to std::string.
Wrapper class around a file descriptor to avoid leaks.
bool io_tmp_rename(const std::string &tmp_file, const std::string &real_file)
Rename a temporary file to its final position.
static const uint4 compress_min_tab[]
#define VERSION_TO_DAY(V)
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.
std::string serialised_stats
The serialised database stats.
Indicates an attempt to access a database not present.
const int DB_DANGEROUS
Update the database in-place.
void read()
Read the version file and check it's a version we understand.
DatabaseVersionError indicates that a database is in an unsupported format.
const int DB_NO_SYNC
Don't attempt to ensure changes have hit disk.
DatabaseCorruptError indicates database corruption was detected.
RootInfo old_root[Glass::MAX_]
#define GLASS_BTREE_CURSOR_LEVELS
Allow for this many levels in the B-tree.
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
void init(unsigned blocksize_, uint4 compress_min_)
const size_t COMPRESS_MIN
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
void pack_string(std::string &s, const std::string &value)
Append an encoded std::string to a string.
Xapian::termcount spelling_wordfreq_ubound
An upper bound on the spelling wordfreq in this database.
Xapian::totallength get_total_doclen() const
static constexpr unsigned BINARY_SIZE
The size of a UUID in bytes.
Xapian::termcount get_spelling_wordfreq_upper_bound() const
Pack types into strings and unpack them again.
Wrappers for low-level POSIX I/O routines.
void write_block(const char *p, size_t len)
Various handy helpers which std::string really should provide.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
Class for handling UUIDs.
<unistd.h>, but with compat.
Xapian::termcount doclen_ubound
An upper bound on the greatest document length in this database.
Xapian::docid last_docid
Greatest document id ever used in this database.
Various assertion macros.
const char * data() const
Xapian::termcount doclen_lbound
A lower bound on the smallest document length in this database.
bool unpack_string(const char **p, const char *end, std::string &result)
Decode a std::string from a string.
DatabaseError indicates some sort of database related error.
const std::string write(glass_revision_number_t new_rev, int flags)
#define GLASS_VERSION_MAGIC_AND_VERSION_LEN
#define GLASS_MAX_BLOCKSIZE
Maximum B-tree block size.
void serialise(std::string &s) const
std::string db_dir
The database directory.
include <fcntl.h>, but working around broken platforms.
Xapian::doccount doccount
The number of documents in the database.
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Xapian::doccount get_doccount() const