29 #include "../flint_lock.h" 70 std::fill_n(
fds,
sizeof(
fds) /
sizeof(
fds[0]), -1);
80 #if 0 // FIXME: close or keep open? 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());
196 db_path += dbnames + table * (11 +
CONST_STRLEN(GLASS_TABLE_EXTENSION));
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);
The Xapian namespace contains public interfaces for the Xapian library.
void throw_databaselockerror(FlintLock::reason why, const std::string &db_dir, const std::string &explanation) const
Throw Xapian::DatabaseLockError.
Define the XAPIAN_NORETURN macro.
A RemoteConnection object provides a bidirectional connection to another RemoteConnection object on a...
RemoteConnection class used by the remote backend.
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 check_revision_at_least(const std::string &rev, const std::string &target) const
Virtual methods of DatabaseReplicator.
XAPIAN_REVISION_TYPE rev
Revision number of a database.
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.
Internal definitions for glass database replication.
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.
The GlassVersion class manages the revision files.
double end_time(double timeout)
Return the end time for a timeout in timeout seconds.
int fds[Glass::MAX_]
File descriptors for writing to each table.
static const char * dbnames
Definitions, types, etc for use inside glass.
Convert types to std::string.
std::string db_dir
Path of database.
#define GLASS_TABLE_EXTENSION
Glass table extension.
GlassDatabaseReplicator(const std::string &db_dir_)
#define REASONABLE_CHANGESET_SIZE
#define CHANGES_MAGIC_STRING
Hierarchy of classes which Xapian can throw as exceptions.
class wrapper around zlib
std::string apply_changeset_from_conn(RemoteConnection &conn, double end_time, bool valid) const
Virtual methods of DatabaseReplicator.
static void throw_connection_closed_unexpectedly()
int get_message_chunk(std::string &result, size_t at_least, double end_time)
Read a chunk of a message from fdin.
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.
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.
#define CONST_STRLEN(S)
Returns the length of a string constant.
bool startswith(const std::string &s, char pfx)
~GlassDatabaseReplicator()
void read()
Read the version file and check it's a version we understand.
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
int get_message_chunked(double end_time)
Prepare to read one message from fdin in chunks.
Replication protocol version and message numbers.
Indicates a problem communicating with a remote database.
Pack types into strings and unpack them again.
Wrappers for low-level POSIX I/O routines.
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.
std::string get_uuid() const
Virtual methods of DatabaseReplicator.
reason lock(bool exclusive, bool wait, std::string &explanation)
Attempt to obtain the lock.
Support for glass database replication.
void process_changeset_chunk_version(std::string &buf, RemoteConnection &conn, double end_time) const
Process a chunk which holds a version file.
DatabaseError indicates some sort of database related error.
glass_revision_number_t get_revision() const
std::string get_uuid_string() const
Return UUID in the standard 36 character string format.
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)