Remove virtual and pimpl from single node
Summary: This diff removes: `SingleNodeRecoveryTransactions`, `TypemapPack` It also removes virtual and/or pimpl from: `SingleNodeCounters`, `StorageGcSingleNode`, `SingleNodeConcurrentIdMapper`, accessors (revert D1510), transaction engine, `GraphDbAccessor`, `GraphDb` Reviewers: msantl, teon.banek Reviewed By: msantl, teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1639
This commit is contained in:
parent
7b70d126f6
commit
4e5fe37dd6
@ -46,7 +46,7 @@ set(mg_single_node_sources
|
||||
storage/common/property_value_store.cpp
|
||||
storage/single_node/record_accessor.cpp
|
||||
storage/single_node/vertex_accessor.cpp
|
||||
transactions/single_node/engine_single_node.cpp
|
||||
transactions/single_node/engine.cpp
|
||||
memgraph_init.cpp
|
||||
)
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "database/counters.hpp"
|
||||
#include "database/distributed/counters.hpp"
|
||||
|
||||
namespace communication::rpc {
|
||||
class Server;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "durability/distributed/snapshooter.hpp"
|
||||
// TODO: Why do we depend on query here?
|
||||
#include "query/exceptions.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper_master.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper_worker.hpp"
|
||||
#include "storage/distributed/storage_gc_master.hpp"
|
||||
|
@ -5,16 +5,16 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "database/counters.hpp"
|
||||
#include "database/distributed/counters.hpp"
|
||||
#include "durability/distributed/recovery.hpp"
|
||||
#include "durability/distributed/wal.hpp"
|
||||
#include "io/network/endpoint.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper.hpp"
|
||||
#include "storage/distributed/storage.hpp"
|
||||
#include "storage/distributed/storage_gc.hpp"
|
||||
#include "storage/distributed/vertex_accessor.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
|
||||
namespace database {
|
||||
|
@ -6,20 +6,19 @@
|
||||
#include <string>
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "database/counters.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
/// Implementation for the single-node memgraph
|
||||
class SingleNodeCounters : public Counters {
|
||||
class Counters {
|
||||
public:
|
||||
int64_t Get(const std::string &name) override {
|
||||
int64_t Get(const std::string &name) {
|
||||
return counters_.access()
|
||||
.emplace(name, std::make_tuple(name), std::make_tuple(0))
|
||||
.first->second.fetch_add(1);
|
||||
}
|
||||
|
||||
void Set(const std::string &name, int64_t value) override {
|
||||
void Set(const std::string &name, int64_t value) {
|
||||
auto name_counter_pair = counters_.access().emplace(
|
||||
name, std::make_tuple(name), std::make_tuple(value));
|
||||
if (!name_counter_pair.second) name_counter_pair.first->second.store(value);
|
@ -4,220 +4,26 @@
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "database/single_node/counters.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "database/single_node/single_node_counters.hpp"
|
||||
#include "durability/paths.hpp"
|
||||
#include "durability/single_node/recovery.hpp"
|
||||
#include "durability/single_node/snapshooter.hpp"
|
||||
#include "storage/single_node/concurrent_id_mapper_single_node.hpp"
|
||||
#include "storage/single_node/storage_gc_single_node.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "storage/single_node/concurrent_id_mapper.hpp"
|
||||
#include "storage/single_node/storage_gc.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "utils/file.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
namespace {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// RecordAccessor and GraphDbAccessor implementations
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class TRecord>
|
||||
class SingleNodeRecordAccessor final {
|
||||
public:
|
||||
typename RecordAccessor<TRecord>::AddressT GlobalAddress(
|
||||
const RecordAccessor<TRecord> &record_accessor) {
|
||||
// TODO: This is still coupled to distributed storage, albeit loosely.
|
||||
int worker_id = 0;
|
||||
CHECK(record_accessor.is_local());
|
||||
return storage::Address<mvcc::VersionList<TRecord>>(record_accessor.gid(),
|
||||
worker_id);
|
||||
}
|
||||
|
||||
void SetOldNew(const RecordAccessor<TRecord> &record_accessor, TRecord **old,
|
||||
TRecord **newr) {
|
||||
auto &dba = record_accessor.db_accessor();
|
||||
const auto &address = record_accessor.address();
|
||||
CHECK(record_accessor.is_local());
|
||||
address.local()->find_set_old_new(dba.transaction(), old, newr);
|
||||
}
|
||||
|
||||
TRecord *FindNew(const RecordAccessor<TRecord> &record_accessor) {
|
||||
const auto &address = record_accessor.address();
|
||||
auto &dba = record_accessor.db_accessor();
|
||||
CHECK(address.is_local());
|
||||
return address.local()->update(dba.transaction());
|
||||
}
|
||||
|
||||
void ProcessDelta(const RecordAccessor<TRecord> &record_accessor,
|
||||
const database::StateDelta &delta) {
|
||||
CHECK(record_accessor.is_local());
|
||||
record_accessor.db_accessor().wal().Emplace(delta);
|
||||
}
|
||||
|
||||
int64_t CypherId(const RecordAccessor<TRecord> &record_accessor) {
|
||||
return record_accessor.address().local()->cypher_id();
|
||||
}
|
||||
};
|
||||
|
||||
class VertexAccessorImpl final : public ::VertexAccessor::Impl {
|
||||
SingleNodeRecordAccessor<Vertex> accessor_;
|
||||
|
||||
public:
|
||||
typename RecordAccessor<Vertex>::AddressT GlobalAddress(
|
||||
const RecordAccessor<Vertex> &ra) override {
|
||||
return accessor_.GlobalAddress(ra);
|
||||
}
|
||||
|
||||
void SetOldNew(const RecordAccessor<Vertex> &ra, Vertex **old_record,
|
||||
Vertex **new_record) override {
|
||||
return accessor_.SetOldNew(ra, old_record, new_record);
|
||||
}
|
||||
|
||||
Vertex *FindNew(const RecordAccessor<Vertex> &ra) override {
|
||||
return accessor_.FindNew(ra);
|
||||
}
|
||||
|
||||
void ProcessDelta(const RecordAccessor<Vertex> &ra,
|
||||
const database::StateDelta &delta) override {
|
||||
return accessor_.ProcessDelta(ra, delta);
|
||||
}
|
||||
|
||||
void AddLabel(const VertexAccessor &va,
|
||||
const storage::Label &label) override {
|
||||
CHECK(va.is_local());
|
||||
auto &dba = va.db_accessor();
|
||||
auto delta = StateDelta::AddLabel(dba.transaction_id(), va.gid(), label,
|
||||
dba.LabelName(label));
|
||||
Vertex &vertex = va.update();
|
||||
// not a duplicate label, add it
|
||||
if (!utils::Contains(vertex.labels_, label)) {
|
||||
vertex.labels_.emplace_back(label);
|
||||
dba.wal().Emplace(delta);
|
||||
dba.UpdateLabelIndices(label, va, &vertex);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveLabel(const VertexAccessor &va,
|
||||
const storage::Label &label) override {
|
||||
CHECK(va.is_local());
|
||||
auto &dba = va.db_accessor();
|
||||
auto delta = StateDelta::RemoveLabel(dba.transaction_id(), va.gid(), label,
|
||||
dba.LabelName(label));
|
||||
Vertex &vertex = va.update();
|
||||
if (utils::Contains(vertex.labels_, label)) {
|
||||
auto &labels = vertex.labels_;
|
||||
auto found = std::find(labels.begin(), labels.end(), delta.label);
|
||||
std::swap(*found, labels.back());
|
||||
labels.pop_back();
|
||||
dba.wal().Emplace(delta);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t CypherId(const RecordAccessor<Vertex> &ra) override {
|
||||
return accessor_.CypherId(ra);
|
||||
}
|
||||
};
|
||||
|
||||
class EdgeAccessorImpl final : public ::RecordAccessor<Edge>::Impl {
|
||||
SingleNodeRecordAccessor<Edge> accessor_;
|
||||
|
||||
public:
|
||||
typename RecordAccessor<Edge>::AddressT GlobalAddress(
|
||||
const RecordAccessor<Edge> &ra) override {
|
||||
return accessor_.GlobalAddress(ra);
|
||||
}
|
||||
|
||||
void SetOldNew(const RecordAccessor<Edge> &ra, Edge **old_record,
|
||||
Edge **new_record) override {
|
||||
return accessor_.SetOldNew(ra, old_record, new_record);
|
||||
}
|
||||
|
||||
Edge *FindNew(const RecordAccessor<Edge> &ra) override {
|
||||
return accessor_.FindNew(ra);
|
||||
}
|
||||
|
||||
void ProcessDelta(const RecordAccessor<Edge> &ra,
|
||||
const database::StateDelta &delta) override {
|
||||
return accessor_.ProcessDelta(ra, delta);
|
||||
}
|
||||
|
||||
int64_t CypherId(const RecordAccessor<Edge> &ra) override {
|
||||
return accessor_.CypherId(ra);
|
||||
}
|
||||
};
|
||||
|
||||
class SingleNodeAccessor : public GraphDbAccessor {
|
||||
// Shared implementations of record accessors.
|
||||
static VertexAccessorImpl vertex_accessor_;
|
||||
static EdgeAccessorImpl edge_accessor_;
|
||||
|
||||
public:
|
||||
explicit SingleNodeAccessor(GraphDb &db) : GraphDbAccessor(db) {}
|
||||
SingleNodeAccessor(GraphDb &db, tx::TransactionId tx_id)
|
||||
: GraphDbAccessor(db, tx_id) {}
|
||||
|
||||
::VertexAccessor::Impl *GetVertexImpl() override { return &vertex_accessor_; }
|
||||
|
||||
::RecordAccessor<Edge>::Impl *GetEdgeImpl() override {
|
||||
return &edge_accessor_;
|
||||
}
|
||||
};
|
||||
|
||||
VertexAccessorImpl SingleNodeAccessor::vertex_accessor_;
|
||||
EdgeAccessorImpl SingleNodeAccessor::edge_accessor_;
|
||||
|
||||
} // namespace
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SingleNode GraphDb implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <template <typename TId> class TMapper>
|
||||
struct TypemapPack {
|
||||
template <typename... TMapperArgs>
|
||||
explicit TypemapPack(TMapperArgs &... args)
|
||||
: label(args...), edge_type(args...), property(args...) {}
|
||||
// TODO this should also be garbage collected
|
||||
TMapper<storage::Label> label;
|
||||
TMapper<storage::EdgeType> edge_type;
|
||||
TMapper<storage::Property> property;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
class SingleNode {
|
||||
public:
|
||||
explicit SingleNode(const Config &config) : config_(config) {}
|
||||
|
||||
Config config_;
|
||||
std::unique_ptr<Storage> storage_ =
|
||||
std::make_unique<Storage>(config_.worker_id, config_.properties_on_disk);
|
||||
durability::WriteAheadLog wal_{
|
||||
config_.worker_id, config_.durability_directory,
|
||||
config_.durability_enabled, config_.synchronous_commit};
|
||||
|
||||
tx::EngineSingleNode tx_engine_{&wal_};
|
||||
std::unique_ptr<StorageGcSingleNode> storage_gc_ =
|
||||
std::make_unique<StorageGcSingleNode>(*storage_, tx_engine_,
|
||||
config_.gc_cycle_sec);
|
||||
TypemapPack<storage::SingleNodeConcurrentIdMapper> typemap_pack_{
|
||||
storage_->PropertiesOnDisk()};
|
||||
database::SingleNodeCounters counters_;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
SingleNode::SingleNode(Config config)
|
||||
: impl_(std::make_unique<impl::SingleNode>(config)) {
|
||||
GraphDb::GraphDb(Config config) : config_(config) {
|
||||
CHECK(config.worker_id == 0)
|
||||
<< "Worker ID should only be set in distributed GraphDb";
|
||||
if (impl_->config_.durability_enabled)
|
||||
utils::CheckDir(impl_->config_.durability_directory);
|
||||
if (config_.durability_enabled) utils::CheckDir(config_.durability_directory);
|
||||
|
||||
// Durability recovery.
|
||||
if (impl_->config_.db_recover_on_startup) {
|
||||
CHECK(durability::VersionConsistency(impl_->config_.durability_directory))
|
||||
if (config_.db_recover_on_startup) {
|
||||
CHECK(durability::VersionConsistency(config_.durability_directory))
|
||||
<< "Contents of durability directory are not compatible with the "
|
||||
"current version of Memgraph binary!";
|
||||
|
||||
@ -226,112 +32,108 @@ SingleNode::SingleNode(Config config)
|
||||
durability::RecoveryData recovery_data;
|
||||
|
||||
recovery_info = durability::RecoverOnlySnapshot(
|
||||
impl_->config_.durability_directory, this, &recovery_data,
|
||||
config_.durability_directory, this, &recovery_data,
|
||||
std::experimental::nullopt, 0);
|
||||
|
||||
// Post-recovery setup and checking.
|
||||
if (recovery_info) {
|
||||
recovery_data.wal_tx_to_recover = recovery_info->wal_recovered;
|
||||
SingleNodeRecoveryTransanctions recovery_transactions(this);
|
||||
durability::RecoverWal(impl_->config_.durability_directory, this,
|
||||
&recovery_data, &recovery_transactions);
|
||||
durability::RecoveryTransactions recovery_transactions(this);
|
||||
durability::RecoverWal(config_.durability_directory, this, &recovery_data,
|
||||
&recovery_transactions);
|
||||
durability::RecoverIndexes(this, recovery_data.indexes);
|
||||
}
|
||||
}
|
||||
|
||||
if (impl_->config_.durability_enabled) {
|
||||
if (config_.durability_enabled) {
|
||||
// move any existing snapshots or wal files to a deprecated folder.
|
||||
if (!impl_->config_.db_recover_on_startup &&
|
||||
durability::ContainsDurabilityFiles(
|
||||
impl_->config_.durability_directory)) {
|
||||
durability::MoveToBackup(impl_->config_.durability_directory);
|
||||
if (!config_.db_recover_on_startup &&
|
||||
durability::ContainsDurabilityFiles(config_.durability_directory)) {
|
||||
durability::MoveToBackup(config_.durability_directory);
|
||||
LOG(WARNING) << "Since Memgraph was not supposed to recover on startup "
|
||||
"and durability is enabled, your current durability "
|
||||
"files will likely be overriden. To prevent important "
|
||||
"data loss, Memgraph has stored those files into a "
|
||||
".backup directory inside durability directory";
|
||||
}
|
||||
impl_->wal_.Init();
|
||||
wal_.Init();
|
||||
snapshot_creator_ = std::make_unique<utils::Scheduler>();
|
||||
snapshot_creator_->Run(
|
||||
"Snapshot", std::chrono::seconds(impl_->config_.snapshot_cycle_sec),
|
||||
[this] {
|
||||
"Snapshot", std::chrono::seconds(config_.snapshot_cycle_sec), [this] {
|
||||
auto dba = this->Access();
|
||||
this->MakeSnapshot(*dba);
|
||||
});
|
||||
}
|
||||
|
||||
// Start transaction killer.
|
||||
if (impl_->config_.query_execution_time_sec != -1) {
|
||||
if (config_.query_execution_time_sec != -1) {
|
||||
transaction_killer_.Run(
|
||||
"TX killer",
|
||||
std::chrono::seconds(std::max(
|
||||
1, std::min(5, impl_->config_.query_execution_time_sec / 4))),
|
||||
std::chrono::seconds(
|
||||
std::max(1, std::min(5, config_.query_execution_time_sec / 4))),
|
||||
[this]() {
|
||||
impl_->tx_engine_.LocalForEachActiveTransaction(
|
||||
[this](tx::Transaction &t) {
|
||||
if (t.creation_time() +
|
||||
std::chrono::seconds(
|
||||
impl_->config_.query_execution_time_sec) <
|
||||
std::chrono::steady_clock::now()) {
|
||||
t.set_should_abort();
|
||||
};
|
||||
});
|
||||
tx_engine_.LocalForEachActiveTransaction([this](tx::Transaction &t) {
|
||||
if (t.creation_time() +
|
||||
std::chrono::seconds(config_.query_execution_time_sec) <
|
||||
std::chrono::steady_clock::now()) {
|
||||
t.set_should_abort();
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SingleNode::~SingleNode() {
|
||||
GraphDb::~GraphDb() {
|
||||
snapshot_creator_ = nullptr;
|
||||
|
||||
is_accepting_transactions_ = false;
|
||||
impl_->tx_engine_.LocalForEachActiveTransaction(
|
||||
tx_engine_.LocalForEachActiveTransaction(
|
||||
[](auto &t) { t.set_should_abort(); });
|
||||
|
||||
if (impl_->config_.snapshot_on_exit) {
|
||||
if (config_.snapshot_on_exit) {
|
||||
auto dba = this->Access();
|
||||
MakeSnapshot(*dba);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> SingleNode::Access() {
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access() {
|
||||
// NOTE: We are doing a heap allocation to allow polymorphism. If this poses
|
||||
// performance issues, we may want to have a stack allocated GraphDbAccessor
|
||||
// which is constructed with a pointer to some global implementation struct
|
||||
// which contains only pure functions (without any state).
|
||||
return std::make_unique<SingleNodeAccessor>(*this);
|
||||
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this));
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> SingleNode::Access(tx::TransactionId tx_id) {
|
||||
return std::make_unique<SingleNodeAccessor>(*this, tx_id);
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access(tx::TransactionId tx_id) {
|
||||
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this, tx_id));
|
||||
}
|
||||
|
||||
Storage &SingleNode::storage() { return *impl_->storage_; }
|
||||
Storage &GraphDb::storage() { return *storage_; }
|
||||
|
||||
durability::WriteAheadLog &SingleNode::wal() { return impl_->wal_; }
|
||||
durability::WriteAheadLog &GraphDb::wal() { return wal_; }
|
||||
|
||||
tx::Engine &SingleNode::tx_engine() { return impl_->tx_engine_; }
|
||||
tx::Engine &GraphDb::tx_engine() { return tx_engine_; }
|
||||
|
||||
storage::ConcurrentIdMapper<storage::Label> &SingleNode::label_mapper() {
|
||||
return impl_->typemap_pack_.label;
|
||||
storage::ConcurrentIdMapper<storage::Label> &GraphDb::label_mapper() {
|
||||
return label_mapper_;
|
||||
}
|
||||
|
||||
storage::ConcurrentIdMapper<storage::EdgeType> &SingleNode::edge_type_mapper() {
|
||||
return impl_->typemap_pack_.edge_type;
|
||||
storage::ConcurrentIdMapper<storage::EdgeType> &GraphDb::edge_type_mapper() {
|
||||
return edge_mapper_;
|
||||
}
|
||||
|
||||
storage::ConcurrentIdMapper<storage::Property> &SingleNode::property_mapper() {
|
||||
return impl_->typemap_pack_.property;
|
||||
storage::ConcurrentIdMapper<storage::Property> &GraphDb::property_mapper() {
|
||||
return property_mapper_;
|
||||
}
|
||||
|
||||
database::Counters &SingleNode::counters() { return impl_->counters_; }
|
||||
database::Counters &GraphDb::counters() { return counters_; }
|
||||
|
||||
void SingleNode::CollectGarbage() { impl_->storage_gc_->CollectGarbage(); }
|
||||
void GraphDb::CollectGarbage() { storage_gc_->CollectGarbage(); }
|
||||
|
||||
bool SingleNode::MakeSnapshot(GraphDbAccessor &accessor) {
|
||||
bool GraphDb::MakeSnapshot(GraphDbAccessor &accessor) {
|
||||
const bool status = durability::MakeSnapshot(
|
||||
*this, accessor, 0, fs::path(impl_->config_.durability_directory),
|
||||
impl_->config_.snapshot_max_retained);
|
||||
*this, accessor, 0, fs::path(config_.durability_directory),
|
||||
config_.snapshot_max_retained);
|
||||
if (status) {
|
||||
LOG(INFO) << "Snapshot created successfully.";
|
||||
} else {
|
||||
@ -340,48 +142,13 @@ bool SingleNode::MakeSnapshot(GraphDbAccessor &accessor) {
|
||||
return status;
|
||||
}
|
||||
|
||||
void SingleNode::ReinitializeStorage() {
|
||||
void GraphDb::ReinitializeStorage() {
|
||||
// Release gc scheduler to stop it from touching storage
|
||||
impl_->storage_gc_ = nullptr;
|
||||
impl_->storage_ = std::make_unique<Storage>(
|
||||
impl_->config_.worker_id, impl_->config_.properties_on_disk);
|
||||
impl_->storage_gc_ = std::make_unique<StorageGcSingleNode>(
|
||||
*impl_->storage_, impl_->tx_engine_, impl_->config_.gc_cycle_sec);
|
||||
}
|
||||
|
||||
SingleNodeRecoveryTransanctions::SingleNodeRecoveryTransanctions(SingleNode *db)
|
||||
: db_(db) {}
|
||||
|
||||
SingleNodeRecoveryTransanctions::~SingleNodeRecoveryTransanctions() {}
|
||||
|
||||
void SingleNodeRecoveryTransanctions::Begin(const tx::TransactionId &tx_id) {
|
||||
CHECK(accessors_.find(tx_id) == accessors_.end())
|
||||
<< "Double transaction start";
|
||||
accessors_.emplace(tx_id, db_->Access());
|
||||
}
|
||||
|
||||
GraphDbAccessor *GetAccessor(
|
||||
const std::unordered_map<tx::TransactionId,
|
||||
std::unique_ptr<GraphDbAccessor>> &accessors,
|
||||
const tx::TransactionId &tx_id) {
|
||||
auto found = accessors.find(tx_id);
|
||||
CHECK(found != accessors.end()) << "Accessor does not exist for transaction: "
|
||||
<< tx_id;
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
void SingleNodeRecoveryTransanctions::Abort(const tx::TransactionId &tx_id) {
|
||||
GetAccessor(accessors_, tx_id)->Abort();
|
||||
accessors_.erase(accessors_.find(tx_id));
|
||||
}
|
||||
|
||||
void SingleNodeRecoveryTransanctions::Commit(const tx::TransactionId &tx_id) {
|
||||
GetAccessor(accessors_, tx_id)->Commit();
|
||||
accessors_.erase(accessors_.find(tx_id));
|
||||
}
|
||||
|
||||
void SingleNodeRecoveryTransanctions::Apply(const database::StateDelta &delta) {
|
||||
delta.Apply(*GetAccessor(accessors_, delta.transaction_id));
|
||||
storage_gc_ = nullptr;
|
||||
storage_ =
|
||||
std::make_unique<Storage>(config_.worker_id, config_.properties_on_disk);
|
||||
storage_gc_ =
|
||||
std::make_unique<StorageGc>(*storage_, tx_engine_, config_.gc_cycle_sec);
|
||||
}
|
||||
|
||||
} // namespace database
|
||||
|
@ -5,15 +5,15 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "database/counters.hpp"
|
||||
#include "database/single_node/counters.hpp"
|
||||
#include "durability/single_node/recovery.hpp"
|
||||
#include "durability/single_node/wal.hpp"
|
||||
#include "io/network/endpoint.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/single_node/concurrent_id_mapper.hpp"
|
||||
#include "storage/single_node/storage.hpp"
|
||||
#include "storage/single_node/storage_gc.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
|
||||
namespace database {
|
||||
@ -73,91 +73,63 @@ class GraphDbAccessor;
|
||||
/// -> CRASH
|
||||
class GraphDb {
|
||||
public:
|
||||
GraphDb() {}
|
||||
explicit GraphDb(Config config = Config());
|
||||
~GraphDb();
|
||||
|
||||
GraphDb(const GraphDb &) = delete;
|
||||
GraphDb(GraphDb &&) = delete;
|
||||
GraphDb &operator=(const GraphDb &) = delete;
|
||||
GraphDb &operator=(GraphDb &&) = delete;
|
||||
|
||||
virtual ~GraphDb() {}
|
||||
|
||||
/// Create a new accessor by starting a new transaction.
|
||||
virtual std::unique_ptr<GraphDbAccessor> Access() = 0;
|
||||
std::unique_ptr<GraphDbAccessor> Access();
|
||||
/// Create an accessor for a running transaction.
|
||||
virtual std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId) = 0;
|
||||
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId);
|
||||
|
||||
virtual Storage &storage() = 0;
|
||||
virtual durability::WriteAheadLog &wal() = 0;
|
||||
virtual tx::Engine &tx_engine() = 0;
|
||||
virtual storage::ConcurrentIdMapper<storage::Label> &label_mapper() = 0;
|
||||
virtual storage::ConcurrentIdMapper<storage::EdgeType>
|
||||
&edge_type_mapper() = 0;
|
||||
virtual storage::ConcurrentIdMapper<storage::Property> &property_mapper() = 0;
|
||||
virtual database::Counters &counters() = 0;
|
||||
virtual void CollectGarbage() = 0;
|
||||
Storage &storage();
|
||||
durability::WriteAheadLog &wal();
|
||||
tx::Engine &tx_engine();
|
||||
storage::ConcurrentIdMapper<storage::Label> &label_mapper();
|
||||
storage::ConcurrentIdMapper<storage::EdgeType> &edge_type_mapper();
|
||||
storage::ConcurrentIdMapper<storage::Property> &property_mapper();
|
||||
database::Counters &counters();
|
||||
void CollectGarbage();
|
||||
|
||||
/// Makes a snapshot from the visibility of the given accessor
|
||||
virtual bool MakeSnapshot(GraphDbAccessor &accessor) = 0;
|
||||
bool MakeSnapshot(GraphDbAccessor &accessor);
|
||||
|
||||
/// Releases the storage object safely and creates a new object.
|
||||
/// This is needed because of recovery, otherwise we might try to recover into
|
||||
/// a storage which has already been polluted because of a failed previous
|
||||
/// recovery
|
||||
virtual void ReinitializeStorage() = 0;
|
||||
void ReinitializeStorage();
|
||||
|
||||
/// When this is false, no new transactions should be created.
|
||||
bool is_accepting_transactions() const { return is_accepting_transactions_; }
|
||||
|
||||
protected:
|
||||
std::atomic<bool> is_accepting_transactions_{true};
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
class SingleNode;
|
||||
} // namespace impl
|
||||
|
||||
class SingleNode final : public GraphDb {
|
||||
public:
|
||||
explicit SingleNode(Config config = Config());
|
||||
~SingleNode();
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> Access() override;
|
||||
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId) override;
|
||||
|
||||
Storage &storage() override;
|
||||
durability::WriteAheadLog &wal() override;
|
||||
tx::Engine &tx_engine() override;
|
||||
storage::ConcurrentIdMapper<storage::Label> &label_mapper() override;
|
||||
storage::ConcurrentIdMapper<storage::EdgeType> &edge_type_mapper() override;
|
||||
storage::ConcurrentIdMapper<storage::Property> &property_mapper() override;
|
||||
database::Counters &counters() override;
|
||||
void CollectGarbage() override;
|
||||
|
||||
bool MakeSnapshot(GraphDbAccessor &accessor) override;
|
||||
void ReinitializeStorage() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<impl::SingleNode> impl_;
|
||||
|
||||
std::unique_ptr<utils::Scheduler> snapshot_creator_;
|
||||
utils::Scheduler transaction_killer_;
|
||||
};
|
||||
|
||||
class SingleNodeRecoveryTransanctions final
|
||||
: public durability::RecoveryTransactions {
|
||||
public:
|
||||
explicit SingleNodeRecoveryTransanctions(SingleNode *db);
|
||||
~SingleNodeRecoveryTransanctions();
|
||||
Config config_;
|
||||
std::unique_ptr<Storage> storage_ =
|
||||
std::make_unique<Storage>(config_.worker_id, config_.properties_on_disk);
|
||||
durability::WriteAheadLog wal_{
|
||||
config_.worker_id, config_.durability_directory,
|
||||
config_.durability_enabled, config_.synchronous_commit};
|
||||
|
||||
void Begin(const tx::TransactionId &tx_id) override;
|
||||
void Abort(const tx::TransactionId &tx_id) override;
|
||||
void Commit(const tx::TransactionId &tx_id) override;
|
||||
void Apply(const database::StateDelta &delta) override;
|
||||
|
||||
private:
|
||||
SingleNode *db_;
|
||||
std::unordered_map<tx::TransactionId, std::unique_ptr<GraphDbAccessor>>
|
||||
accessors_;
|
||||
tx::Engine tx_engine_{&wal_};
|
||||
std::unique_ptr<StorageGc> storage_gc_ =
|
||||
std::make_unique<StorageGc>(*storage_, tx_engine_, config_.gc_cycle_sec);
|
||||
storage::ConcurrentIdMapper<storage::Label> label_mapper_{
|
||||
storage_->PropertiesOnDisk()};
|
||||
storage::ConcurrentIdMapper<storage::EdgeType> edge_mapper_{
|
||||
storage_->PropertiesOnDisk()};
|
||||
storage::ConcurrentIdMapper<storage::Property> property_mapper_{
|
||||
storage_->PropertiesOnDisk()};
|
||||
database::Counters counters_;
|
||||
};
|
||||
|
||||
} // namespace database
|
||||
|
@ -45,6 +45,7 @@ class GraphDbAccessor {
|
||||
// the code.
|
||||
friend class ::RecordAccessor<Vertex>;
|
||||
friend class ::VertexAccessor;
|
||||
friend class GraphDb;
|
||||
|
||||
protected:
|
||||
// Construction should only be done through GraphDb::Access function and
|
||||
@ -56,16 +57,13 @@ class GraphDbAccessor {
|
||||
GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id);
|
||||
|
||||
public:
|
||||
virtual ~GraphDbAccessor();
|
||||
~GraphDbAccessor();
|
||||
|
||||
GraphDbAccessor(const GraphDbAccessor &other) = delete;
|
||||
GraphDbAccessor(GraphDbAccessor &&other) = delete;
|
||||
GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete;
|
||||
GraphDbAccessor &operator=(GraphDbAccessor &&other) = delete;
|
||||
|
||||
virtual ::VertexAccessor::Impl *GetVertexImpl() = 0;
|
||||
virtual ::RecordAccessor<Edge>::Impl *GetEdgeImpl() = 0;
|
||||
|
||||
/**
|
||||
* Creates a new Vertex and returns an accessor to it. If the ID is
|
||||
* provided, the created Vertex will have that local ID, and the ID counter
|
||||
@ -101,8 +99,7 @@ class GraphDbAccessor {
|
||||
* before deletion.
|
||||
* @return If or not the vertex was deleted.
|
||||
*/
|
||||
virtual bool RemoveVertex(VertexAccessor &vertex_accessor,
|
||||
bool check_empty = true);
|
||||
bool RemoveVertex(VertexAccessor &vertex_accessor, bool check_empty = true);
|
||||
|
||||
/**
|
||||
* Removes the vertex of the given accessor along with all it's outgoing
|
||||
@ -340,8 +337,8 @@ class GraphDbAccessor {
|
||||
* @param remove_in_edge If the edge should be removed from the its
|
||||
* destination side.
|
||||
*/
|
||||
virtual void RemoveEdge(EdgeAccessor &edge, bool remove_out_edge = true,
|
||||
bool remove_in_edge = true);
|
||||
void RemoveEdge(EdgeAccessor &edge, bool remove_out_edge = true,
|
||||
bool remove_in_edge = true);
|
||||
|
||||
/**
|
||||
* Obtains the edge for the given ID. If there is no edge for the given
|
||||
@ -444,7 +441,7 @@ class GraphDbAccessor {
|
||||
* @param label - label to build for
|
||||
* @param property - property to build for
|
||||
*/
|
||||
virtual void BuildIndex(storage::Label label, storage::Property property);
|
||||
void BuildIndex(storage::Label label, storage::Property property);
|
||||
|
||||
/// Populates index with vertices containing the key
|
||||
void PopulateIndex(const LabelPropertyIndex::Key &key);
|
||||
@ -574,7 +571,7 @@ class GraphDbAccessor {
|
||||
tx::TransactionId transaction_id() const;
|
||||
|
||||
/** Advances transaction's command id by 1. */
|
||||
virtual void AdvanceCommand();
|
||||
void AdvanceCommand();
|
||||
|
||||
/** Commit transaction. */
|
||||
void Commit();
|
||||
@ -621,10 +618,10 @@ class GraphDbAccessor {
|
||||
|
||||
protected:
|
||||
/** Called in `BuildIndex` after creating an index, but before populating. */
|
||||
virtual void PostCreateIndex(const LabelPropertyIndex::Key &key) {}
|
||||
void PostCreateIndex(const LabelPropertyIndex::Key &key) {}
|
||||
|
||||
/** Populates the index from a *new* transaction after creating the index. */
|
||||
virtual void PopulateIndexFromBuildIndex(const LabelPropertyIndex::Key &key) {
|
||||
void PopulateIndexFromBuildIndex(const LabelPropertyIndex::Key &key) {
|
||||
PopulateIndex(key);
|
||||
}
|
||||
|
||||
@ -632,7 +629,7 @@ class GraphDbAccessor {
|
||||
* Insert a new edge to `from` vertex and return the address.
|
||||
* Called from `InsertEdge` as the first step in edge insertion.
|
||||
* */
|
||||
virtual storage::EdgeAddress InsertEdgeOnFrom(
|
||||
storage::EdgeAddress InsertEdgeOnFrom(
|
||||
VertexAccessor *from, VertexAccessor *to,
|
||||
const storage::EdgeType &edge_type,
|
||||
const std::experimental::optional<gid::Gid> &requested_gid,
|
||||
@ -643,9 +640,9 @@ class GraphDbAccessor {
|
||||
* Called after `InsertEdgeOnFrom` in `InsertEdge`. The given `edge_address`
|
||||
* is from the created edge, returned by `InsertEdgeOnFrom`.
|
||||
*/
|
||||
virtual void InsertEdgeOnTo(VertexAccessor *from, VertexAccessor *to,
|
||||
const storage::EdgeType &edge_type,
|
||||
const storage::EdgeAddress &edge_address);
|
||||
void InsertEdgeOnTo(VertexAccessor *from, VertexAccessor *to,
|
||||
const storage::EdgeType &edge_type,
|
||||
const storage::EdgeAddress &edge_address);
|
||||
|
||||
private:
|
||||
GraphDb &db_;
|
||||
|
@ -419,6 +419,36 @@ RecoveryInfo RecoverOnlySnapshot(
|
||||
*recovery_data)};
|
||||
}
|
||||
|
||||
RecoveryTransactions::RecoveryTransactions(database::GraphDb *db) : db_(db) {}
|
||||
|
||||
void RecoveryTransactions::Begin(const tx::TransactionId &tx_id) {
|
||||
CHECK(accessors_.find(tx_id) == accessors_.end())
|
||||
<< "Double transaction start";
|
||||
accessors_.emplace(tx_id, db_->Access());
|
||||
}
|
||||
|
||||
void RecoveryTransactions::Abort(const tx::TransactionId &tx_id) {
|
||||
GetAccessor(tx_id)->Abort();
|
||||
accessors_.erase(accessors_.find(tx_id));
|
||||
}
|
||||
|
||||
void RecoveryTransactions::Commit(const tx::TransactionId &tx_id) {
|
||||
GetAccessor(tx_id)->Commit();
|
||||
accessors_.erase(accessors_.find(tx_id));
|
||||
}
|
||||
|
||||
void RecoveryTransactions::Apply(const database::StateDelta &delta) {
|
||||
delta.Apply(*GetAccessor(delta.transaction_id));
|
||||
}
|
||||
|
||||
database::GraphDbAccessor *RecoveryTransactions::GetAccessor(
|
||||
const tx::TransactionId &tx_id) {
|
||||
auto found = accessors_.find(tx_id);
|
||||
CHECK(found != accessors_.end())
|
||||
<< "Accessor does not exist for transaction: " << tx_id;
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
// TODO - finer-grained recovery feedback could be useful here.
|
||||
void RecoverWal(const fs::path &durability_dir, database::GraphDb *db,
|
||||
RecoveryData *recovery_data,
|
||||
|
@ -116,12 +116,23 @@ RecoveryInfo RecoverOnlySnapshot(
|
||||
/** Interface for accessing transactions during WAL recovery. */
|
||||
class RecoveryTransactions {
|
||||
public:
|
||||
virtual ~RecoveryTransactions() {}
|
||||
RecoveryTransactions(database::GraphDb *db);
|
||||
|
||||
virtual void Begin(const tx::TransactionId &) = 0;
|
||||
virtual void Abort(const tx::TransactionId &) = 0;
|
||||
virtual void Commit(const tx::TransactionId &) = 0;
|
||||
virtual void Apply(const database::StateDelta &) = 0;
|
||||
void Begin(const tx::TransactionId &tx_id);
|
||||
|
||||
void Abort(const tx::TransactionId &tx_id);
|
||||
|
||||
void Commit(const tx::TransactionId &tx_id);
|
||||
|
||||
void Apply(const database::StateDelta &delta);
|
||||
|
||||
private:
|
||||
database::GraphDbAccessor *GetAccessor(const tx::TransactionId &tx_id);
|
||||
|
||||
database::GraphDb *db_;
|
||||
std::unordered_map<tx::TransactionId,
|
||||
std::unique_ptr<database::GraphDbAccessor>>
|
||||
accessors_;
|
||||
};
|
||||
|
||||
void RecoverWal(const std::experimental::filesystem::path &durability_dir,
|
||||
|
@ -44,7 +44,7 @@ using communication::ServerContext;
|
||||
|
||||
void SingleNodeMain() {
|
||||
google::SetUsageMessage("Memgraph single-node database server");
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
query::Interpreter interpreter;
|
||||
SessionData session_data{&db, &interpreter};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
|
||||
#include "mvcc/common/version.hpp"
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
|
||||
#include "mvcc/common/version.hpp"
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
|
||||
namespace storage {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "communication/rpc/client_pool.hpp"
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "io/network/endpoint.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/distributed/concurrent_id_mapper.hpp"
|
||||
|
||||
namespace storage {
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "data_structures/concurrent/skiplist.hpp"
|
||||
#include "mvcc/distributed/version_list.hpp"
|
||||
#include "storage/distributed/deferred_deleter.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
|
||||
/**
|
||||
* @brief - Garbage collects deleted records.
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "storage/distributed/gid.hpp"
|
||||
#include "storage/distributed/storage.hpp"
|
||||
#include "storage/distributed/vertex.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/timer.hpp"
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "storage/common/concurrent_id_mapper.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
|
||||
@ -11,16 +10,16 @@ namespace storage {
|
||||
|
||||
/** SingleNode implementation of ConcurrentIdMapper. */
|
||||
template <typename TId>
|
||||
class SingleNodeConcurrentIdMapper : public ConcurrentIdMapper<TId> {
|
||||
class ConcurrentIdMapper {
|
||||
using StorageT = typename TId::IdT;
|
||||
|
||||
public:
|
||||
SingleNodeConcurrentIdMapper() = default;
|
||||
explicit SingleNodeConcurrentIdMapper(
|
||||
ConcurrentIdMapper() = default;
|
||||
explicit ConcurrentIdMapper(
|
||||
const std::vector<std::string> &properties_on_disk)
|
||||
: properties_on_disk_(properties_on_disk) {}
|
||||
|
||||
TId value_to_id(const std::string &value) override {
|
||||
TId value_to_id(const std::string &value) {
|
||||
auto value_to_id_acc = value_to_id_.access();
|
||||
auto found = value_to_id_acc.find(value);
|
||||
TId inserted_id(0);
|
||||
@ -46,7 +45,7 @@ class SingleNodeConcurrentIdMapper : public ConcurrentIdMapper<TId> {
|
||||
return inserted_id;
|
||||
}
|
||||
|
||||
const std::string &id_to_value(const TId &id) override {
|
||||
const std::string &id_to_value(const TId &id) {
|
||||
auto id_to_value_acc = id_to_value_.access();
|
||||
auto result = id_to_value_acc.find(id);
|
||||
DCHECK(result != id_to_value_acc.end());
|
@ -6,7 +6,7 @@
|
||||
|
||||
EdgeAccessor::EdgeAccessor(EdgeAddress address,
|
||||
database::GraphDbAccessor &db_accessor)
|
||||
: RecordAccessor(address, db_accessor, db_accessor.GetEdgeImpl()),
|
||||
: RecordAccessor(address, db_accessor),
|
||||
from_(nullptr),
|
||||
to_(nullptr),
|
||||
edge_type_() {
|
||||
@ -22,7 +22,7 @@ EdgeAccessor::EdgeAccessor(EdgeAddress address,
|
||||
database::GraphDbAccessor &db_accessor,
|
||||
VertexAddress from, VertexAddress to,
|
||||
storage::EdgeType edge_type)
|
||||
: RecordAccessor(address, db_accessor, db_accessor.GetEdgeImpl()),
|
||||
: RecordAccessor(address, db_accessor),
|
||||
from_(from),
|
||||
to_(to),
|
||||
edge_type_(edge_type) {}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "data_structures/concurrent/skiplist.hpp"
|
||||
#include "mvcc/single_node/version_list.hpp"
|
||||
#include "storage/single_node/deferred_deleter.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
/**
|
||||
* @brief - Garbage collects deleted records.
|
||||
|
@ -11,10 +11,8 @@ using database::StateDelta;
|
||||
|
||||
template <typename TRecord>
|
||||
RecordAccessor<TRecord>::RecordAccessor(AddressT address,
|
||||
database::GraphDbAccessor &db_accessor,
|
||||
Impl *impl)
|
||||
: impl_(impl),
|
||||
db_accessor_(&db_accessor),
|
||||
database::GraphDbAccessor &db_accessor)
|
||||
: db_accessor_(&db_accessor),
|
||||
address_(db_accessor.db().storage().LocalizedAddressIfPossible(address)) {
|
||||
}
|
||||
|
||||
@ -107,7 +105,10 @@ typename RecordAccessor<TRecord>::AddressT RecordAccessor<TRecord>::address()
|
||||
template <typename TRecord>
|
||||
typename RecordAccessor<TRecord>::AddressT
|
||||
RecordAccessor<TRecord>::GlobalAddress() const {
|
||||
return impl_->GlobalAddress(*this);
|
||||
// TODO: This is still coupled to distributed storage, albeit loosely.
|
||||
int worker_id = 0;
|
||||
CHECK(is_local());
|
||||
return storage::Address<mvcc::VersionList<TRecord>>(gid(), worker_id);
|
||||
}
|
||||
|
||||
template <typename TRecord>
|
||||
@ -138,7 +139,10 @@ RecordAccessor<TRecord> &RecordAccessor<TRecord>::SwitchOld() {
|
||||
|
||||
template <typename TRecord>
|
||||
bool RecordAccessor<TRecord>::Reconstruct() const {
|
||||
impl_->SetOldNew(*this, &old_, &new_);
|
||||
auto &dba = db_accessor();
|
||||
const auto &addr = address();
|
||||
CHECK(is_local());
|
||||
addr.local()->find_set_old_new(dba.transaction(), &old_, &new_);
|
||||
current_ = old_ ? old_ : new_;
|
||||
return old_ != nullptr || new_ != nullptr;
|
||||
}
|
||||
@ -160,14 +164,17 @@ TRecord &RecordAccessor<TRecord>::update() const {
|
||||
|
||||
if (new_) return *new_;
|
||||
|
||||
new_ = impl_->FindNew(*this);
|
||||
const auto &addr = address();
|
||||
CHECK(addr.is_local());
|
||||
new_ = addr.local()->update(dba.transaction());
|
||||
|
||||
DCHECK(new_ != nullptr) << "RecordAccessor.new_ is null after update";
|
||||
return *new_;
|
||||
}
|
||||
|
||||
template <typename TRecord>
|
||||
int64_t RecordAccessor<TRecord>::CypherId() const {
|
||||
return impl_->CypherId(*this);
|
||||
return address().local()->cypher_id();
|
||||
}
|
||||
|
||||
template <typename TRecord>
|
||||
@ -184,7 +191,8 @@ const TRecord &RecordAccessor<TRecord>::current() const {
|
||||
template <typename TRecord>
|
||||
void RecordAccessor<TRecord>::ProcessDelta(
|
||||
const database::StateDelta &delta) const {
|
||||
impl_->ProcessDelta(*this, delta);
|
||||
CHECK(is_local());
|
||||
db_accessor().wal().Emplace(delta);
|
||||
}
|
||||
|
||||
template class RecordAccessor<Vertex>;
|
||||
|
@ -27,34 +27,27 @@ struct StateDelta;
|
||||
*/
|
||||
template <typename TRecord>
|
||||
class RecordAccessor : public utils::TotalOrdering<RecordAccessor<TRecord>> {
|
||||
public:
|
||||
protected:
|
||||
using AddressT = storage::Address<mvcc::VersionList<TRecord>>;
|
||||
|
||||
/**
|
||||
* Interface for the underlying implementation of the record accessor.
|
||||
* The RecordAccessor only borrows the pointer to the implementation, it does
|
||||
* *not* own it. When a RecordAccessor is copied, so is the pointer but *not*
|
||||
* the implementation itself. This means that concrete Impl types need to be
|
||||
* shareable among different accessors. To achieve that, it's best for derived
|
||||
* Impl types to contain *no state*. The reason we are using this approach is
|
||||
* to prevent large amounts of allocations, because RecordAccessor are often
|
||||
* created and copied.
|
||||
* The database::GraphDbAccessor is friend to this accessor so it can
|
||||
* operate on it's data (mvcc version-list and the record itself).
|
||||
* This is legitimate because database::GraphDbAccessor creates
|
||||
* RecordAccessors
|
||||
* and is semantically their parent/owner. It is necessary because
|
||||
* the database::GraphDbAccessor handles insertions and deletions, and these
|
||||
* operations modify data intensively.
|
||||
*/
|
||||
class Impl {
|
||||
public:
|
||||
virtual ~Impl() {}
|
||||
friend database::GraphDbAccessor;
|
||||
|
||||
virtual AddressT GlobalAddress(const RecordAccessor<TRecord> &ra) = 0;
|
||||
/** Set the pointers for old and new records during `Reconstruct`. */
|
||||
virtual void SetOldNew(const RecordAccessor<TRecord> &ra,
|
||||
TRecord **old_record, TRecord **new_record) = 0;
|
||||
/** Find the pointer to the new, updated record. */
|
||||
virtual TRecord *FindNew(const RecordAccessor<TRecord> &ra) = 0;
|
||||
/** Process a change delta, e.g. by writing WAL. */
|
||||
virtual void ProcessDelta(const RecordAccessor<TRecord> &ra,
|
||||
const database::StateDelta &delta) = 0;
|
||||
virtual int64_t CypherId(const RecordAccessor<TRecord> &ra) = 0;
|
||||
};
|
||||
public:
|
||||
/**
|
||||
* @param address Address (local or global) of the Vertex/Edge of this
|
||||
* accessor.
|
||||
* @param db_accessor The DB accessor that "owns" this record accessor.
|
||||
*/
|
||||
RecordAccessor(AddressT address, database::GraphDbAccessor &db_accessor);
|
||||
|
||||
// this class is default copyable, movable and assignable
|
||||
RecordAccessor(const RecordAccessor &other) = default;
|
||||
@ -62,25 +55,6 @@ class RecordAccessor : public utils::TotalOrdering<RecordAccessor<TRecord>> {
|
||||
RecordAccessor &operator=(const RecordAccessor &other) = default;
|
||||
RecordAccessor &operator=(RecordAccessor &&other) = default;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Protected destructor because we allow inheritance, but nobody should own a
|
||||
* pointer to plain RecordAccessor.
|
||||
*/
|
||||
~RecordAccessor() = default;
|
||||
|
||||
/**
|
||||
* Only derived types may allow construction.
|
||||
*
|
||||
* @param address Address (local or global) of the Vertex/Edge of this
|
||||
* accessor.
|
||||
* @param db_accessor The DB accessor that "owns" this record accessor.
|
||||
* @param impl Borrowed pointer to the underlying implementation.
|
||||
*/
|
||||
RecordAccessor(AddressT address, database::GraphDbAccessor &db_accessor,
|
||||
Impl *impl);
|
||||
|
||||
public:
|
||||
/** Gets the property for the given key. */
|
||||
PropertyValue PropsAt(storage::Property key) const;
|
||||
|
||||
@ -183,17 +157,6 @@ class RecordAccessor : public utils::TotalOrdering<RecordAccessor<TRecord>> {
|
||||
int64_t CypherId() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The database::GraphDbAccessor is friend to this accessor so it can
|
||||
* operate on it's data (mvcc version-list and the record itself).
|
||||
* This is legitimate because database::GraphDbAccessor creates
|
||||
* RecordAccessors
|
||||
* and is semantically their parent/owner. It is necessary because
|
||||
* the database::GraphDbAccessor handles insertions and deletions, and these
|
||||
* operations modify data intensively.
|
||||
*/
|
||||
friend database::GraphDbAccessor;
|
||||
|
||||
/** Process a change delta, e.g. by writing WAL. */
|
||||
void ProcessDelta(const database::StateDelta &delta) const;
|
||||
|
||||
@ -212,7 +175,6 @@ class RecordAccessor : public utils::TotalOrdering<RecordAccessor<TRecord>> {
|
||||
const TRecord ¤t() const;
|
||||
|
||||
private:
|
||||
Impl *impl_;
|
||||
// The database accessor for which this record accessor is created
|
||||
// Provides means of getting to the transaction and database functions.
|
||||
// Immutable, set in the constructor and never changed.
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "storage/single_node/gid.hpp"
|
||||
#include "storage/single_node/storage.hpp"
|
||||
#include "storage/single_node/vertex.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/timer.hpp"
|
||||
@ -59,7 +59,10 @@ class StorageGc {
|
||||
});
|
||||
}
|
||||
|
||||
virtual ~StorageGc() {
|
||||
~StorageGc() {
|
||||
// We have to stop the scheduler before destroying this class.
|
||||
scheduler_.Stop();
|
||||
|
||||
edges_.record_deleter_.FreeExpiredObjects(tx::Transaction::MaxId());
|
||||
vertices_.record_deleter_.FreeExpiredObjects(tx::Transaction::MaxId());
|
||||
edges_.version_list_deleter_.FreeExpiredObjects(tx::Transaction::MaxId());
|
||||
@ -72,7 +75,10 @@ class StorageGc {
|
||||
StorageGc &operator=(const StorageGc &) = delete;
|
||||
StorageGc &operator=(StorageGc &&) = delete;
|
||||
|
||||
virtual void CollectCommitLogGarbage(tx::TransactionId oldest_active) = 0;
|
||||
void CollectCommitLogGarbage(tx::TransactionId oldest_active) {
|
||||
auto safe_to_delete = GetClogSafeTransaction(oldest_active);
|
||||
if (safe_to_delete) tx_engine_.GarbageCollectCommitLog(*safe_to_delete);
|
||||
}
|
||||
|
||||
void CollectGarbage() {
|
||||
// main garbage collection logic
|
||||
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/single_node/storage_gc.hpp"
|
||||
|
||||
namespace database {
|
||||
class StorageGcSingleNode : public StorageGc {
|
||||
public:
|
||||
using StorageGc::StorageGc;
|
||||
|
||||
~StorageGcSingleNode() {
|
||||
// We have to stop scheduler before destroying this class because otherwise
|
||||
// a task might try to utilize methods in this class which might cause pure
|
||||
// virtual method called since they are not implemented for the base class.
|
||||
scheduler_.Stop();
|
||||
}
|
||||
|
||||
void CollectCommitLogGarbage(tx::TransactionId oldest_active) final {
|
||||
auto safe_to_delete = GetClogSafeTransaction(oldest_active);
|
||||
if (safe_to_delete) tx_engine_.GarbageCollectCommitLog(*safe_to_delete);
|
||||
}
|
||||
};
|
||||
} // namespace database
|
@ -8,8 +8,7 @@
|
||||
|
||||
VertexAccessor::VertexAccessor(VertexAddress address,
|
||||
database::GraphDbAccessor &db_accessor)
|
||||
: RecordAccessor(address, db_accessor, db_accessor.GetVertexImpl()),
|
||||
impl_(db_accessor.GetVertexImpl()) {
|
||||
: RecordAccessor(address, db_accessor) {
|
||||
Reconstruct();
|
||||
}
|
||||
|
||||
@ -18,11 +17,32 @@ size_t VertexAccessor::out_degree() const { return current().out_.size(); }
|
||||
size_t VertexAccessor::in_degree() const { return current().in_.size(); }
|
||||
|
||||
void VertexAccessor::add_label(storage::Label label) {
|
||||
return impl_->AddLabel(*this, label);
|
||||
CHECK(is_local());
|
||||
auto &dba = db_accessor();
|
||||
auto delta = database::StateDelta::AddLabel(dba.transaction_id(), gid(),
|
||||
label, dba.LabelName(label));
|
||||
Vertex &vertex = update();
|
||||
// not a duplicate label, add it
|
||||
if (!utils::Contains(vertex.labels_, label)) {
|
||||
vertex.labels_.emplace_back(label);
|
||||
dba.wal().Emplace(delta);
|
||||
dba.UpdateLabelIndices(label, *this, &vertex);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexAccessor::remove_label(storage::Label label) {
|
||||
return impl_->RemoveLabel(*this, label);
|
||||
CHECK(is_local());
|
||||
auto &dba = db_accessor();
|
||||
auto delta = database::StateDelta::RemoveLabel(dba.transaction_id(), gid(),
|
||||
label, dba.LabelName(label));
|
||||
Vertex &vertex = update();
|
||||
if (utils::Contains(vertex.labels_, label)) {
|
||||
auto &labels = vertex.labels_;
|
||||
auto found = std::find(labels.begin(), labels.end(), delta.label);
|
||||
std::swap(*found, labels.back());
|
||||
labels.pop_back();
|
||||
dba.wal().Emplace(delta);
|
||||
}
|
||||
}
|
||||
|
||||
bool VertexAccessor::has_label(storage::Label label) const {
|
||||
|
@ -49,15 +49,6 @@ class VertexAccessor final : public RecordAccessor<Vertex> {
|
||||
}
|
||||
|
||||
public:
|
||||
/** Like RecordAccessor::Impl with addition of Vertex specific methods. */
|
||||
class Impl : public RecordAccessor<Vertex>::Impl {
|
||||
public:
|
||||
virtual void AddLabel(const VertexAccessor &va,
|
||||
const storage::Label &label) = 0;
|
||||
virtual void RemoveLabel(const VertexAccessor &va,
|
||||
const storage::Label &label) = 0;
|
||||
};
|
||||
|
||||
VertexAccessor(VertexAddress address, database::GraphDbAccessor &db_accessor);
|
||||
|
||||
/** Returns the number of outgoing edges. */
|
||||
@ -153,9 +144,6 @@ class VertexAccessor final : public RecordAccessor<Vertex> {
|
||||
* this operation should always be accompanied by the removal of the edge from
|
||||
* the outgoing edges on the other side and edge deletion. */
|
||||
void RemoveInEdge(storage::EdgeAddress edge);
|
||||
|
||||
private:
|
||||
Impl *impl_{nullptr};
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &, const VertexAccessor &);
|
||||
|
111
src/transactions/distributed/engine.hpp
Normal file
111
src/transactions/distributed/engine.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
/// @file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/snapshot.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "transactions/type.hpp"
|
||||
|
||||
namespace tx {
|
||||
/// Database transaction engine. Used for managing transactions and the related
|
||||
/// information such as transaction snapshots and the transaction state info.
|
||||
///
|
||||
/// This is an abstract base class for implementing a transactional engine.
|
||||
///
|
||||
/// Methods in this class are often prefixed with "Global" or "Local", depending
|
||||
/// on the guarantees that they need to satisfy. These guarantee requirements
|
||||
/// are determined by the users of a particular method.
|
||||
class Engine {
|
||||
public:
|
||||
virtual ~Engine() = default;
|
||||
|
||||
/// Begins a transaction and returns a pointer to it's object.
|
||||
virtual Transaction *Begin() = 0;
|
||||
|
||||
/// Advances the command on the transaction with the given id.
|
||||
virtual CommandId Advance(TransactionId id) = 0;
|
||||
|
||||
/// Updates the command on the workers to the master's value.
|
||||
virtual CommandId UpdateCommand(TransactionId id) = 0;
|
||||
|
||||
/// Comits the given transaction. Deletes the transaction object, it's not
|
||||
/// valid after this function executes.
|
||||
virtual void Commit(const Transaction &t) = 0;
|
||||
|
||||
/// Aborts the given transaction. Deletes the transaction object, it's not
|
||||
/// valid after this function executes.
|
||||
virtual void Abort(const Transaction &t) = 0;
|
||||
|
||||
/// Returns the commit log Info about the given transaction.
|
||||
virtual CommitLog::Info Info(TransactionId tx) const = 0;
|
||||
|
||||
/// Returns the snapshot relevant to garbage collection of database records.
|
||||
///
|
||||
/// If there are no active transactions that means a snapshot containing only
|
||||
/// the next transaction ID. If there are active transactions, that means the
|
||||
/// oldest active transaction's snapshot, with that transaction's ID appened
|
||||
/// as last.
|
||||
///
|
||||
/// The idea is that data records can only be deleted if they were expired
|
||||
/// (and that was committed) by a transaction older than the older currently
|
||||
/// active. We need the full snapshot to prevent overlaps (see general GC
|
||||
/// documentation).
|
||||
///
|
||||
/// The returned snapshot must be for the globally oldest active transaction.
|
||||
/// If we only looked at locally known transactions, it would be possible to
|
||||
/// delete something that and older active transaction can still see.
|
||||
virtual Snapshot GlobalGcSnapshot() = 0;
|
||||
|
||||
/// Returns active transactions.
|
||||
virtual Snapshot GlobalActiveTransactions() = 0;
|
||||
|
||||
/// Returns the ID the last globally known transaction.
|
||||
virtual tx::TransactionId GlobalLast() const = 0;
|
||||
|
||||
/// Returns the ID of last locally known transaction.
|
||||
virtual tx::TransactionId LocalLast() const = 0;
|
||||
|
||||
/// Returns the ID of the oldest transaction locally known to be active. It is
|
||||
/// guaranteed that all the transactions older than the returned are globally
|
||||
/// not active.
|
||||
virtual TransactionId LocalOldestActive() const = 0;
|
||||
|
||||
/// Calls function f on each locally active transaction.
|
||||
virtual void LocalForEachActiveTransaction(
|
||||
std::function<void(Transaction &)> f) = 0;
|
||||
|
||||
/// Gets a transaction object for a running transaction.
|
||||
virtual tx::Transaction *RunningTransaction(TransactionId tx_id) = 0;
|
||||
|
||||
/// Ensures the next transaction that starts will have the ID greater than
|
||||
/// the given id.
|
||||
virtual void EnsureNextIdGreater(TransactionId tx_id) = 0;
|
||||
|
||||
/// Garbage collects transactions older than tx_id from commit log.
|
||||
virtual void GarbageCollectCommitLog(TransactionId tx_id) = 0;
|
||||
|
||||
auto &local_lock_graph() { return local_lock_graph_; }
|
||||
const auto &local_lock_graph() const { return local_lock_graph_; }
|
||||
|
||||
protected:
|
||||
Transaction *CreateTransaction(TransactionId id, const Snapshot &snapshot) {
|
||||
return new Transaction(id, snapshot, *this);
|
||||
}
|
||||
|
||||
CommandId AdvanceCommand(Transaction *t) { return t->AdvanceCommand(); }
|
||||
|
||||
void SetCommand(Transaction *t, CommandId cid) { t->SetCommand(cid); }
|
||||
|
||||
private:
|
||||
// Map lock dependencies. Each entry maps (tx_that_wants_lock,
|
||||
// tx_that_holds_lock). Used for local deadlock resolution.
|
||||
// TODO consider global deadlock resolution.
|
||||
ConcurrentMap<TransactionId, TransactionId> local_lock_graph_;
|
||||
};
|
||||
} // namespace tx
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "communication/rpc/server.hpp"
|
||||
#include "distributed/coordination.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace tx {
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "durability/distributed/wal.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "utils/thread/sync.hpp"
|
||||
|
||||
|
@ -1,111 +1,9 @@
|
||||
/// @file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#ifdef MG_SINGLE_NODE
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#endif
|
||||
|
||||
#include "data_structures/concurrent/concurrent_map.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/snapshot.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "transactions/type.hpp"
|
||||
|
||||
namespace tx {
|
||||
/// Database transaction engine. Used for managing transactions and the related
|
||||
/// information such as transaction snapshots and the transaction state info.
|
||||
///
|
||||
/// This is an abstract base class for implementing a transactional engine.
|
||||
///
|
||||
/// Methods in this class are often prefixed with "Global" or "Local", depending
|
||||
/// on the guarantees that they need to satisfy. These guarantee requirements
|
||||
/// are determined by the users of a particular method.
|
||||
class Engine {
|
||||
public:
|
||||
virtual ~Engine() = default;
|
||||
|
||||
/// Begins a transaction and returns a pointer to it's object.
|
||||
virtual Transaction *Begin() = 0;
|
||||
|
||||
/// Advances the command on the transaction with the given id.
|
||||
virtual CommandId Advance(TransactionId id) = 0;
|
||||
|
||||
/// Updates the command on the workers to the master's value.
|
||||
virtual CommandId UpdateCommand(TransactionId id) = 0;
|
||||
|
||||
/// Comits the given transaction. Deletes the transaction object, it's not
|
||||
/// valid after this function executes.
|
||||
virtual void Commit(const Transaction &t) = 0;
|
||||
|
||||
/// Aborts the given transaction. Deletes the transaction object, it's not
|
||||
/// valid after this function executes.
|
||||
virtual void Abort(const Transaction &t) = 0;
|
||||
|
||||
/// Returns the commit log Info about the given transaction.
|
||||
virtual CommitLog::Info Info(TransactionId tx) const = 0;
|
||||
|
||||
/// Returns the snapshot relevant to garbage collection of database records.
|
||||
///
|
||||
/// If there are no active transactions that means a snapshot containing only
|
||||
/// the next transaction ID. If there are active transactions, that means the
|
||||
/// oldest active transaction's snapshot, with that transaction's ID appened
|
||||
/// as last.
|
||||
///
|
||||
/// The idea is that data records can only be deleted if they were expired
|
||||
/// (and that was committed) by a transaction older than the older currently
|
||||
/// active. We need the full snapshot to prevent overlaps (see general GC
|
||||
/// documentation).
|
||||
///
|
||||
/// The returned snapshot must be for the globally oldest active transaction.
|
||||
/// If we only looked at locally known transactions, it would be possible to
|
||||
/// delete something that and older active transaction can still see.
|
||||
virtual Snapshot GlobalGcSnapshot() = 0;
|
||||
|
||||
/// Returns active transactions.
|
||||
virtual Snapshot GlobalActiveTransactions() = 0;
|
||||
|
||||
/// Returns the ID the last globally known transaction.
|
||||
virtual tx::TransactionId GlobalLast() const = 0;
|
||||
|
||||
/// Returns the ID of last locally known transaction.
|
||||
virtual tx::TransactionId LocalLast() const = 0;
|
||||
|
||||
/// Returns the ID of the oldest transaction locally known to be active. It is
|
||||
/// guaranteed that all the transactions older than the returned are globally
|
||||
/// not active.
|
||||
virtual TransactionId LocalOldestActive() const = 0;
|
||||
|
||||
/// Calls function f on each locally active transaction.
|
||||
virtual void LocalForEachActiveTransaction(
|
||||
std::function<void(Transaction &)> f) = 0;
|
||||
|
||||
/// Gets a transaction object for a running transaction.
|
||||
virtual tx::Transaction *RunningTransaction(TransactionId tx_id) = 0;
|
||||
|
||||
/// Ensures the next transaction that starts will have the ID greater than
|
||||
/// the given id.
|
||||
virtual void EnsureNextIdGreater(TransactionId tx_id) = 0;
|
||||
|
||||
/// Garbage collects transactions older than tx_id from commit log.
|
||||
virtual void GarbageCollectCommitLog(TransactionId tx_id) = 0;
|
||||
|
||||
auto &local_lock_graph() { return local_lock_graph_; }
|
||||
const auto &local_lock_graph() const { return local_lock_graph_; }
|
||||
|
||||
protected:
|
||||
Transaction *CreateTransaction(TransactionId id, const Snapshot &snapshot) {
|
||||
return new Transaction(id, snapshot, *this);
|
||||
}
|
||||
|
||||
CommandId AdvanceCommand(Transaction *t) { return t->AdvanceCommand(); }
|
||||
|
||||
void SetCommand(Transaction *t, CommandId cid) { t->SetCommand(cid); }
|
||||
|
||||
private:
|
||||
// Map lock dependencies. Each entry maps (tx_that_wants_lock,
|
||||
// tx_that_holds_lock). Used for local deadlock resolution.
|
||||
// TODO consider global deadlock resolution.
|
||||
ConcurrentMap<TransactionId, TransactionId> local_lock_graph_;
|
||||
};
|
||||
} // namespace tx
|
||||
#ifdef MG_DISTRIBUTED
|
||||
#include "transactions/distributed/engine.hpp"
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
@ -9,10 +9,9 @@
|
||||
|
||||
namespace tx {
|
||||
|
||||
EngineSingleNode::EngineSingleNode(durability::WriteAheadLog *wal)
|
||||
: wal_(wal) {}
|
||||
Engine::Engine(durability::WriteAheadLog *wal) : wal_(wal) {}
|
||||
|
||||
Transaction *EngineSingleNode::Begin() {
|
||||
Transaction *Engine::Begin() {
|
||||
VLOG(11) << "[Tx] Starting transaction " << counter_ + 1;
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
|
||||
@ -26,7 +25,7 @@ Transaction *EngineSingleNode::Begin() {
|
||||
return t;
|
||||
}
|
||||
|
||||
CommandId EngineSingleNode::Advance(TransactionId id) {
|
||||
CommandId Engine::Advance(TransactionId id) {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
|
||||
auto it = store_.find(id);
|
||||
@ -37,7 +36,7 @@ CommandId EngineSingleNode::Advance(TransactionId id) {
|
||||
return AdvanceCommand(t);
|
||||
}
|
||||
|
||||
CommandId EngineSingleNode::UpdateCommand(TransactionId id) {
|
||||
CommandId Engine::UpdateCommand(TransactionId id) {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
auto it = store_.find(id);
|
||||
DCHECK(it != store_.end())
|
||||
@ -45,7 +44,7 @@ CommandId EngineSingleNode::UpdateCommand(TransactionId id) {
|
||||
return it->second->cid();
|
||||
}
|
||||
|
||||
void EngineSingleNode::Commit(const Transaction &t) {
|
||||
void Engine::Commit(const Transaction &t) {
|
||||
VLOG(11) << "[Tx] Commiting transaction " << t.id_;
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
clog_.set_committed(t.id_);
|
||||
@ -56,7 +55,7 @@ void EngineSingleNode::Commit(const Transaction &t) {
|
||||
store_.erase(store_.find(t.id_));
|
||||
}
|
||||
|
||||
void EngineSingleNode::Abort(const Transaction &t) {
|
||||
void Engine::Abort(const Transaction &t) {
|
||||
VLOG(11) << "[Tx] Aborting transaction " << t.id_;
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
clog_.set_aborted(t.id_);
|
||||
@ -67,11 +66,11 @@ void EngineSingleNode::Abort(const Transaction &t) {
|
||||
store_.erase(store_.find(t.id_));
|
||||
}
|
||||
|
||||
CommitLog::Info EngineSingleNode::Info(TransactionId tx) const {
|
||||
CommitLog::Info Engine::Info(TransactionId tx) const {
|
||||
return clog_.fetch_info(tx);
|
||||
}
|
||||
|
||||
Snapshot EngineSingleNode::GlobalGcSnapshot() {
|
||||
Snapshot Engine::GlobalGcSnapshot() {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
|
||||
// No active transactions.
|
||||
@ -87,29 +86,29 @@ Snapshot EngineSingleNode::GlobalGcSnapshot() {
|
||||
return snapshot_copy;
|
||||
}
|
||||
|
||||
Snapshot EngineSingleNode::GlobalActiveTransactions() {
|
||||
Snapshot Engine::GlobalActiveTransactions() {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
Snapshot active_transactions = active_;
|
||||
return active_transactions;
|
||||
}
|
||||
|
||||
TransactionId EngineSingleNode::LocalLast() const {
|
||||
TransactionId Engine::LocalLast() const {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
return counter_;
|
||||
}
|
||||
|
||||
TransactionId EngineSingleNode::GlobalLast() const { return LocalLast(); }
|
||||
TransactionId Engine::GlobalLast() const { return LocalLast(); }
|
||||
|
||||
TransactionId EngineSingleNode::LocalOldestActive() const {
|
||||
TransactionId Engine::LocalOldestActive() const {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
return active_.empty() ? counter_ + 1 : active_.front();
|
||||
}
|
||||
|
||||
void EngineSingleNode::GarbageCollectCommitLog(TransactionId tx_id) {
|
||||
void Engine::GarbageCollectCommitLog(TransactionId tx_id) {
|
||||
clog_.garbage_collect_older(tx_id);
|
||||
}
|
||||
|
||||
void EngineSingleNode::LocalForEachActiveTransaction(
|
||||
void Engine::LocalForEachActiveTransaction(
|
||||
std::function<void(Transaction &)> f) {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
for (auto transaction : active_) {
|
||||
@ -117,7 +116,7 @@ void EngineSingleNode::LocalForEachActiveTransaction(
|
||||
}
|
||||
}
|
||||
|
||||
Transaction *EngineSingleNode::RunningTransaction(TransactionId tx_id) {
|
||||
Transaction *Engine::RunningTransaction(TransactionId tx_id) {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
auto found = store_.find(tx_id);
|
||||
CHECK(found != store_.end())
|
||||
@ -125,7 +124,7 @@ Transaction *EngineSingleNode::RunningTransaction(TransactionId tx_id) {
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
void EngineSingleNode::EnsureNextIdGreater(TransactionId tx_id) {
|
||||
void Engine::EnsureNextIdGreater(TransactionId tx_id) {
|
||||
std::lock_guard<utils::SpinLock> guard(lock_);
|
||||
counter_ = std::max(tx_id, counter_);
|
||||
}
|
71
src/transactions/single_node/engine.hpp
Normal file
71
src/transactions/single_node/engine.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/// @file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <experimental/optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "durability/single_node/wal.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "utils/thread/sync.hpp"
|
||||
|
||||
namespace tx {
|
||||
|
||||
/// Single-node deployment transaction engine. Has complete functionality.
|
||||
class Engine final {
|
||||
public:
|
||||
/// @param wal - Optional. If present, the Engine will write tx
|
||||
/// Begin/Commit/Abort atomically (while under lock).
|
||||
explicit Engine(durability::WriteAheadLog *wal = nullptr);
|
||||
|
||||
Engine(const Engine &) = delete;
|
||||
Engine(Engine &&) = delete;
|
||||
Engine &operator=(const Engine &) = delete;
|
||||
Engine &operator=(Engine &&) = delete;
|
||||
|
||||
Transaction *Begin();
|
||||
CommandId Advance(TransactionId id);
|
||||
CommandId UpdateCommand(TransactionId id);
|
||||
void Commit(const Transaction &t);
|
||||
void Abort(const Transaction &t);
|
||||
CommitLog::Info Info(TransactionId tx) const;
|
||||
Snapshot GlobalGcSnapshot();
|
||||
Snapshot GlobalActiveTransactions();
|
||||
TransactionId GlobalLast() const;
|
||||
TransactionId LocalLast() const;
|
||||
TransactionId LocalOldestActive() const;
|
||||
void LocalForEachActiveTransaction(std::function<void(Transaction &)> f);
|
||||
Transaction *RunningTransaction(TransactionId tx_id);
|
||||
void EnsureNextIdGreater(TransactionId tx_id);
|
||||
void GarbageCollectCommitLog(TransactionId tx_id);
|
||||
|
||||
auto &local_lock_graph() { return local_lock_graph_; }
|
||||
const auto &local_lock_graph() const { return local_lock_graph_; }
|
||||
|
||||
protected:
|
||||
Transaction *CreateTransaction(TransactionId id, const Snapshot &snapshot) {
|
||||
return new Transaction(id, snapshot, *this);
|
||||
}
|
||||
|
||||
CommandId AdvanceCommand(Transaction *t) { return t->AdvanceCommand(); }
|
||||
|
||||
void SetCommand(Transaction *t, CommandId cid) { t->SetCommand(cid); }
|
||||
|
||||
private:
|
||||
// Map lock dependencies. Each entry maps (tx_that_wants_lock,
|
||||
// tx_that_holds_lock). Used for local deadlock resolution.
|
||||
// TODO consider global deadlock resolution.
|
||||
ConcurrentMap<TransactionId, TransactionId> local_lock_graph_;
|
||||
|
||||
TransactionId counter_{0};
|
||||
CommitLog clog_;
|
||||
std::unordered_map<TransactionId, std::unique_ptr<Transaction>> store_;
|
||||
Snapshot active_;
|
||||
mutable utils::SpinLock lock_;
|
||||
// Optional. If present, the Engine will write tx Begin/Commit/Abort
|
||||
// atomically (while under lock).
|
||||
durability::WriteAheadLog *wal_{nullptr};
|
||||
};
|
||||
} // namespace tx
|
@ -1,56 +0,0 @@
|
||||
/// @file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <experimental/optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "durability/single_node/wal.hpp"
|
||||
#include "transactions/commit_log.hpp"
|
||||
#include "transactions/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "utils/thread/sync.hpp"
|
||||
|
||||
namespace tx {
|
||||
|
||||
/// Single-node deployment transaction engine. Has complete functionality.
|
||||
class EngineSingleNode final : public Engine {
|
||||
public:
|
||||
/// @param wal - Optional. If present, the Engine will write tx
|
||||
/// Begin/Commit/Abort atomically (while under lock).
|
||||
explicit EngineSingleNode(durability::WriteAheadLog *wal = nullptr);
|
||||
|
||||
EngineSingleNode(const EngineSingleNode &) = delete;
|
||||
EngineSingleNode(EngineSingleNode &&) = delete;
|
||||
EngineSingleNode &operator=(const EngineSingleNode &) = delete;
|
||||
EngineSingleNode &operator=(EngineSingleNode &&) = delete;
|
||||
|
||||
Transaction *Begin() override;
|
||||
CommandId Advance(TransactionId id) override;
|
||||
CommandId UpdateCommand(TransactionId id) override;
|
||||
void Commit(const Transaction &t) override;
|
||||
void Abort(const Transaction &t) override;
|
||||
CommitLog::Info Info(TransactionId tx) const override;
|
||||
Snapshot GlobalGcSnapshot() override;
|
||||
Snapshot GlobalActiveTransactions() override;
|
||||
TransactionId GlobalLast() const override;
|
||||
TransactionId LocalLast() const override;
|
||||
TransactionId LocalOldestActive() const override;
|
||||
void LocalForEachActiveTransaction(
|
||||
std::function<void(Transaction &)> f) override;
|
||||
Transaction *RunningTransaction(TransactionId tx_id) override;
|
||||
void EnsureNextIdGreater(TransactionId tx_id) override;
|
||||
void GarbageCollectCommitLog(TransactionId tx_id) override;
|
||||
|
||||
private:
|
||||
TransactionId counter_{0};
|
||||
CommitLog clog_;
|
||||
std::unordered_map<TransactionId, std::unique_ptr<Transaction>> store_;
|
||||
Snapshot active_;
|
||||
mutable utils::SpinLock lock_;
|
||||
// Optional. If present, the Engine will write tx Begin/Commit/Abort
|
||||
// atomically (while under lock).
|
||||
durability::WriteAheadLog *wal_{nullptr};
|
||||
};
|
||||
} // namespace tx
|
@ -12,7 +12,7 @@ class ExpansionBenchFixture : public benchmark::Fixture {
|
||||
protected:
|
||||
// GraphDb shouldn't be global constructed/destructed. See
|
||||
// documentation in database/single_node/graph_db.hpp for details.
|
||||
std::experimental::optional<database::SingleNode> db_;
|
||||
std::experimental::optional<database::GraphDb> db_;
|
||||
query::Interpreter interpreter_;
|
||||
|
||||
void SetUp(const benchmark::State &state) override {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "mvcc/single_node/record.hpp"
|
||||
#include "mvcc/single_node/version_list.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
class Prop : public mvcc::Record<Prop> {
|
||||
public:
|
||||
@ -19,7 +19,7 @@ class Prop : public mvcc::Record<Prop> {
|
||||
void MvccMix(benchmark::State &state) {
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
auto t1 = engine.Begin();
|
||||
mvcc::VersionList<Prop> version_list(*t1, 0, 0);
|
||||
|
||||
|
@ -31,7 +31,7 @@ static void AddChainedMatches(int num_matches, query::AstStorage &storage) {
|
||||
}
|
||||
|
||||
static void BM_PlanChainedMatches(benchmark::State &state) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
@ -101,7 +101,7 @@ static auto CreateIndexedVertices(int index_count, int vertex_count,
|
||||
}
|
||||
|
||||
static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
storage::Label label;
|
||||
storage::Property prop;
|
||||
int index_count = state.range(0);
|
||||
@ -134,7 +134,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
|
||||
static void BM_PlanAndEstimateIndexedMatchingWithCachedCounts(
|
||||
benchmark::State &state) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
storage::Label label;
|
||||
storage::Property prop;
|
||||
int index_count = state.range(0);
|
||||
|
@ -3,14 +3,14 @@
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "utils/timer.hpp"
|
||||
|
||||
void Benchmark(int64_t num_threads, int64_t num_transactions) {
|
||||
LOG(INFO) << "Testing with " << num_threads << " threads and "
|
||||
<< num_transactions << " transactions per thread...";
|
||||
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
std::vector<std::thread> threads;
|
||||
utils::Timer timer;
|
||||
for (int i = 0; i < num_threads; ++i) {
|
||||
|
@ -30,7 +30,7 @@ DEFINE_string(output_file, "", "Output file where shold the results be.");
|
||||
void KafkaBenchmarkMain() {
|
||||
google::SetUsageMessage("Memgraph kafka benchmark database server");
|
||||
query::Interpreter interpreter;
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
SessionData session_data{&db, &interpreter};
|
||||
|
||||
std::atomic<int64_t> query_counter{0};
|
||||
|
@ -553,7 +553,7 @@ int main(int argc, char *argv[]) {
|
||||
std::cerr << "File '" << in_db_filename << "' does not exist!" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
Timer planning_timer;
|
||||
InteractiveDbAccessor interactive_db(
|
||||
|
@ -75,7 +75,7 @@ int main(int argc, char *argv[]) {
|
||||
// TODO switch to GFlags, once finally available
|
||||
if (argc > 3) google::InitGoogleLogging(argv[0]);
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::cout << "Generating graph..." << std::endl;
|
||||
// fill_db;
|
||||
random_generate(db, node_count, edge_count);
|
||||
|
@ -11,7 +11,7 @@ int main(int argc, char *argv[]) {
|
||||
std::cout << "Usage: ./single_query 'RETURN \"query here\"'" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
auto results = query::Interpreter()(argv[1], *dba, {}, false);
|
||||
|
@ -24,7 +24,7 @@ RC_GTEST_PROP(RandomGraph, RandomGraph, (std::vector<std::string> vertex_labels,
|
||||
int vertices_num = vertex_labels.size();
|
||||
int edges_num = edge_types.size();
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::vector<VertexAccessor> vertices;
|
||||
std::unordered_map<VertexAccessor, std::string> vertex_label_map;
|
||||
std::unordered_map<EdgeAccessor, std::string> edge_type_map;
|
||||
|
@ -60,7 +60,7 @@ class SingleNodeDb : public Database {
|
||||
}
|
||||
|
||||
protected:
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
};
|
||||
|
||||
class SingleNodeBfsTest
|
||||
|
@ -164,7 +164,7 @@ TEST(BoltEncoder, VertexAndEdge) {
|
||||
output.clear();
|
||||
|
||||
// create vertex
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto db_accessor = db.Access();
|
||||
auto va1 = db_accessor->InsertVertex();
|
||||
auto va2 = db_accessor->InsertVertex();
|
||||
|
@ -6,10 +6,10 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/single_node/concurrent_id_mapper_single_node.hpp"
|
||||
#include "storage/single_node/concurrent_id_mapper.hpp"
|
||||
|
||||
using IdLabel = storage::Label;
|
||||
using MapperLabel = storage::SingleNodeConcurrentIdMapper<IdLabel>;
|
||||
using MapperLabel = storage::ConcurrentIdMapper<IdLabel>;
|
||||
|
||||
TEST(ConcurrentIdMapper, SameValueGivesSameId) {
|
||||
MapperLabel mapper;
|
||||
@ -54,7 +54,7 @@ TEST(ConcurrentIdMapper, SameIdReturnedMultipleThreads) {
|
||||
}
|
||||
|
||||
using IdProperty = storage::Property;
|
||||
using MapperProperty = storage::SingleNodeConcurrentIdMapper<IdProperty>;
|
||||
using MapperProperty = storage::ConcurrentIdMapper<IdProperty>;
|
||||
|
||||
TEST(ConcurrentIdMapper, PropertyLocation) {
|
||||
// TODO(ipaljak): write unit tests for storage::Common and all
|
||||
|
@ -35,7 +35,7 @@ using testing::UnorderedElementsAre;
|
||||
class Base {
|
||||
public:
|
||||
explicit Base(const std::string &query) : query_string_(query) {}
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> db_accessor_{db_.Access()};
|
||||
ParsingContext context_;
|
||||
Parameters parameters_;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/single_node/vertex.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
#include "mvcc_gc_common.hpp"
|
||||
|
||||
@ -14,9 +14,9 @@ using testing::UnorderedElementsAreArray;
|
||||
// Test index does it insert everything uniquely
|
||||
TEST(LabelsIndex, UniqueInsert) {
|
||||
database::KeyIndex<storage::Label, Vertex> index;
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
|
||||
auto t1 = engine.Begin();
|
||||
mvcc::VersionList<Vertex> vlist(*t1, 0, 0);
|
||||
@ -42,10 +42,10 @@ TEST(LabelsIndex, UniqueInsert) {
|
||||
|
||||
// Check if index filters duplicates.
|
||||
TEST(LabelsIndex, UniqueFilter) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
database::KeyIndex<storage::Label, Vertex> index;
|
||||
auto dba = db.Access();
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
|
||||
auto t1 = engine.Begin();
|
||||
mvcc::VersionList<Vertex> vlist1(*t1, 0, 0);
|
||||
@ -83,9 +83,9 @@ TEST(LabelsIndex, UniqueFilter) {
|
||||
// Delete not anymore relevant recods from index.
|
||||
TEST(LabelsIndex, Refresh) {
|
||||
database::KeyIndex<storage::Label, Vertex> index;
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto access = db.Access();
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
|
||||
// add two vertices to database
|
||||
auto t1 = engine.Begin();
|
||||
@ -122,7 +122,7 @@ TEST(LabelsIndex, Refresh) {
|
||||
|
||||
// Transaction hasn't ended and so the vertex is not visible.
|
||||
TEST(LabelsIndexDb, AddGetZeroLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->InsertVertex();
|
||||
vertex.add_label(dba->Label("test"));
|
||||
@ -135,7 +135,7 @@ TEST(LabelsIndexDb, AddGetZeroLabels) {
|
||||
// Test label index by adding and removing one vertex, and removing label from
|
||||
// another, while the third one with an irrelevant label exists.
|
||||
TEST(LabelsIndexDb, AddGetRemoveLabel) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "storage/common/types.hpp"
|
||||
#include "storage/single_node/indexes/label_property_index.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
#include "mvcc_gc_common.hpp"
|
||||
|
||||
@ -42,11 +42,11 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
public:
|
||||
SingleNode db_;
|
||||
GraphDb db_;
|
||||
LabelPropertyIndex index;
|
||||
LabelPropertyIndex::Key *key;
|
||||
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
tx::Transaction *t{nullptr};
|
||||
|
||||
mvcc::VersionList<Vertex> *vlist;
|
||||
@ -59,7 +59,7 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
|
||||
};
|
||||
|
||||
TEST(LabelPropertyIndex, CreateIndex) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
@ -69,7 +69,7 @@ TEST(LabelPropertyIndex, CreateIndex) {
|
||||
}
|
||||
|
||||
TEST(LabelPropertyIndex, DeleteIndex) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
@ -81,7 +81,7 @@ TEST(LabelPropertyIndex, DeleteIndex) {
|
||||
}
|
||||
|
||||
TEST(LabelPropertyIndex, IndexExistance) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
@ -94,7 +94,7 @@ TEST(LabelPropertyIndex, IndexExistance) {
|
||||
}
|
||||
|
||||
TEST(LabelPropertyIndex, Count) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
auto label = accessor->Label("label");
|
||||
auto property = accessor->Property("property");
|
||||
|
@ -9,7 +9,7 @@ DECLARE_int32(query_execution_time_sec);
|
||||
|
||||
TEST(TransactionTimeout, TransactionTimeout) {
|
||||
FLAGS_query_execution_time_sec = 3;
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
query::Interpreter interpreter;
|
||||
auto interpret = [&](auto &dba, const std::string &query) {
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
|
@ -343,7 +343,7 @@ TEST_F(Durability, WalEncoding) {
|
||||
{
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
ASSERT_EQ(v0.gid(), gid0);
|
||||
@ -418,7 +418,7 @@ TEST_F(Durability, SnapshotEncoding) {
|
||||
auto gid1 = generator.Next();
|
||||
auto gid2 = generator.Next();
|
||||
{
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
ASSERT_EQ(v0.gid(), gid0);
|
||||
@ -532,7 +532,7 @@ TEST_F(Durability, SnapshotEncoding) {
|
||||
}
|
||||
|
||||
TEST_F(Durability, SnapshotRecovery) {
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
MakeDb(db, 300, {0, 1, 2});
|
||||
MakeDb(db, 300);
|
||||
MakeDb(db, 300, {3, 4});
|
||||
@ -540,13 +540,13 @@ TEST_F(Durability, SnapshotRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
CompareDbs(db, recovered);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(Durability, SnapshotNoVerticesIdRecovery) {
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
MakeDb(db, 10);
|
||||
|
||||
// Erase all vertices, this should cause snapshot to not have any more
|
||||
@ -562,7 +562,7 @@ TEST_F(Durability, SnapshotNoVerticesIdRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
EXPECT_EQ(db.storage().VertexGenerator().LocalCount(),
|
||||
recovered.storage().VertexGenerator().LocalCount());
|
||||
EXPECT_EQ(db.storage().EdgeGenerator().LocalCount(),
|
||||
@ -573,7 +573,7 @@ TEST_F(Durability, SnapshotNoVerticesIdRecovery) {
|
||||
TEST_F(Durability, SnapshotAndWalIdRecovery) {
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 300);
|
||||
MakeSnapshot(0, db);
|
||||
MakeDb(db, 300);
|
||||
@ -583,7 +583,7 @@ TEST_F(Durability, SnapshotAndWalIdRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
EXPECT_EQ(db.storage().VertexGenerator().LocalCount(),
|
||||
recovered.storage().VertexGenerator().LocalCount());
|
||||
EXPECT_EQ(db.storage().EdgeGenerator().LocalCount(),
|
||||
@ -594,7 +594,7 @@ TEST_F(Durability, SnapshotAndWalIdRecovery) {
|
||||
TEST_F(Durability, OnlyWalIdRecovery) {
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 300);
|
||||
db.wal().Flush();
|
||||
ASSERT_EQ(DirFiles(snapshot_dir_).size(), 0);
|
||||
@ -602,7 +602,7 @@ TEST_F(Durability, OnlyWalIdRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
EXPECT_EQ(db.storage().VertexGenerator().LocalCount(),
|
||||
recovered.storage().VertexGenerator().LocalCount());
|
||||
EXPECT_EQ(db.storage().EdgeGenerator().LocalCount(),
|
||||
@ -621,7 +621,7 @@ TEST_F(Durability, WalRecovery) {
|
||||
for (auto &synchronous_commit : {false, true}) {
|
||||
CleanDurability();
|
||||
auto config = modify_config(DbConfig(), true, synchronous_commit);
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 100, {0, 1, 2});
|
||||
MakeDb(db, 100);
|
||||
MakeDb(db, 100, {3, 4});
|
||||
@ -637,7 +637,7 @@ TEST_F(Durability, WalRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
CompareDbs(db, recovered);
|
||||
}
|
||||
}
|
||||
@ -646,7 +646,7 @@ TEST_F(Durability, WalRecovery) {
|
||||
TEST_F(Durability, SnapshotAndWalRecovery) {
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 300, {0, 1, 2});
|
||||
MakeDb(db, 300);
|
||||
MakeSnapshot(0, db);
|
||||
@ -661,7 +661,7 @@ TEST_F(Durability, SnapshotAndWalRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
CompareDbs(db, recovered);
|
||||
}
|
||||
}
|
||||
@ -669,7 +669,7 @@ TEST_F(Durability, SnapshotAndWalRecovery) {
|
||||
TEST_F(Durability, SnapshotAndWalRecoveryAfterComplexTxSituation) {
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
|
||||
// The first transaction modifies and commits.
|
||||
auto dba_1 = db.Access();
|
||||
@ -711,7 +711,7 @@ TEST_F(Durability, SnapshotAndWalRecoveryAfterComplexTxSituation) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
ASSERT_EQ(VisibleVertexCount(recovered), 400);
|
||||
CompareDbs(db, recovered);
|
||||
}
|
||||
@ -722,7 +722,7 @@ TEST_F(Durability, NoWalDuringRecovery) {
|
||||
{
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 300, {0, 1, 2});
|
||||
|
||||
db.wal().Flush();
|
||||
@ -732,13 +732,13 @@ TEST_F(Durability, NoWalDuringRecovery) {
|
||||
{
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
EXPECT_EQ(DirFiles(wal_dir_).size(), wal_files_before);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(Durability, SnapshotRetention) {
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
for (auto &pair : {std::pair<int, int>{5, 10}, {5, 3}, {7, -1}}) {
|
||||
CleanDurability();
|
||||
int count, retain;
|
||||
@ -765,7 +765,7 @@ TEST_F(Durability, WalRetention) {
|
||||
{
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
MakeDb(db, 100);
|
||||
MakeSnapshot(0, db);
|
||||
MakeDb(db, 100);
|
||||
@ -788,7 +788,7 @@ TEST_F(Durability, SnapshotOnExit) {
|
||||
{
|
||||
auto config = DbConfig();
|
||||
config.snapshot_on_exit = true;
|
||||
database::SingleNode graph_db{config};
|
||||
database::GraphDb graph_db{config};
|
||||
}
|
||||
EXPECT_EQ(DirFiles(snapshot_dir_).size(), 1);
|
||||
}
|
||||
@ -877,7 +877,7 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
};
|
||||
|
||||
auto make_updates = [&run_updates, this](
|
||||
database::SingleNode &db, bool snapshot_during, bool snapshot_after) {
|
||||
database::GraphDb &db, bool snapshot_during, bool snapshot_after) {
|
||||
std::atomic<bool> keep_running{true};
|
||||
auto update_theads = run_updates(db, keep_running);
|
||||
std::this_thread::sleep_for(25ms);
|
||||
@ -899,7 +899,7 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
CleanDurability();
|
||||
auto config = DbConfig();
|
||||
config.durability_enabled = true;
|
||||
database::SingleNode db{config};
|
||||
database::GraphDb db{config};
|
||||
init_db(db);
|
||||
make_updates(db, combo.first, combo.second);
|
||||
|
||||
@ -907,12 +907,12 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
auto recovered_config = DbConfig();
|
||||
recovered_config.db_recover_on_startup = true;
|
||||
recovered_config.durability_enabled = true;
|
||||
database::SingleNode recovered{recovered_config};
|
||||
database::GraphDb recovered{recovered_config};
|
||||
CompareDbs(db, recovered);
|
||||
{
|
||||
for (auto &combo2 : combinations) {
|
||||
make_updates(recovered, combo2.first, combo2.second);
|
||||
database::SingleNode recovered_2{recovered_config};
|
||||
database::GraphDb recovered_2{recovered_config};
|
||||
CompareDbs(recovered, recovered_2);
|
||||
}
|
||||
}
|
||||
@ -923,7 +923,7 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
TEST_F(Durability, ContainsDurabilityFilesSnapshot) {
|
||||
ASSERT_FALSE(durability::ContainsDurabilityFiles(durability_dir_));
|
||||
{
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
MakeSnapshot(0, db);
|
||||
@ -934,7 +934,7 @@ TEST_F(Durability, ContainsDurabilityFilesSnapshot) {
|
||||
TEST_F(Durability, ContainsDurabilityFilesWal) {
|
||||
ASSERT_FALSE(durability::ContainsDurabilityFiles(durability_dir_));
|
||||
{
|
||||
database::SingleNode db{DbConfig(true, false)};
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
dba->Commit();
|
||||
@ -946,21 +946,21 @@ TEST_F(Durability, ContainsDurabilityFilesWal) {
|
||||
TEST_F(Durability, MoveToBackupSnapshot) {
|
||||
ASSERT_FALSE(durability::ContainsDurabilityFiles(backup_dir_));
|
||||
{
|
||||
database::SingleNode db{DbConfig()};
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
MakeSnapshot(0, db);
|
||||
}
|
||||
|
||||
// durability-enabled=true, db-recover-on-startup=false
|
||||
database::SingleNode db{DbConfig(true, false)};
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
ASSERT_TRUE(durability::ContainsDurabilityFiles(backup_dir_));
|
||||
}
|
||||
|
||||
TEST_F(Durability, MoveToBackupWal) {
|
||||
ASSERT_FALSE(durability::ContainsDurabilityFiles(backup_dir_));
|
||||
{
|
||||
database::SingleNode db{DbConfig(true, false)};
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
dba->Commit();
|
||||
@ -968,6 +968,6 @@ TEST_F(Durability, MoveToBackupWal) {
|
||||
}
|
||||
|
||||
// durability-enabled=true, db-recover-on-startup=false
|
||||
database::SingleNode db{DbConfig(true, false)};
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
ASSERT_TRUE(durability::ContainsDurabilityFiles(backup_dir_));
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
TEST(GraphDbTest, GarbageCollectIndices) {
|
||||
database::Config config;
|
||||
config.gc_cycle_sec = -1;
|
||||
database::SingleNode graph_db{config};
|
||||
database::GraphDb graph_db{config};
|
||||
std::unique_ptr<database::GraphDbAccessor> dba = graph_db.Access();
|
||||
|
||||
auto commit = [&] {
|
||||
|
@ -17,7 +17,7 @@ auto Count(TIterable iterable) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, InsertVertex) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
gid::Generator generator(0);
|
||||
|
||||
@ -37,7 +37,7 @@ TEST(GraphDbAccessorTest, InsertVertex) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, UniqueVertexId) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
SkipList<int64_t> ids;
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
@ -54,7 +54,7 @@ TEST(GraphDbAccessorTest, UniqueVertexId) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, RemoveVertexSameTransaction) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 0);
|
||||
@ -72,7 +72,7 @@ TEST(GraphDbAccessorTest, RemoveVertexSameTransaction) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
// first transaction creates a vertex
|
||||
{
|
||||
auto accessor = db.Access();
|
||||
@ -97,7 +97,7 @@ TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, InsertEdge) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto va1 = dba->InsertVertex();
|
||||
@ -139,7 +139,7 @@ TEST(GraphDbAccessorTest, InsertEdge) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, UniqueEdgeId) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
SkipList<int64_t> ids;
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
@ -160,7 +160,7 @@ TEST(GraphDbAccessorTest, UniqueEdgeId) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, RemoveEdge) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// setup (v1) - [:likes] -> (v2) <- [:hates] - (v3)
|
||||
@ -207,7 +207,7 @@ TEST(GraphDbAccessorTest, RemoveEdge) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, DetachRemoveVertex) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// setup (v0)- []->(v1)<-[]-(v2)<-[]-(v3)
|
||||
@ -281,7 +281,7 @@ TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
|
||||
// This test checks that we can detach remove the
|
||||
// same vertex / edge multiple times
|
||||
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// setup: make a fully connected N graph
|
||||
@ -324,7 +324,7 @@ TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Labels) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
Label label_friend = dba->Label("friend");
|
||||
@ -338,7 +338,7 @@ TEST(GraphDbAccessorTest, Labels) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, EdgeTypes) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
EdgeType edge_type = dba->EdgeType("likes");
|
||||
@ -352,7 +352,7 @@ TEST(GraphDbAccessorTest, EdgeTypes) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Properties) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
Property prop = dba->Property("name");
|
||||
@ -366,7 +366,7 @@ TEST(GraphDbAccessorTest, Properties) {
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Transfer) {
|
||||
SingleNode db;
|
||||
GraphDb db;
|
||||
|
||||
auto dba1 = db.Access();
|
||||
auto prop = dba1->Property("property");
|
||||
|
@ -22,7 +22,7 @@ auto Count(TIterable iterable) {
|
||||
*/
|
||||
class GraphDbAccessorIndex : public testing::Test {
|
||||
protected:
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
storage::Property property = dba->Property("property");
|
||||
storage::Label label = dba->Label("label");
|
||||
@ -137,7 +137,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyIndexCount) {
|
||||
TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
|
||||
const int ITER_COUNT = 10;
|
||||
for (int iter = 0; iter < ITER_COUNT; ++iter) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
const int THREAD_COUNT = 10;
|
||||
std::vector<std::thread> threads;
|
||||
for (int index = 0; index < THREAD_COUNT; ++index) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
class InterpreterTest : public ::testing::Test {
|
||||
protected:
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
query::Interpreter interpreter_;
|
||||
|
||||
auto Interpret(const std::string &query,
|
||||
|
@ -5,14 +5,14 @@
|
||||
#include "mvcc/common/version.hpp"
|
||||
#include "mvcc/single_node/record.hpp"
|
||||
#include "mvcc/single_node/version_list.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
#include "utils/thread/sync.hpp"
|
||||
|
||||
#include "mvcc_gc_common.hpp"
|
||||
|
||||
TEST(MVCC, Deadlock) {
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
|
||||
auto t0 = engine.Begin();
|
||||
mvcc::VersionList<Prop> version_list1(*t0, 0, 0);
|
||||
@ -32,7 +32,7 @@ TEST(MVCC, Deadlock) {
|
||||
TEST(MVCC, UpdateDontDelete) {
|
||||
std::atomic<int> count{0};
|
||||
{
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
auto t1 = engine.Begin();
|
||||
mvcc::VersionList<DestrCountRec> version_list(*t1, 0, 0, count);
|
||||
engine.Commit(*t1);
|
||||
@ -56,7 +56,7 @@ TEST(MVCC, UpdateDontDelete) {
|
||||
|
||||
// Check that we get the oldest record.
|
||||
TEST(MVCC, Oldest) {
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
auto t1 = engine.Begin();
|
||||
mvcc::VersionList<Prop> version_list(*t1, 0, 0);
|
||||
auto first = version_list.Oldest();
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "mvcc/common/version.hpp"
|
||||
#include "mvcc/single_node/record.hpp"
|
||||
#include "mvcc/single_node/version_list.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
|
||||
class TestClass : public mvcc::Record<TestClass> {
|
||||
@ -58,7 +58,7 @@ class Mvcc : public ::testing::Test {
|
||||
}
|
||||
// variable where number of versions is stored
|
||||
int version_list_size = 0;
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
tx::Transaction *t1 = engine.Begin();
|
||||
mvcc::VersionList<TestClass> version_list{*t1, 0, 0, version_list_size};
|
||||
TestClass *v1 = nullptr;
|
||||
|
@ -11,13 +11,13 @@
|
||||
#include "mvcc/single_node/version_list.hpp"
|
||||
#include "storage/single_node/garbage_collector.hpp"
|
||||
#include "storage/single_node/vertex.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
#include "mvcc_gc_common.hpp"
|
||||
|
||||
class MvccGcTest : public ::testing::Test {
|
||||
protected:
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
|
||||
private:
|
||||
tx::Transaction *t0 = engine.Begin();
|
||||
@ -115,7 +115,7 @@ TEST_F(MvccGcTest, OldestTransactionSnapshot) {
|
||||
*/
|
||||
TEST(GarbageCollector, GcClean) {
|
||||
ConcurrentMap<int64_t, mvcc::VersionList<DestrCountRec> *> collection;
|
||||
tx::EngineSingleNode engine;
|
||||
tx::Engine engine;
|
||||
DeferredDeleter<DestrCountRec> deleter;
|
||||
DeferredDeleter<mvcc::VersionList<DestrCountRec>> vlist_deleter;
|
||||
GarbageCollector<decltype(collection), DestrCountRec> gc(collection, deleter,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "mvcc/single_node/record.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
|
||||
/**
|
||||
* @brief - Empty class which inherits from mvcc:Record.
|
||||
@ -29,7 +29,7 @@ class DestrCountRec : public mvcc::Record<DestrCountRec> {
|
||||
// helper function for creating a GC snapshot
|
||||
// if given a nullptr it makes a GC snapshot like there
|
||||
// are no active transactions
|
||||
auto GcSnapshot(tx::EngineSingleNode &engine, tx::Transaction *t) {
|
||||
auto GcSnapshot(tx::Engine &engine, tx::Transaction *t) {
|
||||
if (t != nullptr) {
|
||||
tx::Snapshot gc_snap = t->snapshot();
|
||||
gc_snap.insert(t->id_);
|
||||
|
@ -6,7 +6,7 @@
|
||||
/// AstStorage storage; // Macros rely on storage being in scope.
|
||||
/// // PROPERTY_LOOKUP and PROPERTY_PAIR macros
|
||||
/// // rely on a DbAccessor *reference* named dba.
|
||||
/// database::SingleNode db;
|
||||
/// database::GraphDb db;
|
||||
/// auto dba_ptr = db.Access();
|
||||
/// auto &dba = *dba_ptr;
|
||||
///
|
||||
|
@ -23,7 +23,7 @@ using MiscParam = CostEstimator<database::GraphDbAccessor>::MiscParam;
|
||||
* estimation testing. */
|
||||
class QueryCostEstimator : public ::testing::Test {
|
||||
protected:
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
storage::Label label = dba->Label("label");
|
||||
storage::Property property = dba->Property("property");
|
||||
|
@ -29,7 +29,7 @@ namespace {
|
||||
|
||||
class ExpressionEvaluatorTest : public ::testing::Test {
|
||||
protected:
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
|
||||
AstStorage storage;
|
||||
|
@ -27,7 +27,7 @@ TEST(QueryPlan, Accumulate) {
|
||||
// with accumulation we expect them to be [[2, 2], [2, 2]]
|
||||
|
||||
auto check = [&](bool accumulate) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto prop = dba.Property("x");
|
||||
@ -88,7 +88,7 @@ TEST(QueryPlan, AccumulateAdvance) {
|
||||
// to get correct results we need to advance the command
|
||||
|
||||
auto check = [&](bool advance) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -150,7 +150,7 @@ std::shared_ptr<Produce> MakeAggregationProduce(
|
||||
/** Test fixture for all the aggregation ops in one return. */
|
||||
class QueryPlanAggregateOps : public ::testing::Test {
|
||||
protected:
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
storage::Property prop = dba.Property("prop");
|
||||
@ -290,7 +290,7 @@ TEST(QueryPlan, AggregateGroupByValues) {
|
||||
// Tests that distinct groups are aggregated properly for values of all types.
|
||||
// Also test the "remember" part of the Aggregation API as final results are
|
||||
// obtained via a property lookup of a remembered node.
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -350,7 +350,7 @@ TEST(QueryPlan, AggregateMultipleGroupBy) {
|
||||
// in this test we have 3 different properties that have different values
|
||||
// for different records and assert that we get the correct combination
|
||||
// of values in our groups
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -386,7 +386,7 @@ TEST(QueryPlan, AggregateMultipleGroupBy) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, AggregateNoInput) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -413,7 +413,7 @@ TEST(QueryPlan, AggregateCountEdgeCases) {
|
||||
// - 2 vertices in database, property set on one
|
||||
// - 2 vertices in database, property set on both
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto prop = dba.Property("prop");
|
||||
@ -466,7 +466,7 @@ TEST(QueryPlan, AggregateFirstValueTypes) {
|
||||
// testing exceptions that get emitted by the first-value
|
||||
// type check
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -524,7 +524,7 @@ TEST(QueryPlan, AggregateTypes) {
|
||||
// does not check all combinations that can result in an exception
|
||||
// (that logic is defined and tested by TypedValue)
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -581,7 +581,7 @@ TEST(QueryPlan, AggregateTypes) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Unwind) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
@ -22,7 +22,7 @@ using namespace query;
|
||||
using namespace query::plan;
|
||||
|
||||
TEST(QueryPlan, Skip) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
AstStorage storage;
|
||||
@ -51,7 +51,7 @@ TEST(QueryPlan, Skip) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Limit) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
AstStorage storage;
|
||||
@ -83,7 +83,7 @@ TEST(QueryPlan, CreateLimit) {
|
||||
// CREATE (n), (m)
|
||||
// MATCH (n) CREATE (m) LIMIT 1
|
||||
// in the end we need to have 3 vertices in the db
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
@ -104,7 +104,7 @@ TEST(QueryPlan, CreateLimit) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OrderBy) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
AstStorage storage;
|
||||
@ -164,7 +164,7 @@ TEST(QueryPlan, OrderBy) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OrderByMultiple) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
AstStorage storage;
|
||||
@ -221,7 +221,7 @@ TEST(QueryPlan, OrderByMultiple) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OrderByExceptions) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
AstStorage storage;
|
||||
|
@ -17,7 +17,7 @@ using namespace query;
|
||||
using namespace query::plan;
|
||||
|
||||
TEST(QueryPlan, CreateNodeWithAttributes) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -52,7 +52,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
|
||||
|
||||
TEST(QueryPlan, CreateReturn) {
|
||||
// test CREATE (n:Person {age: 42}) RETURN n, n.age
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -94,7 +94,7 @@ TEST(QueryPlan, CreateReturn) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, CreateExpand) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -169,7 +169,7 @@ TEST(QueryPlan, CreateExpand) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchCreateNode) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add three nodes we'll match and expand-create from
|
||||
@ -196,7 +196,7 @@ TEST(QueryPlan, MatchCreateNode) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchCreateExpand) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add three nodes we'll match and expand-create from
|
||||
@ -248,7 +248,7 @@ TEST(QueryPlan, MatchCreateExpand) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Delete) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
@ -338,7 +338,7 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
// MATCH (n)-[r]-(m) [DETACH] DELETE n, r, m
|
||||
|
||||
auto test_delete = [](bool detach) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -377,7 +377,7 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -417,7 +417,7 @@ TEST(QueryPlan, DeleteReturn) {
|
||||
|
||||
TEST(QueryPlan, DeleteNull) {
|
||||
// test (simplified) WITH Null as x delete x
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -438,7 +438,7 @@ TEST(QueryPlan, DeleteAdvance) {
|
||||
// note that Neo does not fail when the deleted
|
||||
// record is not used in subsequent clauses, but
|
||||
// we are not yet compatible with that
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
@ -457,7 +457,7 @@ TEST(QueryPlan, DeleteAdvance) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, SetProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -510,7 +510,7 @@ TEST(QueryPlan, SetProperty) {
|
||||
|
||||
TEST(QueryPlan, SetProperties) {
|
||||
auto test_set_properties = [](bool update) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// graph: ({a: 0})-[:R {b:1}]->({c:2})
|
||||
@ -580,7 +580,7 @@ TEST(QueryPlan, SetProperties) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, SetLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto label1 = dba->Label("label1");
|
||||
@ -607,7 +607,7 @@ TEST(QueryPlan, SetLabels) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, RemoveProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -661,7 +661,7 @@ TEST(QueryPlan, RemoveProperty) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, RemoveLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto label1 = dba->Label("label1");
|
||||
@ -693,7 +693,7 @@ TEST(QueryPlan, RemoveLabels) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, NodeFilterSet) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
|
||||
@ -735,7 +735,7 @@ TEST(QueryPlan, NodeFilterSet) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, FilterRemove) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
|
||||
@ -773,7 +773,7 @@ TEST(QueryPlan, FilterRemove) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, SetRemove) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto label1 = dba->Label("label1");
|
||||
@ -803,7 +803,7 @@ TEST(QueryPlan, Merge) {
|
||||
// - merge_match branch looks for an expansion (any direction)
|
||||
// and sets some property (for result validation)
|
||||
// - merge_create branch just sets some other property
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto v1 = dba.InsertVertex();
|
||||
@ -850,7 +850,7 @@ TEST(QueryPlan, Merge) {
|
||||
TEST(QueryPlan, MergeNoInput) {
|
||||
// merge with no input, creates a single node
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -869,7 +869,7 @@ TEST(QueryPlan, MergeNoInput) {
|
||||
|
||||
TEST(QueryPlan, SetPropertyOnNull) {
|
||||
// SET (Null).prop = 42
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
AstStorage storage;
|
||||
@ -885,7 +885,7 @@ TEST(QueryPlan, SetPropertyOnNull) {
|
||||
|
||||
TEST(QueryPlan, SetPropertiesOnNull) {
|
||||
// OPTIONAL MATCH (n) SET n = n
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -902,7 +902,7 @@ TEST(QueryPlan, SetPropertiesOnNull) {
|
||||
|
||||
TEST(QueryPlan, SetLabelsOnNull) {
|
||||
// OPTIONAL MATCH (n) SET n :label
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
AstStorage storage;
|
||||
@ -920,7 +920,7 @@ TEST(QueryPlan, SetLabelsOnNull) {
|
||||
|
||||
TEST(QueryPlan, RemovePropertyOnNull) {
|
||||
// REMOVE (Null).prop
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
AstStorage storage;
|
||||
@ -935,7 +935,7 @@ TEST(QueryPlan, RemovePropertyOnNull) {
|
||||
|
||||
TEST(QueryPlan, RemoveLabelsOnNull) {
|
||||
// OPTIONAL MATCH (n) REMOVE n :label
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
AstStorage storage;
|
||||
@ -953,7 +953,7 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
|
||||
|
||||
TEST(QueryPlan, CreateIndex) {
|
||||
// CREATE INDEX ON :Label(property)
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
auto property = dba->Property("property");
|
||||
@ -965,7 +965,7 @@ TEST(QueryPlan, CreateIndex) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteSetProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Add a single vertex.
|
||||
@ -989,7 +989,7 @@ TEST(QueryPlan, DeleteSetProperty) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteSetPropertiesFromMap) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Add a single vertex.
|
||||
@ -1021,7 +1021,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromMap) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Add a single vertex.
|
||||
@ -1053,7 +1053,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteRemoveLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
dba->InsertVertex();
|
||||
@ -1073,7 +1073,7 @@ TEST(QueryPlan, DeleteRemoveLabels) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteRemoveProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
// Add a single vertex.
|
||||
|
@ -16,7 +16,7 @@ DECLARE_bool(query_cost_planner);
|
||||
|
||||
class QueryExecution : public testing::Test {
|
||||
protected:
|
||||
std::experimental::optional<database::SingleNode> db_;
|
||||
std::experimental::optional<database::GraphDb> db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_;
|
||||
|
||||
void SetUp() {
|
||||
|
@ -26,7 +26,7 @@ using namespace query::plan;
|
||||
|
||||
class MatchReturnFixture : public testing::Test {
|
||||
protected:
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -90,7 +90,7 @@ TEST_F(MatchReturnFixture, MatchReturnPath) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchReturnCartesian) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
dba->InsertVertex().add_label(dba->Label("l1"));
|
||||
@ -123,7 +123,7 @@ TEST(QueryPlan, MatchReturnCartesian) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, StandaloneReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a few nodes to the database
|
||||
@ -145,7 +145,7 @@ TEST(QueryPlan, StandaloneReturn) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, NodeFilterLabelsAndProperties) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -202,7 +202,7 @@ TEST(QueryPlan, NodeFilterLabelsAndProperties) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, NodeFilterMultipleLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a few nodes to the database
|
||||
@ -252,7 +252,7 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Cartesian) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto add_vertex = [&dba](std::string label) {
|
||||
@ -297,7 +297,7 @@ TEST(QueryPlan, Cartesian) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, CartesianEmptySet) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
AstStorage storage;
|
||||
@ -326,7 +326,7 @@ TEST(QueryPlan, CartesianEmptySet) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, CartesianThreeWay) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto add_vertex = [&dba](std::string label) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
@ -386,7 +386,7 @@ TEST(QueryPlan, CartesianThreeWay) {
|
||||
|
||||
class ExpandFixture : public testing::Test {
|
||||
protected:
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -483,7 +483,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
// a lot below in test declaration
|
||||
using map_int = std::unordered_map<int, int>;
|
||||
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
// labels for layers in the double chain
|
||||
std::vector<storage::Label> labels;
|
||||
@ -839,7 +839,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
||||
protected:
|
||||
// style-guide non-conformant name due to PROPERTY_PAIR and
|
||||
// PROPERTY_LOOKUP macro requirements
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
std::pair<std::string, storage::Property> prop = PROPERTY_PAIR("property");
|
||||
@ -1192,7 +1192,7 @@ TEST_F(QueryPlanExpandWeightedShortestPath, Exceptions) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ExpandOptional) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
AstStorage storage;
|
||||
@ -1252,7 +1252,7 @@ TEST(QueryPlan, ExpandOptional) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OptionalMatchEmptyDB) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
AstStorage storage;
|
||||
@ -1274,7 +1274,7 @@ TEST(QueryPlan, OptionalMatchEmptyDB) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1302,7 +1302,7 @@ TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph with 2 connected, unlabeled nodes.
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -1351,7 +1351,7 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ExpandExistingNode) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// make a graph (v1)->(v2) that
|
||||
@ -1395,7 +1395,7 @@ TEST(QueryPlan, ExpandExistingNode) {
|
||||
TEST(QueryPlan, ExpandBothCycleEdgeCase) {
|
||||
// we're testing that expanding on BOTH
|
||||
// does only one expansion for a cycle
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v = dba->InsertVertex();
|
||||
@ -1413,7 +1413,7 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, EdgeFilter) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -1483,7 +1483,7 @@ TEST(QueryPlan, EdgeFilter) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -1518,7 +1518,7 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Filter) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
|
||||
@ -1548,7 +1548,7 @@ TEST(QueryPlan, Filter) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ExpandUniquenessFilter) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
// make a graph that has (v1)->(v2) and a recursive edge (v1)->(v1)
|
||||
@ -1596,7 +1596,7 @@ TEST(QueryPlan, Distinct) {
|
||||
// test queries like
|
||||
// UNWIND [1, 2, 3, 3] AS x RETURN DISTINCT x
|
||||
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1638,7 +1638,7 @@ TEST(QueryPlan, Distinct) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabel) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Add a vertex with a label and one without.
|
||||
auto label = dba->Label("label");
|
||||
@ -1665,7 +1665,7 @@ TEST(QueryPlan, ScanAllByLabel) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
// Add 5 vertices with same label, but with different property values.
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
@ -1735,7 +1735,7 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
// Add 2 vertices with same label, but with property values that cannot be
|
||||
// compared. On the other hand, equality works fine.
|
||||
auto label = db.Access()->Label("label");
|
||||
@ -1774,7 +1774,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
{
|
||||
@ -1802,7 +1802,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
{
|
||||
@ -1852,7 +1852,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
// Add 2 vertices with the same label, but one has a property value while
|
||||
// the other does not. Checking if the value is equal to null, should
|
||||
// yield no results.
|
||||
@ -1885,7 +1885,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
// Add 2 vertices with the same label, but one has a property value while
|
||||
// the other does not. Checking if the value is between nulls, should
|
||||
// yield no results.
|
||||
@ -1920,7 +1920,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
{
|
||||
@ -1952,7 +1952,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
|
||||
|
@ -15,7 +15,7 @@ using namespace query;
|
||||
|
||||
class TestSymbolGenerator : public ::testing::Test {
|
||||
protected:
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
SymbolTable symbol_table;
|
||||
|
@ -83,7 +83,7 @@ void CheckPlansProduce(
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -103,7 +103,7 @@ TEST(TestVariableStartPlanner, MatchReturn) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -139,7 +139,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -165,7 +165,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -190,7 +190,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -213,7 +213,7 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchVariableExpand) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r1]-> (v2) -[:r2]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -236,7 +236,7 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto id = dba.Property("id");
|
||||
@ -264,7 +264,7 @@ TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto id = dba->Property("id");
|
||||
// Graph (v1 {id:1}) -[:r1]-> (v2) -[:r2]-> (v3)
|
||||
@ -290,7 +290,7 @@ TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchBfs) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto id = dba.Property("id");
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "storage/single_node/vertex_accessor.hpp"
|
||||
|
||||
TEST(RecordAccessor, Properties) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto vertex = dba->InsertVertex();
|
||||
@ -35,7 +35,7 @@ TEST(RecordAccessor, Properties) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, DbAccessor) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto vertex = dba->InsertVertex();
|
||||
@ -46,7 +46,7 @@ TEST(RecordAccessor, DbAccessor) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, RecordEquality) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -61,7 +61,7 @@ TEST(RecordAccessor, RecordEquality) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, GlobalToLocalAddressConversion) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
@ -73,7 +73,7 @@ TEST(RecordAccessor, GlobalToLocalAddressConversion) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
|
||||
// test both Switches work on new record
|
||||
{
|
||||
@ -109,7 +109,7 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, Reconstruct) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
|
||||
{
|
||||
@ -143,7 +143,7 @@ TEST(RecordAccessor, Reconstruct) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, VertexLabels) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto &labels = v1.labels();
|
||||
@ -184,7 +184,7 @@ TEST(RecordAccessor, VertexLabels) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, EdgeType) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
@ -198,7 +198,7 @@ TEST(RecordAccessor, EdgeType) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, EdgeIsCycle) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
@ -211,7 +211,7 @@ TEST(RecordAccessor, EdgeIsCycle) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, VertexEdgeConnections) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
@ -243,7 +243,7 @@ TEST(RecordAccessor, VertexEdgeConnections) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
@ -278,7 +278,7 @@ TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, VertexEdgeConnectionsWithEdgeType) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "durability/single_node/state_delta.hpp"
|
||||
|
||||
TEST(StateDelta, CreateVertex) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
@ -24,7 +24,7 @@ TEST(StateDelta, CreateVertex) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, RemoveVertex) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
@ -47,7 +47,7 @@ TEST(StateDelta, RemoveVertex) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, CreateEdge) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
auto gid1 = generator.Next();
|
||||
@ -74,7 +74,7 @@ TEST(StateDelta, CreateEdge) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, RemoveEdge) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
auto gid1 = generator.Next();
|
||||
@ -100,7 +100,7 @@ TEST(StateDelta, RemoveEdge) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, AddLabel) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
@ -126,7 +126,7 @@ TEST(StateDelta, AddLabel) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, RemoveLabel) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
@ -152,7 +152,7 @@ TEST(StateDelta, RemoveLabel) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, SetPropertyVertex) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
@ -178,7 +178,7 @@ TEST(StateDelta, SetPropertyVertex) {
|
||||
}
|
||||
|
||||
TEST(StateDelta, SetPropertyEdge) {
|
||||
database::SingleNode db;
|
||||
database::GraphDb db;
|
||||
gid::Generator generator(0);
|
||||
auto gid0 = generator.Next();
|
||||
auto gid1 = generator.Next();
|
||||
|
@ -4,13 +4,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "data_structures/concurrent/skiplist.hpp"
|
||||
#include "transactions/single_node/engine_single_node.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
|
||||
using namespace tx;
|
||||
|
||||
TEST(Engine, GcSnapshot) {
|
||||
EngineSingleNode engine;
|
||||
Engine engine;
|
||||
ASSERT_EQ(engine.GlobalGcSnapshot(), Snapshot({1}));
|
||||
|
||||
std::vector<Transaction *> transactions;
|
||||
@ -38,7 +38,7 @@ TEST(Engine, GcSnapshot) {
|
||||
}
|
||||
|
||||
TEST(Engine, Advance) {
|
||||
EngineSingleNode engine;
|
||||
Engine engine;
|
||||
|
||||
auto t0 = engine.Begin();
|
||||
auto t1 = engine.Begin();
|
||||
@ -51,7 +51,7 @@ TEST(Engine, Advance) {
|
||||
}
|
||||
|
||||
TEST(Engine, ConcurrentBegin) {
|
||||
EngineSingleNode engine;
|
||||
Engine engine;
|
||||
std::vector<std::thread> threads;
|
||||
SkipList<TransactionId> tx_ids;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
@ -67,7 +67,7 @@ TEST(Engine, ConcurrentBegin) {
|
||||
}
|
||||
|
||||
TEST(Engine, RunningTransaction) {
|
||||
EngineSingleNode engine;
|
||||
Engine engine;
|
||||
auto t0 = engine.Begin();
|
||||
auto t1 = engine.Begin();
|
||||
EXPECT_EQ(t0, engine.RunningTransaction(t0->id_));
|
||||
@ -76,7 +76,7 @@ TEST(Engine, RunningTransaction) {
|
||||
}
|
||||
|
||||
TEST(Engine, EnsureTxIdGreater) {
|
||||
EngineSingleNode engine;
|
||||
Engine engine;
|
||||
ASSERT_LE(engine.Begin()->id_, 40);
|
||||
engine.EnsureNextIdGreater(42);
|
||||
EXPECT_EQ(engine.Begin()->id_, 43);
|
||||
|
@ -18,7 +18,7 @@ using query::TypedValueException;
|
||||
class AllTypesFixture : public testing::Test {
|
||||
protected:
|
||||
std::vector<TypedValue> values_;
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
|
||||
void SetUp() override {
|
||||
|
@ -24,13 +24,13 @@ class RecoveryTest : public ::testing::Test {
|
||||
durability::RecoveryData recovery_data;
|
||||
durability::RecoverOnlySnapshot(durability_dir, &db_, &recovery_data,
|
||||
std::experimental::nullopt, 0);
|
||||
database::SingleNodeRecoveryTransanctions recovery_transactions(&db_);
|
||||
durability::RecoveryTransactions recovery_transactions(&db_);
|
||||
durability::RecoverWal(durability_dir, &db_, &recovery_data,
|
||||
&recovery_transactions);
|
||||
durability::RecoverIndexes(&db_, recovery_data.indexes);
|
||||
}
|
||||
|
||||
database::SingleNode db_;
|
||||
database::GraphDb db_;
|
||||
};
|
||||
|
||||
TEST_F(RecoveryTest, TestVerticesRecovered) {
|
||||
|
Loading…
Reference in New Issue
Block a user