1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-30 07:23:07 +03:00

Provider type abstraction, partially completed.

This commit is contained in:
Teemu Ollakka
2018-06-09 23:28:02 +03:00
parent 2cecb3defe
commit e74b214c9c
15 changed files with 646 additions and 263 deletions

View File

@ -5,15 +5,228 @@
#ifndef WSREP_PROVIDER_HPP
#define WSREP_PROVIDER_HPP
// #include "provider_impl.hpp"
#include "key.hpp"
#include "data.hpp"
#include "client_id.hpp"
#include "transaction_id.hpp"
#include <wsrep_api.h>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <ostream>
namespace wsrep
{
/*! \class seqno
*
* Sequence number type.
*
* By convention, nil value is zero, negative values are not allowed.
* Relation operators are restricted to < and > on purpose to
* enforce correct use.
*/
class seqno
{
public:
seqno()
: seqno_()
{ }
template <typename I>
seqno(I seqno)
: seqno_(seqno)
{
assert(seqno_ >= 0);
}
long long get() const
{
return seqno_;
}
bool nil() const
{
return (seqno_ == 0);
}
bool operator<(seqno other) const
{
return (seqno_ < other.seqno_);
}
bool operator>(seqno other) const
{
return (seqno_ > other.seqno_);
}
seqno operator+(seqno other) const
{
return (seqno_ + other.seqno_);
}
static seqno undefined() { return 0; }
private:
long long seqno_;
};
static inline std::ostream& operator<<(std::ostream& os, wsrep::seqno seqno)
{
return (os << seqno.get());
}
class id
{
public:
enum type
{
none,
string,
uuid
};
id()
: type_(none)
, data_()
{ }
id(const std::string&);
id (const void* data, size_t data_size)
: type_()
, data_()
{
assert(data_size <= 16);
std::memcpy(data_, data, data_size);
}
#if 0
void assign(const void* data, size_t data_size)
{
assert(data_size == 16);
memcpy(data_, data, data_size);
}
#endif
bool operator<(const id& other) const
{
return (std::memcmp(data_, other.data_, sizeof(data_)) < 0);
}
bool operator==(const id& other) const
{
return (std::memcmp(data_, other.data_, sizeof(data_)) == 0);
}
private:
enum type type_;
unsigned char data_[16];
};
class gtid
{
public:
gtid()
: id_()
, seqno_()
{ }
gtid(const wsrep::id& id, wsrep::seqno seqno)
: id_(id)
, seqno_(seqno)
{ }
const wsrep::id& id() const { return id_; }
wsrep::seqno seqno() const { return seqno_ ; }
private:
wsrep::id id_;
wsrep::seqno seqno_;
};
class stid
{
public:
stid()
: server_id_()
, transaction_id_()
, client_id_()
{ }
stid(const wsrep::id& server_id,
wsrep::transaction_id transaction_id,
wsrep::client_id client_id)
: server_id_(server_id)
, transaction_id_(transaction_id)
, client_id_(client_id)
{ }
const wsrep::id& server_id() const { return server_id_; }
wsrep::transaction_id transaction_id() const
{ return transaction_id_; }
wsrep::client_id client_id() const { return client_id_; }
private:
wsrep::id server_id_;
wsrep::transaction_id transaction_id_;
wsrep::client_id client_id_;
};
class ws_handle
{
public:
ws_handle()
: transaction_id_()
, opaque_()
{ }
ws_handle(wsrep::transaction_id id)
: transaction_id_(id)
, opaque_()
{ }
ws_handle(wsrep::transaction_id id,
void* opaque)
: transaction_id_(id)
, opaque_(opaque)
{ }
wsrep::transaction_id transaction_id() const
{ return transaction_id_; }
void* opaque() const { return opaque_; }
private:
wsrep::transaction_id transaction_id_;
void* opaque_;
};
class ws_meta
{
public:
ws_meta()
: gtid_()
, stid_()
, depends_on_()
, flags_()
{ }
ws_meta(const wsrep::gtid& gtid,
const wsrep::stid& stid,
wsrep::seqno depends_on,
int flags)
: gtid_(gtid)
, stid_(stid)
, depends_on_(depends_on)
, flags_(flags)
{ }
wsrep::transaction_id transaction_id() const
{
return stid_.transaction_id();
}
wsrep::seqno seqno() const
{
return gtid_.seqno();
}
private:
wsrep::gtid gtid_;
wsrep::stid stid_;
wsrep::seqno depends_on_;
int flags_;
};
// Abstract interface for provider implementations
class provider
{
@ -33,6 +246,50 @@ namespace wsrep
std::string name_;
std::string value_;
};
/*!
* Return value enumeration
*/
enum status
{
/*! Success */
success,
/*! Warning*/
error_warning,
/*! Transaction was not found from provider */
error_transaction_missing,
/*! Certification failed */
error_certification_failed,
/*! Transaction was BF aborted */
error_bf_abort,
/*! Transaction size exceeded */
error_size_exceeded,
/*! Connectivity to cluster lost */
error_connection_failed,
/*! Internal provider failure, provider must be reinitialized */
error_provider_failed,
/*! Fatal error, server must abort */
error_fatal,
/*! Requested functionality is not implemented by the provider */
error_not_implemented,
/*! Operation is not allowed */
error_not_allowed,
/*! Unknown error code from the provider */
error_unknown
};
struct flag
{
static const int start_transaction = (1 << 0);
static const int commit = (1 << 1);
static const int rollback = (1 << 2);
static const int isolation = (1 << 3);
static const int pa_unsafe = (1 << 4);
static const int commutative = (1 << 5);
static const int native = (1 << 6);
static const int snapshot = (1 << 7);
};
virtual ~provider() { }
// Provider state management
virtual int connect(const std::string& cluster_name,
@ -43,16 +300,16 @@ namespace wsrep
// Applier interface
virtual wsrep_status_t run_applier(void* applier_ctx) = 0;
virtual enum status run_applier(void* applier_ctx) = 0;
// Write set replication
// TODO: Rename to assing_read_view()
virtual int start_transaction(wsrep_ws_handle_t*) = 0;
virtual int append_key(wsrep_ws_handle_t*, const wsrep_key_t*) = 0;
virtual int append_data(wsrep_ws_handle_t*, const wsrep_buf_t*) = 0;
virtual wsrep_status_t
certify(wsrep_conn_id_t, wsrep_ws_handle_t*,
uint32_t,
wsrep_trx_meta_t*) = 0;
virtual int start_transaction(wsrep::ws_handle&) = 0;
virtual int append_key(wsrep::ws_handle&, const wsrep::key&) = 0;
virtual int append_data(wsrep::ws_handle&, const wsrep::data&) = 0;
virtual enum status
certify(wsrep::client_id, wsrep::ws_handle&,
int,
wsrep::ws_meta&) = 0;
/*!
* BF abort a transaction inside provider.
*
@ -63,25 +320,25 @@ namespace wsrep
*
* @return wsrep_status_t
*/
virtual wsrep_status_t bf_abort(wsrep_seqno_t bf_seqno,
wsrep_trx_id_t victim_trx,
wsrep_seqno_t* victim_seqno) = 0;
virtual int rollback(const wsrep_trx_id_t) = 0;
virtual wsrep_status commit_order_enter(const wsrep_ws_handle_t*,
const wsrep_trx_meta_t*) = 0;
virtual int commit_order_leave(const wsrep_ws_handle_t*,
const wsrep_trx_meta_t*) = 0;
virtual int release(wsrep_ws_handle_t*) = 0;
virtual enum status bf_abort(wsrep::seqno bf_seqno,
wsrep::transaction_id victim_trx,
wsrep::seqno& victim_seqno) = 0;
virtual int rollback(wsrep::transaction_id) = 0;
virtual enum status commit_order_enter(const wsrep::ws_handle&,
const wsrep::ws_meta&) = 0;
virtual int commit_order_leave(const wsrep::ws_handle&,
const wsrep::ws_meta&) = 0;
virtual int release(wsrep::ws_handle&) = 0;
/*!
* Replay a transaction.
*
* @return Zero in case of success, non-zero on failure.
*/
virtual int replay(wsrep_ws_handle_t* ws_handle, void* applier_ctx) = 0;
virtual int replay(wsrep::ws_handle& ws_handle, void* applier_ctx) = 0;
virtual int sst_sent(const wsrep_gtid_t&, int) = 0;
virtual int sst_received(const wsrep_gtid_t&, int) = 0;
virtual int sst_sent(const wsrep::gtid&, int) = 0;
virtual int sst_received(const wsrep::gtid&, int) = 0;
virtual std::vector<status_variable> status() const = 0;