mirror of https://gitee.com/bigwinds/arangodb
Added a virtual base class for traverser engines.
This commit is contained in:
parent
3c183cb24f
commit
a7546b684c
|
@ -42,19 +42,9 @@ static const std::string EDGES = "edges";
|
|||
static const std::string VARIABLES = "variables";
|
||||
static const std::string VERTICES = "vertices";
|
||||
|
||||
TraverserEngine::TraverserEngine(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Slice info)
|
||||
: _opts(nullptr),
|
||||
_query(nullptr),
|
||||
_trx(nullptr),
|
||||
_collections(vocbase) {
|
||||
VPackSlice optsSlice = info.get(OPTIONS);
|
||||
if (optsSlice.isNone() || !optsSlice.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"The body requires a " + OPTIONS + " attribute.");
|
||||
}
|
||||
|
||||
BaseTraverserEngine::BaseTraverserEngine(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Slice info)
|
||||
: _opts(nullptr), _query(nullptr), _trx(nullptr), _collections(vocbase) {
|
||||
VPackSlice shardsSlice = info.get(SHARDS);
|
||||
if (shardsSlice.isNone() || !shardsSlice.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
|
@ -115,7 +105,6 @@ TraverserEngine::TraverserEngine(TRI_vocbase_t* vocbase,
|
|||
"The optional " + VARIABLES + " has to be an array.");
|
||||
}
|
||||
for (auto v : VPackArrayIterator(variablesSlice)) {
|
||||
// TODO do we have to keep the variable somewhere?
|
||||
_query->ast()->variables()->createVariable(v);
|
||||
}
|
||||
}
|
||||
|
@ -123,10 +112,9 @@ TraverserEngine::TraverserEngine(TRI_vocbase_t* vocbase,
|
|||
|
||||
_trx->begin(); // We begin the transaction before we lock.
|
||||
// We also setup indexes before we lock.
|
||||
_opts.reset(new TraverserOptions(_query, optsSlice, edgesSlice));
|
||||
}
|
||||
|
||||
TraverserEngine::~TraverserEngine() {
|
||||
BaseTraverserEngine::~BaseTraverserEngine() {
|
||||
/*
|
||||
auto resolver = _trx->resolver();
|
||||
// TODO Do we need this or will delete trx do this already?
|
||||
|
@ -151,7 +139,7 @@ TraverserEngine::~TraverserEngine() {
|
|||
}
|
||||
}
|
||||
|
||||
void TraverserEngine::getEdges(VPackSlice vertex, size_t depth, VPackBuilder& builder) {
|
||||
void BaseTraverserEngine::getEdges(VPackSlice vertex, size_t depth, VPackBuilder& builder) {
|
||||
// We just hope someone has locked the shards properly. We have no clue... Thanks locking
|
||||
|
||||
TRI_ASSERT(vertex.isString() || vertex.isArray());
|
||||
|
@ -200,7 +188,7 @@ void TraverserEngine::getEdges(VPackSlice vertex, size_t depth, VPackBuilder& bu
|
|||
builder.close();
|
||||
}
|
||||
|
||||
void TraverserEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
|
||||
void BaseTraverserEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
|
||||
// We just hope someone has locked the shards properly. We have no clue...
|
||||
// Thanks locking
|
||||
TRI_ASSERT(vertex.isString() || vertex.isArray());
|
||||
|
@ -248,7 +236,7 @@ void TraverserEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
|
|||
builder.close(); // The outer object
|
||||
}
|
||||
|
||||
void TraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
|
||||
void BaseTraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
|
||||
VPackBuilder& builder) {
|
||||
// We just hope someone has locked the shards properly. We have no clue...
|
||||
// Thanks locking
|
||||
|
@ -305,12 +293,12 @@ void TraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
|
|||
builder.close();
|
||||
}
|
||||
|
||||
void TraverserEngine::smartSearch(VPackSlice,
|
||||
void BaseTraverserEngine::smartSearch(VPackSlice,
|
||||
VPackBuilder&) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ONLY_ENTERPRISE);
|
||||
}
|
||||
|
||||
bool TraverserEngine::lockCollection(std::string const& shard) {
|
||||
bool BaseTraverserEngine::lockCollection(std::string const& shard) {
|
||||
if (_locked.find(shard) != _locked.end()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -329,6 +317,25 @@ bool TraverserEngine::lockCollection(std::string const& shard) {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<arangodb::TransactionContext> TraverserEngine::context() const {
|
||||
std::shared_ptr<arangodb::TransactionContext> BaseTraverserEngine::context() const {
|
||||
return _trx->transactionContext();
|
||||
}
|
||||
|
||||
TraverserEngine::TraverserEngine(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Slice info)
|
||||
: BaseTraverserEngine(vocbase, info) {
|
||||
VPackSlice optsSlice = info.get(OPTIONS);
|
||||
if (optsSlice.isNone() || !optsSlice.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"The body requires a " + OPTIONS + " attribute.");
|
||||
}
|
||||
VPackSlice shardsSlice = info.get(SHARDS);
|
||||
VPackSlice edgesSlice = shardsSlice.get(EDGES);
|
||||
|
||||
_opts.reset(new TraverserOptions(_query, optsSlice, edgesSlice));
|
||||
}
|
||||
|
||||
|
||||
TraverserEngine::~TraverserEngine() {
|
||||
}
|
||||
|
|
|
@ -46,8 +46,7 @@ class Slice;
|
|||
namespace traverser {
|
||||
struct TraverserOptions;
|
||||
|
||||
class TraverserEngine {
|
||||
|
||||
class BaseTraverserEngine {
|
||||
friend class TraverserEngineRegistry;
|
||||
protected:
|
||||
// These are private on purpose.
|
||||
|
@ -56,13 +55,13 @@ class TraverserEngine {
|
|||
// We can get into undefined state if sth.
|
||||
// deletes an engine but the registry
|
||||
// does not get informed properly
|
||||
TraverserEngine(TRI_vocbase_t*, arangodb::velocypack::Slice);
|
||||
BaseTraverserEngine(TRI_vocbase_t*, arangodb::velocypack::Slice);
|
||||
|
||||
public:
|
||||
virtual ~TraverserEngine();
|
||||
virtual ~BaseTraverserEngine();
|
||||
|
||||
// The engine is NOT copyable.
|
||||
TraverserEngine(TraverserEngine const&) = delete;
|
||||
BaseTraverserEngine(BaseTraverserEngine const&) = delete;
|
||||
|
||||
void getEdges(arangodb::velocypack::Slice, size_t,
|
||||
arangodb::velocypack::Builder&);
|
||||
|
@ -80,7 +79,7 @@ class TraverserEngine {
|
|||
|
||||
std::shared_ptr<TransactionContext> context() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::unique_ptr<TraverserOptions> _opts;
|
||||
arangodb::aql::Query* _query;
|
||||
arangodb::Transaction* _trx;
|
||||
|
@ -88,6 +87,22 @@ class TraverserEngine {
|
|||
std::unordered_set<std::string> _locked;
|
||||
std::unordered_map<std::string, std::vector<std::string>> _vertexShards;
|
||||
};
|
||||
|
||||
class TraverserEngine : public BaseTraverserEngine {
|
||||
friend class TraverserEngineRegistry;
|
||||
private:
|
||||
// These are private on purpose.
|
||||
// Only the Registry (friend) is allowed
|
||||
// to create and destroy engines.
|
||||
// We can get into undefined state if sth.
|
||||
// deletes an engine but the registry
|
||||
// does not get informed properly
|
||||
|
||||
TraverserEngine(TRI_vocbase_t*, arangodb::velocypack::Slice);
|
||||
public:
|
||||
~TraverserEngine();
|
||||
};
|
||||
|
||||
} // namespace traverser
|
||||
} // namespace arangodb
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void TraverserEngineRegistry::destroy(TraverserEngineID id) {
|
|||
}
|
||||
|
||||
/// @brief Get the engine with the given id
|
||||
TraverserEngine* TraverserEngineRegistry::get(TraverserEngineID id) {
|
||||
BaseTraverserEngine* TraverserEngineRegistry::get(TraverserEngineID id) {
|
||||
WRITE_LOCKER(writeLocker, _lock);
|
||||
auto e = _engines.find(id);
|
||||
if (e == _engines.end()) {
|
||||
|
|
|
@ -32,13 +32,13 @@ struct TRI_vocbase_t;
|
|||
namespace arangodb {
|
||||
namespace traverser {
|
||||
|
||||
class TraverserEngine;
|
||||
class BaseTraverserEngine;
|
||||
|
||||
/// @brief type of a Traverser Engine Id
|
||||
typedef TRI_voc_tick_t TraverserEngineID;
|
||||
|
||||
class TraverserEngineRegistry {
|
||||
friend class TraverserEngine;
|
||||
friend class BaseTraverserEngine;
|
||||
public:
|
||||
TraverserEngineRegistry() {}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class TraverserEngineRegistry {
|
|||
/// @brief Get the engine with the given ID.
|
||||
/// TODO Test what happens if this pointer
|
||||
/// is requested twice in parallel?
|
||||
TraverserEngine* get(TraverserEngineID);
|
||||
BaseTraverserEngine* get(TraverserEngineID);
|
||||
|
||||
/// @brief Destroys the engine with the given id.
|
||||
void destroy(TraverserEngineID);
|
||||
|
@ -68,11 +68,11 @@ class TraverserEngineRegistry {
|
|||
void destroy(TraverserEngineID, bool doLock);
|
||||
|
||||
struct EngineInfo {
|
||||
bool _isInUse; // Flag if this engine is in use
|
||||
std::unique_ptr<TraverserEngine> _engine; // The real engine
|
||||
bool _isInUse; // Flag if this engine is in use
|
||||
std::unique_ptr<BaseTraverserEngine> _engine; // The real engine
|
||||
|
||||
double _timeToLive; // in seconds
|
||||
double _expires; // UNIX UTC timestamp for expiration
|
||||
double _timeToLive; // in seconds
|
||||
double _expires; // UNIX UTC timestamp for expiration
|
||||
|
||||
EngineInfo(TRI_vocbase_t*, arangodb::velocypack::Slice);
|
||||
~EngineInfo();
|
||||
|
|
|
@ -63,7 +63,7 @@ struct Variable;
|
|||
}
|
||||
|
||||
namespace traverser {
|
||||
class TraverserEngine;
|
||||
class BaseTraverserEngine;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -76,7 +76,7 @@ struct OperationCursor;
|
|||
class TransactionContext;
|
||||
|
||||
class Transaction {
|
||||
friend class traverser::TraverserEngine;
|
||||
friend class traverser::BaseTraverserEngine;
|
||||
|
||||
public:
|
||||
|
||||
|
|
Loading…
Reference in New Issue