29 #include "../flint_lock.h"
70 std::fill_n(
fds,
sizeof(
fds) /
sizeof(
fds[0]), -1);
100 const string & target)
const
102 LOGCALL(DB,
bool,
"GlassDatabaseReplicator::check_revision_at_least",
rev | target);
107 const char * ptr =
rev.data();
108 const char * end = ptr +
rev.size();
110 throw NetworkError(
"Invalid revision string supplied to check_revision_at_least");
114 end = ptr + target.size();
116 throw NetworkError(
"Invalid revision string supplied to check_revision_at_least");
119 RETURN(rev_val >= target_val);
127 const char *ptr = buf.data();
128 const char *end = ptr + buf.size();
134 string::size_type size;
136 throw NetworkError(
"Invalid version file size in changeset");
139 buf.erase(0, ptr - buf.data());
149 tmpfile +=
"/v.rtmp";
152 string msg =
"Failed to open ";
161 string version_file =
db_dir;
162 version_file +=
"/iamglass";
164 string msg(
"Couldn't create new version file ");
179 const char *ptr = buf.data();
180 const char *end = ptr + buf.size();
182 unsigned int changeset_blocksize = 2048 << v;
183 if (changeset_blocksize > 65536 ||
184 (changeset_blocksize & (changeset_blocksize - 1))) {
189 throw NetworkError(
"Invalid block number in changeset");
191 buf.erase(0, ptr - buf.data());
199 string msg =
"Failed to open ";
213 io_write_block(fd, buf.data(), changeset_blocksize, block_number);
214 buf.erase(0, changeset_blocksize);
222 LOGCALL(DB,
string,
"GlassDatabaseReplicator::apply_changeset_from_conn", conn |
end_time | valid);
243 const char *ptr = buf.data();
244 const char *end = ptr + buf.size();
251 throw NetworkError(
"Couldn't read a valid version number from changeset");
252 unsigned int changes_version = *ptr++;
260 throw NetworkError(
"Couldn't read a valid start revision from changeset");
262 throw NetworkError(
"Couldn't read a valid end revision from changeset");
264 if (endrev <= startrev)
265 throw NetworkError(
"End revision in changeset is not later than start revision");
278 throw NetworkError(
"Changeset supplied is for wrong revision number");
281 unsigned char changes_type = *ptr++;
282 if (changes_type != 0) {
283 throw NetworkError(
"Unsupported changeset type: " +
str(changes_type));
289 buf.erase(0, ptr - buf.data());
296 end = ptr + buf.size();
307 unsigned char chunk_type = *ptr++;
308 if (chunk_type == 0xff)
310 if (chunk_type == 0xfe) {
312 buf.erase(0, ptr - buf.data());
316 size_t table_code = (chunk_type & 0x07);
320 unsigned char v = (chunk_type >> 3) & 0x0f;
323 buf.erase(0, ptr - buf.data());
341 LOGCALL(DB,
string,
"GlassDatabaseReplicator::get_uuid", NO_ARGS);
#define CHANGES_MAGIC_STRING
#define REASONABLE_CHANGESET_SIZE
reason lock(bool exclusive, bool wait, std::string &explanation)
Attempt to obtain the lock.
void throw_databaselockerror(FlintLock::reason why, const std::string &db_dir, const std::string &explanation) const
Throw Xapian::DatabaseLockError.
void process_changeset_chunk_blocks(Glass::table_type table, unsigned v, std::string &buf, RemoteConnection &conn, double end_time) const
Process a chunk which holds a list of changed blocks in the database.
~GlassDatabaseReplicator()
std::string apply_changeset_from_conn(RemoteConnection &conn, double end_time, bool valid) const
Read and apply the next changeset.
bool check_revision_at_least(const std::string &rev, const std::string &target) const
Virtual methods of DatabaseReplicator.
std::string get_uuid() const
Get a UUID for the replica.
void process_changeset_chunk_version(std::string &buf, RemoteConnection &conn, double end_time) const
Process a chunk which holds a version file.
int fds[Glass::MAX_]
File descriptors for writing to each table.
GlassDatabaseReplicator(const std::string &db_dir_)
std::string db_dir
Path of database.
The GlassVersion class manages the revision files.
glass_revision_number_t get_revision() const
std::string get_uuid_string() const
Return UUID in the standard 36 character string format.
void read()
Read the version file and check it's a version we understand.
A RemoteConnection object provides a bidirectional connection to another RemoteConnection object on a...
int get_message_chunk(std::string &result, size_t at_least, double end_time)
Read a chunk of a message from fdin.
int get_message_chunked(double end_time)
Prepare to read one message from fdin in chunks.
DatabaseError indicates some sort of database related error.
Indicates a problem communicating with a remote database.
class wrapper around zlib
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Hierarchy of classes which Xapian can throw as exceptions.
Wrapper class around a file descriptor to avoid leaks.
static void throw_connection_closed_unexpectedly()
static const char * dbnames
Support for glass database replication.
Definitions, types, etc for use inside glass.
uint4 glass_revision_number_t
The revision number of a glass database.
#define GLASS_TABLE_EXTENSION
Glass table extension.
Internal definitions for glass database replication.
void io_write(int fd, const char *p, size_t n)
Write n bytes from block pointed to by p to 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.
void io_write_block(int fd, const char *p, size_t n, off_t b, off_t o)
Write block b size n bytes from buffer p to file descriptor fd, offset o.
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.
double end_time(double timeout)
Return the end time for a timeout in timeout seconds.
string str(int value)
Convert int to std::string.
The Xapian namespace contains public interfaces for the Xapian library.
XAPIAN_REVISION_TYPE rev
Revision number of a database.
Define the XAPIAN_NORETURN macro.
Pack types into strings and unpack them again.
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.
Provides wrappers with POSIXy semantics.
RemoteConnection class used by the remote backend.
Replication protocol version and message numbers.
Convert types to std::string.
Various handy helpers which std::string really should provide.
#define CONST_STRLEN(S)
Returns the length of a string constant.
bool startswith(const std::string &s, char pfx)