Compare commits

...

13 Commits

Author SHA1 Message Date
Andi Skrgat
cb41396e86 Local shared poc 2023-05-08 15:55:52 +02:00
Aidar Samerkhanov
614e321ebb Get rid of unnecessary copy during query engine iterator operator++ 2023-05-08 10:56:03 +00:00
Aidar Samerkhanov
9a70476872 Fix visibility of vertex in reinit VertexAccessor 2023-05-08 09:35:48 +00:00
Aidar Samerkhanov
d47372b455 Optimize usage of unique_ptr in iterators operator++ 2023-05-05 20:47:59 +00:00
Aidar Samerkhanov
9e710aa00b Replace implicit move by copy in MakeEdgeAccessor 2023-05-03 21:13:18 +00:00
Aidar Samerkhanov
59ed253b82 Fix SubgraphVertexAccessor in and out eges in e2e 2023-05-03 15:49:16 +00:00
Aidar Samerkhanov
dfdba859ff Fix query engine build 2023-04-28 15:02:14 +00:00
Aidar Samerkhanov
01428b49e1 Fix random_graph in property based testing 2023-04-28 12:46:32 +00:00
Aidar Samerkhanov
b98c9b94ca Fix build of full memgraph 2023-04-27 13:34:10 +00:00
Aidar Samerkhanov
54e6aef954 Fixed build of storage v2 gc and random_graph test 2023-04-26 19:24:41 +00:00
Aidar Samerkhanov
20f16eafa3 Fix mg_import_csv build 2023-04-26 12:51:11 +00:00
Aidar Samerkhanov
a69829d01b Fix build of concurrent storage indices tests 2023-04-26 12:12:13 +00:00
Aidar Samerkhanov
01e0dcdfb4 Fix build of concurrent storage unique constraints test 2023-04-26 11:47:05 +00:00
23 changed files with 340 additions and 290 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -20,7 +20,7 @@
#include <unordered_map>
#include "helpers.hpp"
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
#include "utils/exceptions.hpp"
#include "utils/logging.hpp"
#include "utils/message.hpp"
@@ -421,7 +421,7 @@ void ProcessNodeRow(memgraph::storage::Storage *store, const std::vector<std::st
std::unordered_map<NodeId, memgraph::storage::Gid> *node_id_map) {
std::optional<NodeId> id;
auto acc = store->Access();
auto node = acc.CreateVertex();
auto node = acc->CreateVertex();
for (size_t i = 0; i < row.size(); ++i) {
const auto &field = fields[i];
const auto &value = row[i];
@@ -442,7 +442,7 @@ void ProcessNodeRow(memgraph::storage::Storage *store, const std::vector<std::st
throw LoadException("Node with ID '{}' already exists", node_id);
}
}
node_id_map->emplace(node_id, node.Gid());
node_id_map->emplace(node_id, node->Gid());
if (!field.name.empty()) {
memgraph::storage::PropertyValue pv_id;
if (FLAGS_id_type == "INTEGER") {
@@ -450,29 +450,29 @@ void ProcessNodeRow(memgraph::storage::Storage *store, const std::vector<std::st
} else {
pv_id = memgraph::storage::PropertyValue(node_id.id);
}
auto old_node_property = node.SetProperty(acc.NameToProperty(field.name), pv_id);
auto old_node_property = node->SetProperty(acc->NameToProperty(field.name), pv_id);
if (!old_node_property.HasValue()) throw LoadException("Couldn't add property '{}' to the node", field.name);
if (!old_node_property->IsNull()) throw LoadException("The property '{}' already exists", field.name);
}
id = node_id;
} else if (field.type == "LABEL") {
for (const auto &label : memgraph::utils::Split(value, FLAGS_array_delimiter)) {
auto node_label = node.AddLabel(acc.NameToLabel(label));
auto node_label = node->AddLabel(acc->NameToLabel(label));
if (!node_label.HasValue()) throw LoadException("Couldn't add label '{}' to the node", label);
if (!*node_label) throw LoadException("The label '{}' already exists", label);
}
} else if (field.type != "IGNORE") {
auto old_node_property = node.SetProperty(acc.NameToProperty(field.name), StringToValue(value, field.type));
auto old_node_property = node->SetProperty(acc->NameToProperty(field.name), StringToValue(value, field.type));
if (!old_node_property.HasValue()) throw LoadException("Couldn't add property '{}' to the node", field.name);
if (!old_node_property->IsNull()) throw LoadException("The property '{}' already exists", field.name);
}
}
for (const auto &label : additional_labels) {
auto node_label = node.AddLabel(acc.NameToLabel(label));
auto node_label = node->AddLabel(acc->NameToLabel(label));
if (!node_label.HasValue()) throw LoadException("Couldn't add label '{}' to the node", label);
if (!*node_label) throw LoadException("The label '{}' already exists", label);
}
if (acc.Commit().HasError()) throw LoadException("Couldn't store the node");
if (acc->Commit().HasError()) throw LoadException("Couldn't store the node");
}
void ProcessNodes(memgraph::storage::Storage *store, const std::string &nodes_path,
@@ -567,16 +567,16 @@ void ProcessRelationshipsRow(memgraph::storage::Storage *store, const std::vecto
if (!relationship_type) throw LoadException("Relationship TYPE must be set");
auto acc = store->Access();
auto from_node = acc.FindVertex(*start_id, memgraph::storage::View::NEW);
auto from_node = acc->FindVertex(*start_id, memgraph::storage::View::NEW);
if (!from_node) throw LoadException("From node must be in the storage");
auto to_node = acc.FindVertex(*end_id, memgraph::storage::View::NEW);
auto to_node = acc->FindVertex(*end_id, memgraph::storage::View::NEW);
if (!to_node) throw LoadException("To node must be in the storage");
auto relationship = acc.CreateEdge(&*from_node, &*to_node, acc.NameToEdgeType(*relationship_type));
auto relationship = acc->CreateEdge(from_node.get(), to_node.get(), acc->NameToEdgeType(*relationship_type));
if (!relationship.HasValue()) throw LoadException("Couldn't create the relationship");
for (const auto &property : properties) {
auto ret = relationship->SetProperty(acc.NameToProperty(property.first), property.second);
auto ret = relationship.GetValue()->SetProperty(acc->NameToProperty(property.first), property.second);
if (!ret.HasValue()) {
if (ret.GetError() != memgraph::storage::Error::PROPERTIES_DISABLED) {
throw LoadException("Couldn't add property '{}' to the relationship", property.first);
@@ -589,7 +589,7 @@ void ProcessRelationshipsRow(memgraph::storage::Storage *store, const std::vecto
}
}
if (acc.Commit().HasError()) throw LoadException("Couldn't store the relationship");
if (acc->Commit().HasError()) throw LoadException("Couldn't store the relationship");
}
void ProcessRelationships(memgraph::storage::Storage *store, const std::string &relationships_path,
@@ -699,13 +699,13 @@ int main(int argc, char *argv[]) {
}
std::unordered_map<NodeId, memgraph::storage::Gid> node_id_map;
memgraph::storage::Storage store{{
std::unique_ptr<memgraph::storage::Storage> store{new memgraph::storage::InMemoryStorage{{
.items = {.properties_on_edges = FLAGS_storage_properties_on_edges},
.durability = {.storage_directory = FLAGS_data_directory,
.recover_on_startup = false,
.snapshot_wal_mode = memgraph::storage::Config::Durability::SnapshotWalMode::DISABLED,
.snapshot_on_exit = true},
}};
}}};
memgraph::utils::Timer load_timer;
@@ -715,7 +715,7 @@ int main(int argc, char *argv[]) {
std::optional<std::vector<Field>> header;
for (const auto &nodes_file : files) {
spdlog::info("Loading {}", nodes_file);
ProcessNodes(&store, nodes_file, &header, &node_id_map, additional_labels);
ProcessNodes(store.get(), nodes_file, &header, &node_id_map, additional_labels);
}
}
@@ -725,7 +725,7 @@ int main(int argc, char *argv[]) {
std::optional<std::vector<Field>> header;
for (const auto &relationships_file : files) {
spdlog::info("Loading {}", relationships_file);
ProcessRelationships(&store, relationships_file, type, &header, node_id_map);
ProcessRelationships(store.get(), relationships_file, type, &header, node_id_map);
}
}

View File

@@ -112,37 +112,25 @@ query::Graph *SubgraphDbAccessor::getGraph() { return graph_; }
VertexAccessor SubgraphVertexAccessor::GetVertexAccessor() const { return impl_; }
auto SubgraphVertexAccessor::OutEdges(storage::View view) const -> decltype(impl_.OutEdges(view)) {
auto maybe_edges = impl_.impl_->OutEdges(view, {});
if (maybe_edges.HasError()) return maybe_edges.GetError();
auto edges = std::move(*maybe_edges);
const auto &graph_edges = graph_->edges();
auto edges = impl_.OutEdges(view, {});
std::vector<std::unique_ptr<storage::EdgeAccessor>> filteredOutEdges;
for (auto &edge : edges) {
auto edge_q = EdgeAccessor(std::move(edge));
if (graph_edges.contains(edge_q)) {
filteredOutEdges.push_back(std::move(edge));
for (auto edge : *edges) {
if (graph_->ContainsEdge(edge)) {
filteredOutEdges.push_back(std::move(edge.impl_));
}
}
return iter::imap(VertexAccessor::MakeEdgeAccessor, std::move(filteredOutEdges));
}
auto SubgraphVertexAccessor::InEdges(storage::View view) const -> decltype(impl_.InEdges(view)) {
auto maybe_edges = impl_.impl_->InEdges(view, {});
if (maybe_edges.HasError()) return maybe_edges.GetError();
auto edges = std::move(*maybe_edges);
const auto &graph_edges = graph_->edges();
std::vector<std::unique_ptr<storage::EdgeAccessor>> filteredOutEdges;
for (auto &edge : edges) {
auto edge_q = EdgeAccessor(std::move(edge));
if (graph_edges.contains(edge_q)) {
filteredOutEdges.push_back(std::move(edge));
auto edges = impl_.InEdges(view, {});
std::vector<std::unique_ptr<storage::EdgeAccessor>> filteredEdges;
for (auto edge : *edges) {
if (graph_->ContainsEdge(edge)) {
filteredEdges.push_back(std::move(edge.impl_));
}
}
return iter::imap(VertexAccessor::MakeEdgeAccessor, std::move(filteredOutEdges));
return iter::imap(VertexAccessor::MakeEdgeAccessor, std::move(filteredEdges));
}
} // namespace memgraph::query

View File

@@ -14,6 +14,7 @@
#include <optional>
#include <type_traits>
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <cppitertools/filter.hpp>
#include <cppitertools/imap.hpp>
@@ -21,6 +22,7 @@
#include "storage/v2/id_types.hpp"
#include "storage/v2/property_value.hpp"
#include "storage/v2/result.hpp"
#include "storage/v2/vertex_accessor.hpp"
#include "utils/pmr/unordered_set.hpp"
#include "utils/variant_helpers.hpp"
@@ -114,26 +116,34 @@ class VertexAccessor final {
// We make this class a friend so that we can access the private MakeEdgeAccessor function.
friend class SubgraphVertexAccessor;
// IMPLICIT MOVE! This is a workaround for iter::imap
static EdgeAccessor MakeEdgeAccessor(std::unique_ptr<storage::EdgeAccessor> &impl) {
return EdgeAccessor(std::move(impl));
return EdgeAccessor(impl->Copy());
}
public:
// It can affect performance if we use std::unique_ptr here.
std::unique_ptr<storage::VertexAccessor> impl_;
// std::unique_ptr<storage::VertexAccessor> impl_;
// local_shared_ptr and all its local copies must reside in the same thread
boost::local_shared_ptr<storage::VertexAccessor> impl_;
// explicit VertexAccessor(std::unique_ptr<storage::VertexAccessor> impl) : impl_(std::move(impl)) {}
// increase reference count
explicit VertexAccessor(boost::local_shared_ptr<storage::VertexAccessor> impl) : impl_(impl) {}
// VertexAccessor(const VertexAccessor &impl) : impl_(impl.impl_->Copy()){};
VertexAccessor(const VertexAccessor &impl) : impl_(impl.impl_){};
explicit VertexAccessor(std::unique_ptr<storage::VertexAccessor> impl) : impl_(std::move(impl)) {}
VertexAccessor(const VertexAccessor &impl) : impl_(impl.impl_->Copy()){};
explicit VertexAccessor(VertexAccessor *impl) : VertexAccessor(*impl) {}
~VertexAccessor() = default;
VertexAccessor &operator=(const VertexAccessor &other) {
impl_ = other.impl_->Copy();
// impl_ = other.impl_->Copy();
// return *this;
impl_ = other.impl_;
return *this;
}
~VertexAccessor() = default;
bool IsVisible(storage::View view) const { return impl_->IsVisible(view); }
auto Labels(storage::View view) const { return impl_->Labels(view); }
@@ -262,16 +272,12 @@ namespace std {
template <>
struct hash<memgraph::query::VertexAccessor> {
size_t operator()(const memgraph::query::VertexAccessor &v) const {
return std::hash<std::remove_pointer<decltype(v.impl_.get())>::type>{}(*v.impl_);
}
size_t operator()(const memgraph::query::VertexAccessor &v) const { return std::hash<decltype(v.impl_)>{}(v.impl_); }
};
template <>
struct hash<memgraph::query::EdgeAccessor> {
size_t operator()(const memgraph::query::EdgeAccessor &e) const {
return std::hash<std::remove_pointer<decltype(e.impl_.get())>::type>{}(*e.impl_);
}
size_t operator()(const memgraph::query::EdgeAccessor &e) const { return std::hash<decltype(e.impl_)>{}(e.impl_); }
};
} // namespace std
@@ -306,7 +312,7 @@ class VerticesIterable final {
}
Iterator &operator++() {
std::visit([this](auto it_) { this->it_ = ++it_; }, it_);
std::visit([](auto &it_) { ++it_; }, it_);
return *this;
}

View File

@@ -1951,9 +1951,9 @@ void NextPermittedEdge(mgp_edges_iterator &it, const bool for_in) {
const auto *auth_checker = it.source_vertex.graph->ctx->auth_checker.get();
const auto view = it.source_vertex.graph->view;
while (*impl_it != end) {
if (auth_checker->Has(**impl_it, memgraph::query::AuthQuery::FineGrainedPrivilege::READ)) {
const auto &check_vertex =
it.source_vertex.getImpl() == (*impl_it)->From() ? (*impl_it)->To() : (*impl_it)->From();
auto edgeAcc = **impl_it;
if (auth_checker->Has(edgeAcc, memgraph::query::AuthQuery::FineGrainedPrivilege::READ)) {
const auto &check_vertex = it.source_vertex.getImpl() == edgeAcc.From() ? edgeAcc.To() : edgeAcc.From();
if (auth_checker->Has(check_vertex, view, memgraph::query::AuthQuery::FineGrainedPrivilege::READ)) {
break;
}
@@ -2052,12 +2052,10 @@ mgp_error mgp_vertex_iter_out_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges
std::visit(
memgraph::utils::Overloaded{
[&](memgraph::query::DbAccessor *) {
// Dereference iterator implicitly call MakeEdgeAccessor which moves EdgeAccessor.
memgraph::query::EdgeAccessor edgeAcc = **it->out_it;
it->current_e.emplace(edgeAcc, edgeAcc.From(), edgeAcc.To(), v->graph, it->GetMemoryResource());
},
[&](memgraph::query::SubgraphDbAccessor *impl) {
// Dereference iterator implicitly call MakeEdgeAccessor which moves EdgeAccessor.
auto edgeAcc = **it->out_it;
it->current_e.emplace(edgeAcc,
memgraph::query::SubgraphVertexAccessor(edgeAcc.From(), impl->getGraph()),
@@ -2115,13 +2113,11 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
}
std::visit(memgraph::utils::Overloaded{
[&](memgraph::query::DbAccessor *) {
// Dereference iterator implicitly call MakeEdgeAccessor which moves EdgeAccessor.
auto edgeAcc = **impl_it;
it->current_e.emplace(edgeAcc, edgeAcc.From(), edgeAcc.To(), it->source_vertex.graph,
it->GetMemoryResource());
},
[&](memgraph::query::SubgraphDbAccessor *impl) {
// Dereference iterator implicitly call MakeEdgeAccessor which moves EdgeAccessor.
auto edgeAcc = **impl_it;
it->current_e.emplace(
edgeAcc, memgraph::query::SubgraphVertexAccessor(edgeAcc.From(), impl->getGraph()),

View File

@@ -22,4 +22,14 @@ std::unique_ptr<EdgeAccessor> EdgeAccessor::Create(EdgeRef edge, EdgeTypeId edge
return std::make_unique<InMemoryEdgeAccessor>(edge, edge_type, from_vertex, to_vertex, transaction, indices,
constraints, config, for_deleted);
}
bool operator==(const std::unique_ptr<EdgeAccessor> &ea1, const std::unique_ptr<EdgeAccessor> &ea2) noexcept {
const auto *inMemoryEa1 = dynamic_cast<const InMemoryEdgeAccessor *>(ea1.get());
const auto *inMemoryEa2 = dynamic_cast<const InMemoryEdgeAccessor *>(ea2.get());
if (inMemoryEa1 && inMemoryEa2) {
return inMemoryEa1->operator==(*inMemoryEa2);
}
return false;
}
} // namespace memgraph::storage

View File

@@ -91,11 +91,13 @@ class EdgeAccessor {
bool for_deleted_{false};
};
bool operator==(const std::unique_ptr<EdgeAccessor> &ea1, const std::unique_ptr<EdgeAccessor> &ea2) noexcept;
} // namespace memgraph::storage
namespace std {
template <>
struct hash<memgraph::storage::EdgeAccessor> {
size_t operator()(const memgraph::storage::EdgeAccessor &e) const { return e.Gid().AsUint(); }
struct hash<memgraph::storage::EdgeAccessor *> {
size_t operator()(const memgraph::storage::EdgeAccessor *e) const { return e->Gid().AsUint(); }
};
} // namespace std

View File

@@ -344,8 +344,13 @@ void LabelIndex::Iterable::Iterator::AdvanceUntilValid() {
}
if (CurrentVersionHasLabel(*index_iterator_->vertex, self_->label_, self_->transaction_, self_->view_)) {
current_vertex_ = index_iterator_->vertex;
current_vertex_accessor_ = VertexAccessor::Create(current_vertex_, self_->transaction_, self_->indices_,
self_->constraints_, self_->config_, self_->view_);
if (current_vertex_accessor_) {
current_vertex_accessor_->ReInit(current_vertex_, self_->transaction_, self_->indices_, self_->constraints_,
self_->config_, self_->view_);
} else {
current_vertex_accessor_ = VertexAccessor::Create(current_vertex_, self_->transaction_, self_->indices_,
self_->constraints_, self_->config_, self_->view_);
}
break;
}
}
@@ -513,8 +518,13 @@ void LabelPropertyIndex::Iterable::Iterator::AdvanceUntilValid() {
if (CurrentVersionHasLabelProperty(*index_iterator_->vertex, self_->label_, self_->property_,
index_iterator_->value, self_->transaction_, self_->view_)) {
current_vertex_ = index_iterator_->vertex;
current_vertex_accessor_ = VertexAccessor::Create(current_vertex_, self_->transaction_, self_->indices_,
self_->constraints_, self_->config_, self_->view_);
if (current_vertex_accessor_) {
current_vertex_accessor_->ReInit(current_vertex_, self_->transaction_, self_->indices_, self_->constraints_,
self_->config_, self_->view_);
} else {
current_vertex_accessor_ = VertexAccessor::Create(current_vertex_, self_->transaction_, self_->indices_,
self_->constraints_, self_->config_, self_->view_);
}
break;
}
}

View File

@@ -71,6 +71,20 @@ std::unique_ptr<InMemoryVertexAccessor> InMemoryVertexAccessor::Create(Vertex *v
return std::make_unique<InMemoryVertexAccessor>(vertex, transaction, indices, constraints, config);
}
bool InMemoryVertexAccessor::ReInit(Vertex *vertex, Transaction *transaction, Indices *indices,
Constraints *constraints, Config::Items config, View view) {
if (const auto [exists, deleted] = detail::IsVisible(vertex, transaction, view); !exists || deleted) {
return false;
}
transaction_ = transaction;
config_ = config;
vertex_ = vertex;
indices_ = indices;
constraints_ = constraints;
return true;
}
bool InMemoryVertexAccessor::IsVisible(View view) const {
const auto [exists, deleted] = detail::IsVisible(vertex_, transaction_, view);
return exists && (for_deleted_ || !deleted);

View File

@@ -43,6 +43,9 @@ class InMemoryVertexAccessor final : public VertexAccessor {
static std::unique_ptr<InMemoryVertexAccessor> Create(Vertex *vertex, Transaction *transaction, Indices *indices,
Constraints *constraints, Config::Items config, View view);
bool ReInit(Vertex *vertex, Transaction *transaction, Indices *indices, Constraints *constraints,
Config::Items config, View view) override;
/// @return true if the object is visible from the current transaction
bool IsVisible(View view) const override;

View File

@@ -19,8 +19,14 @@ auto AdvanceToVisibleVertex(utils::SkipList<Vertex>::Iterator it, utils::SkipLis
std::unique_ptr<VertexAccessor> &vertex, Transaction *tx, View view, Indices *indices,
Constraints *constraints, Config::Items config) {
while (it != end) {
vertex = VertexAccessor::Create(&*it, tx, indices, constraints, config, view);
if (!vertex) {
bool isVisible = true;
if (vertex) {
isVisible = vertex->ReInit(&*it, tx, indices, constraints, config, view);
} else {
vertex = VertexAccessor::Create(&*it, tx, indices, constraints, config, view);
isVisible = (vertex != nullptr);
}
if (!isVisible) {
++it;
continue;
}

View File

@@ -39,4 +39,13 @@ Result<std::vector<std::unique_ptr<EdgeAccessor>>> VertexAccessor::OutEdges(View
return OutEdges(view, {}, nullptr);
}
bool operator==(const std::unique_ptr<VertexAccessor> &va1, const std::unique_ptr<VertexAccessor> &va2) noexcept {
const auto *inMemoryVa1 = dynamic_cast<const InMemoryVertexAccessor *>(va1.get());
const auto *inMemoryVa2 = dynamic_cast<const InMemoryVertexAccessor *>(va2.get());
if (inMemoryVa1 && inMemoryVa2) {
return inMemoryVa1->operator==(*inMemoryVa2);
}
return false;
}
} // namespace memgraph::storage

View File

@@ -41,6 +41,10 @@ class VertexAccessor {
static std::unique_ptr<VertexAccessor> Create(Vertex *vertex, Transaction *transaction, Indices *indices,
Constraints *constraints, Config::Items config, View view);
/// Reinitialize the accessor with a new vertex to avoid additional allocations.
virtual bool ReInit(Vertex *vertex, Transaction *transaction, Indices *indices, Constraints *constraints,
Config::Items config, View view) = 0;
/// @return true if the object is visible from the current transaction
virtual bool IsVisible(View view) const = 0;
@@ -128,11 +132,13 @@ class VertexAccessor {
bool for_deleted_{false};
};
bool operator==(const std::unique_ptr<VertexAccessor> &va1, const std::unique_ptr<VertexAccessor> &va2) noexcept;
} // namespace memgraph::storage
namespace std {
template <>
struct hash<memgraph::storage::VertexAccessor> {
size_t operator()(const memgraph::storage::VertexAccessor &v) const noexcept { return v.Gid().AsUint(); }
struct hash<memgraph::storage::VertexAccessor *> {
size_t operator()(const memgraph::storage::VertexAccessor *v) const noexcept { return v->Gid().AsUint(); }
};
} // namespace std

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -15,34 +15,34 @@
#include "query/config.hpp"
#include "query/interpreter.hpp"
#include "query/typed_value.hpp"
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/isolation_level.hpp"
#include "storage/v2/storage.hpp"
class ExpansionBenchFixture : public benchmark::Fixture {
protected:
std::optional<memgraph::storage::Storage> db;
std::unique_ptr<memgraph::storage::Storage> db;
std::optional<memgraph::query::InterpreterContext> interpreter_context;
std::optional<memgraph::query::Interpreter> interpreter;
std::filesystem::path data_directory{std::filesystem::temp_directory_path() / "expansion-benchmark"};
void SetUp(const benchmark::State &state) override {
db.emplace();
db.reset(new memgraph::storage::InMemoryStorage());
auto label = db->NameToLabel("Starting");
{
auto dba = db->Access();
for (int i = 0; i < state.range(0); i++) dba.CreateVertex();
for (int i = 0; i < state.range(0); i++) dba->CreateVertex();
// the fixed part is one vertex expanding to 1000 others
auto start = dba.CreateVertex();
MG_ASSERT(start.AddLabel(label).HasValue());
auto edge_type = dba.NameToEdgeType("edge_type");
auto start = dba->CreateVertex();
MG_ASSERT(start->AddLabel(label).HasValue());
auto edge_type = dba->NameToEdgeType("edge_type");
for (int i = 0; i < 1000; i++) {
auto dest = dba.CreateVertex();
MG_ASSERT(dba.CreateEdge(&start, &dest, edge_type).HasValue());
auto dest = dba->CreateVertex();
MG_ASSERT(dba->CreateEdge(start.get(), dest.get(), edge_type).HasValue());
}
MG_ASSERT(!dba.Commit().HasError());
MG_ASSERT(!dba->Commit().HasError());
}
MG_ASSERT(!db->CreateIndex(label).HasError());
@@ -54,7 +54,7 @@ class ExpansionBenchFixture : public benchmark::Fixture {
void TearDown(const benchmark::State &) override {
interpreter = std::nullopt;
interpreter_context = std::nullopt;
db = std::nullopt;
db.reset(nullptr);
std::filesystem::remove_all(data_directory);
}
};

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -14,6 +14,7 @@
#include "query/db_accessor.hpp"
#include "query/interpret/eval.hpp"
#include "query/interpreter.hpp"
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/storage.hpp"
// The following classes are wrappers for memgraph::utils::MemoryResource, so that we can
@@ -38,9 +39,9 @@ static void MapLiteral(benchmark::State &state) {
memgraph::query::SymbolTable symbol_table;
TMemory memory;
memgraph::query::Frame frame(symbol_table.max_position(), memory.get());
memgraph::storage::Storage db;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
std::unordered_map<memgraph::query::PropertyIx, memgraph::query::Expression *> elements;
for (int64_t i = 0; i < state.range(0); ++i) {
elements.emplace(ast.GetPropertyIx("prop" + std::to_string(i)), ast.Create<memgraph::query::PrimitiveLiteral>(i));
@@ -67,9 +68,9 @@ static void AdditionOperator(benchmark::State &state) {
memgraph::query::SymbolTable symbol_table;
TMemory memory;
memgraph::query::Frame frame(symbol_table.max_position(), memory.get());
memgraph::storage::Storage db;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
memgraph::query::Expression *expr = ast.Create<memgraph::query::PrimitiveLiteral>(0);
for (int64_t i = 0; i < state.range(0); ++i) {
expr = ast.Create<memgraph::query::AdditionOperator>(expr, ast.Create<memgraph::query::PrimitiveLiteral>(i));

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -30,7 +30,7 @@
#include "query/frontend/semantic/required_privileges.hpp"
#include "query/frontend/semantic/symbol_generator.hpp"
#include "query/interpreter.hpp"
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
// The following classes are wrappers for memgraph::utils::MemoryResource, so that we can
// use BENCHMARK_TEMPLATE
@@ -62,8 +62,8 @@ class PoolResource final {
static void AddVertices(memgraph::storage::Storage *db, int vertex_count) {
auto dba = db->Access();
for (int i = 0; i < vertex_count; i++) dba.CreateVertex();
MG_ASSERT(!dba.Commit().HasError());
for (int i = 0; i < vertex_count; i++) dba->CreateVertex();
MG_ASSERT(!dba->Commit().HasError());
}
static const char *kStartLabel = "start";
@@ -71,17 +71,17 @@ static const char *kStartLabel = "start";
static void AddStarGraph(memgraph::storage::Storage *db, int spoke_count, int depth) {
{
auto dba = db->Access();
auto center_vertex = dba.CreateVertex();
MG_ASSERT(center_vertex.AddLabel(dba.NameToLabel(kStartLabel)).HasValue());
auto center_vertex = dba->CreateVertex();
MG_ASSERT(center_vertex->AddLabel(dba->NameToLabel(kStartLabel)).HasValue());
for (int i = 0; i < spoke_count; ++i) {
auto prev_vertex = center_vertex;
auto prev_vertex = std::move(center_vertex);
for (int j = 0; j < depth; ++j) {
auto dest = dba.CreateVertex();
MG_ASSERT(dba.CreateEdge(&prev_vertex, &dest, dba.NameToEdgeType("Type")).HasValue());
prev_vertex = dest;
auto dest = dba->CreateVertex();
MG_ASSERT(dba->CreateEdge(prev_vertex.get(), dest.get(), dba->NameToEdgeType("Type")).HasValue());
prev_vertex = std::move(dest);
}
}
MG_ASSERT(!dba.Commit().HasError());
MG_ASSERT(!dba->Commit().HasError());
}
MG_ASSERT(!db->CreateIndex(db->NameToLabel(kStartLabel)).HasError());
}
@@ -89,21 +89,21 @@ static void AddStarGraph(memgraph::storage::Storage *db, int spoke_count, int de
static void AddTree(memgraph::storage::Storage *db, int vertex_count) {
{
auto dba = db->Access();
std::vector<memgraph::storage::VertexAccessor> vertices;
std::vector<std::unique_ptr<memgraph::storage::VertexAccessor>> vertices;
vertices.reserve(vertex_count);
auto root = dba.CreateVertex();
MG_ASSERT(root.AddLabel(dba.NameToLabel(kStartLabel)).HasValue());
vertices.push_back(root);
auto root = dba->CreateVertex();
MG_ASSERT(root->AddLabel(dba->NameToLabel(kStartLabel)).HasValue());
vertices.push_back(std::move(root));
// NOLINTNEXTLINE(cert-msc32-c,cert-msc51-cpp)
std::mt19937_64 rg(42);
for (int i = 1; i < vertex_count; ++i) {
auto v = dba.CreateVertex();
auto v = dba->CreateVertex();
std::uniform_int_distribution<> dis(0U, vertices.size() - 1U);
auto &parent = vertices.at(dis(rg));
MG_ASSERT(dba.CreateEdge(&parent, &v, dba.NameToEdgeType("Type")).HasValue());
vertices.push_back(v);
MG_ASSERT(dba->CreateEdge(parent.get(), v.get(), dba->NameToEdgeType("Type")).HasValue());
vertices.push_back(std::move(v));
}
MG_ASSERT(!dba.Commit().HasError());
MG_ASSERT(!dba->Commit().HasError());
}
MG_ASSERT(!db->CreateIndex(db->NameToLabel(kStartLabel)).HasError());
}
@@ -124,16 +124,16 @@ template <class TMemory>
static void Distinct(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddVertices(&db, state.range(0));
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddVertices(db.get(), state.range(0));
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
auto query_string = "MATCH (s) RETURN DISTINCT s";
auto *cypher_query = ParseCypherQuery(query_string, &ast);
auto symbol_table = memgraph::query::MakeSymbolTable(cypher_query);
auto context = memgraph::query::plan::MakePlanningContext(&ast, &symbol_table, cypher_query, &dba);
auto plan_and_cost = memgraph::query::plan::MakeLogicalPlan(&context, parameters, false);
ResultStreamFaker results(&db);
ResultStreamFaker results(db.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -174,12 +174,12 @@ template <class TMemory>
static void ExpandVariable(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddStarGraph(&db, state.range(0), state.range(1));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddStarGraph(db.get(), state.range(0), state.range(1));
memgraph::query::SymbolTable symbol_table;
auto expand_variable = MakeExpandVariable(memgraph::query::EdgeAtom::Type::DEPTH_FIRST, &symbol_table);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -213,12 +213,12 @@ template <class TMemory>
static void ExpandBfs(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddTree(&db, state.range(0));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddTree(db.get(), state.range(0));
memgraph::query::SymbolTable symbol_table;
auto expand_variable = MakeExpandVariable(memgraph::query::EdgeAtom::Type::BREADTH_FIRST, &symbol_table);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -246,14 +246,14 @@ template <class TMemory>
static void ExpandShortest(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddTree(&db, state.range(0));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddTree(db.get(), state.range(0));
memgraph::query::SymbolTable symbol_table;
auto expand_variable = MakeExpandVariable(memgraph::query::EdgeAtom::Type::BREADTH_FIRST, &symbol_table);
expand_variable.common_.existing_node = true;
auto dest_symbol = expand_variable.common_.node_symbol;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -284,8 +284,8 @@ template <class TMemory>
static void ExpandWeightedShortest(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddTree(&db, state.range(0));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddTree(db.get(), state.range(0));
memgraph::query::SymbolTable symbol_table;
auto expand_variable = MakeExpandVariable(memgraph::query::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH, &symbol_table);
expand_variable.common_.existing_node = true;
@@ -293,8 +293,8 @@ static void ExpandWeightedShortest(benchmark::State &state) {
symbol_table.CreateSymbol("edge", false), symbol_table.CreateSymbol("vertex", false),
ast.Create<memgraph::query::PrimitiveLiteral>(1)};
auto dest_symbol = expand_variable.common_.node_symbol;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -327,8 +327,8 @@ template <class TMemory>
static void Accumulate(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddVertices(&db, state.range(1));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddVertices(db.get(), state.range(1));
memgraph::query::SymbolTable symbol_table;
auto scan_all = std::make_shared<memgraph::query::plan::ScanAll>(nullptr, symbol_table.CreateSymbol("v", false));
std::vector<memgraph::query::Symbol> symbols;
@@ -338,8 +338,8 @@ static void Accumulate(benchmark::State &state) {
}
memgraph::query::plan::Accumulate accumulate(scan_all, symbols,
/* advance_command= */ false);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -368,8 +368,8 @@ template <class TMemory>
static void Aggregate(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddVertices(&db, state.range(1));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddVertices(db.get(), state.range(1));
memgraph::query::SymbolTable symbol_table;
auto scan_all = std::make_shared<memgraph::query::plan::ScanAll>(nullptr, symbol_table.CreateSymbol("v", false));
std::vector<memgraph::query::Symbol> symbols;
@@ -387,8 +387,8 @@ static void Aggregate(benchmark::State &state) {
symbol_table.CreateSymbol("out" + std::to_string(i), false)});
}
memgraph::query::plan::Aggregate aggregate(scan_all, aggregations, group_by, symbols);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -421,8 +421,8 @@ template <class TMemory>
static void OrderBy(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddVertices(&db, state.range(1));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddVertices(db.get(), state.range(1));
memgraph::query::SymbolTable symbol_table;
auto scan_all = std::make_shared<memgraph::query::plan::ScanAll>(nullptr, symbol_table.CreateSymbol("v", false));
std::vector<memgraph::query::Symbol> symbols;
@@ -437,8 +437,8 @@ static void OrderBy(benchmark::State &state) {
sort_items.push_back({memgraph::query::Ordering::ASC, ast.Create<memgraph::query::PrimitiveLiteral>(rand_value)});
}
memgraph::query::plan::OrderBy order_by(scan_all, sort_items, symbols);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -467,16 +467,16 @@ template <class TMemory>
static void Unwind(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::query::Parameters parameters;
memgraph::storage::Storage db;
AddVertices(&db, state.range(0));
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
AddVertices(db.get(), state.range(0));
memgraph::query::SymbolTable symbol_table;
auto scan_all = std::make_shared<memgraph::query::plan::ScanAll>(nullptr, symbol_table.CreateSymbol("v", false));
auto list_sym = symbol_table.CreateSymbol("list", false);
auto *list_expr = ast.Create<memgraph::query::Identifier>("list")->MapTo(list_sym);
auto out_sym = symbol_table.CreateSymbol("out", false);
memgraph::query::plan::Unwind unwind(scan_all, list_expr, out_sym);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
// We need to only set the memory for temporary (per pull) evaluations
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
@@ -503,7 +503,7 @@ template <class TMemory>
// NOLINTNEXTLINE(google-runtime-references)
static void Foreach(benchmark::State &state) {
memgraph::query::AstStorage ast;
memgraph::storage::Storage db;
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
memgraph::query::SymbolTable symbol_table;
auto list_sym = symbol_table.CreateSymbol("list", false);
auto *list_expr = ast.Create<memgraph::query::Identifier>("list")->MapTo(list_sym);
@@ -512,8 +512,8 @@ static void Foreach(benchmark::State &state) {
std::make_shared<memgraph::query::plan::CreateNode>(nullptr, memgraph::query::plan::NodeCreationInfo{});
auto foreach = std::make_shared<memgraph::query::plan::Foreach>(nullptr, std::move(create_node), list_expr, out_sym);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
TMemory per_pull_memory;
memgraph::query::EvaluationContext evaluation_context{per_pull_memory.get()};
while (state.KeepRunning()) {

View File

@@ -17,7 +17,7 @@
#include "query/plan/cost_estimator.hpp"
#include "query/plan/planner.hpp"
#include "query/plan/vertex_count_cache.hpp"
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
// Add chained MATCH (node1) -- (node2), MATCH (node2) -- (node3) ... clauses.
static memgraph::query::CypherQuery *AddChainedMatches(int num_matches, memgraph::query::AstStorage &storage) {
@@ -43,9 +43,9 @@ static memgraph::query::CypherQuery *AddChainedMatches(int num_matches, memgraph
}
static void BM_PlanChainedMatches(benchmark::State &state) {
memgraph::storage::Storage db;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
while (state.KeepRunning()) {
state.PauseTiming();
memgraph::query::AstStorage storage;
@@ -98,24 +98,24 @@ static auto CreateIndexedVertices(int index_count, int vertex_count, memgraph::s
auto dba = db->Access();
for (int vi = 0; vi < vertex_count; ++vi) {
for (int index = 0; index < index_count; ++index) {
auto vertex = dba.CreateVertex();
MG_ASSERT(vertex.AddLabel(label).HasValue());
MG_ASSERT(vertex.SetProperty(prop, memgraph::storage::PropertyValue(index)).HasValue());
auto vertex = dba->CreateVertex();
MG_ASSERT(vertex->AddLabel(label).HasValue());
MG_ASSERT(vertex->SetProperty(prop, memgraph::storage::PropertyValue(index)).HasValue());
}
}
MG_ASSERT(!dba.Commit().HasError());
MG_ASSERT(!dba->Commit().HasError());
return std::make_pair("label", "prop");
}
static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
memgraph::storage::Storage db;
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
std::string label;
std::string prop;
int index_count = state.range(0);
int vertex_count = state.range(1);
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, &db);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db.get());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
memgraph::query::Parameters parameters;
while (state.KeepRunning()) {
state.PauseTiming();
@@ -137,14 +137,14 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
}
static void BM_PlanAndEstimateIndexedMatchingWithCachedCounts(benchmark::State &state) {
memgraph::storage::Storage db;
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
std::string label;
std::string prop;
int index_count = state.range(0);
int vertex_count = state.range(1);
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, &db);
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db.get());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
auto vertex_counts = memgraph::query::plan::MakeVertexCountCache(&dba);
memgraph::query::Parameters parameters;
while (state.KeepRunning()) {

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -13,6 +13,7 @@
#include <gflags/gflags.h>
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/storage.hpp"
#include "utils/timer.hpp"
@@ -43,12 +44,12 @@ void UpdateLabelFunc(int thread_id, memgraph::storage::Storage *storage,
for (int iter = 0; iter < num_iterations; ++iter) {
auto acc = storage->Access();
memgraph::storage::Gid gid = vertices.at(vertex_dist(gen));
std::optional<memgraph::storage::VertexAccessor> vertex = acc.FindVertex(gid, memgraph::storage::View::OLD);
MG_ASSERT(vertex.has_value(), "Vertex with GID {} doesn't exist", gid.AsUint());
std::unique_ptr<memgraph::storage::VertexAccessor> vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
MG_ASSERT(vertex != nullptr, "Vertex with GID {} doesn't exist", gid.AsUint());
if (vertex->AddLabel(memgraph::storage::LabelId::FromUint(label_dist(gen))).HasValue()) {
MG_ASSERT(!acc.Commit().HasError());
MG_ASSERT(!acc->Commit().HasError());
} else {
acc.Abort();
acc->Abort();
}
}
}
@@ -57,21 +58,21 @@ int main(int argc, char *argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
for (const auto &config : TestConfigurations) {
memgraph::storage::Storage storage(config.second);
std::unique_ptr<memgraph::storage::Storage> storage(new memgraph::storage::InMemoryStorage(config.second));
std::vector<memgraph::storage::Gid> vertices;
{
auto acc = storage.Access();
auto acc = storage->Access();
for (int i = 0; i < FLAGS_num_vertices; ++i) {
vertices.push_back(acc.CreateVertex().Gid());
vertices.push_back(acc->CreateVertex()->Gid());
}
MG_ASSERT(!acc.Commit().HasError());
MG_ASSERT(!acc->Commit().HasError());
}
memgraph::utils::Timer timer;
std::vector<std::thread> threads;
threads.reserve(FLAGS_num_threads);
for (int i = 0; i < FLAGS_num_threads; ++i) {
threads.emplace_back(UpdateLabelFunc, i, &storage, vertices, FLAGS_num_iterations);
threads.emplace_back(UpdateLabelFunc, i, storage.get(), vertices, FLAGS_num_iterations);
}
for (int i = 0; i < FLAGS_num_threads; ++i) {

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -15,7 +15,7 @@
#include <fmt/format.h>
#include <gtest/gtest.h>
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/storage_error.hpp"
#include "utils/thread.hpp"
@@ -27,10 +27,10 @@ const uint64_t kVerifierBatchSize = 10;
const uint64_t kMutatorBatchSize = 1000;
TEST(Storage, LabelIndex) {
auto store = memgraph::storage::Storage();
std::unique_ptr<memgraph::storage::Storage> store{new memgraph::storage::InMemoryStorage()};
auto label = store.NameToLabel("label");
ASSERT_FALSE(store.CreateIndex(label).HasError());
auto label = store->NameToLabel("label");
ASSERT_FALSE(store->CreateIndex(label).HasError());
std::vector<std::thread> verifiers;
verifiers.reserve(kNumVerifiers);
@@ -41,19 +41,19 @@ TEST(Storage, LabelIndex) {
gids.reserve(kNumIterations * kVerifierBatchSize);
for (uint64_t i = 0; i < kNumIterations; ++i) {
for (uint64_t j = 0; j < kVerifierBatchSize; ++j) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gids.emplace(vertex.Gid(), false);
auto ret = vertex.AddLabel(label);
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gids.emplace(vertex->Gid(), false);
auto ret = vertex->AddLabel(label);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store.Access();
auto vertices = acc.Vertices(label, memgraph::storage::View::OLD);
auto acc = store->Access();
auto vertices = acc->Vertices(label, memgraph::storage::View::OLD);
for (auto vertex : vertices) {
auto it = gids.find(vertex.Gid());
auto it = gids.find(vertex->Gid());
if (it != gids.end()) {
ASSERT_FALSE(it->second);
it->second = true;
@@ -78,20 +78,20 @@ TEST(Storage, LabelIndex) {
gids.resize(kMutatorBatchSize);
while (mutators_run.load(std::memory_order_acquire)) {
for (uint64_t i = 0; i < kMutatorBatchSize; ++i) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gids[i] = vertex.Gid();
auto ret = vertex.AddLabel(label);
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gids[i] = vertex->Gid();
auto ret = vertex->AddLabel(label);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_FALSE(acc->Commit().HasError());
}
for (uint64_t i = 0; i < kMutatorBatchSize; ++i) {
auto acc = store.Access();
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto acc = store->Access();
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_TRUE(acc.DeleteVertex(&*vertex).HasValue());
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_TRUE(acc->DeleteVertex(&*vertex).HasValue());
ASSERT_FALSE(acc->Commit().HasError());
}
}
});
@@ -108,11 +108,11 @@ TEST(Storage, LabelIndex) {
}
TEST(Storage, LabelPropertyIndex) {
auto store = memgraph::storage::Storage();
std::unique_ptr<memgraph::storage::Storage> store{new memgraph::storage::InMemoryStorage()};
auto label = store.NameToLabel("label");
auto prop = store.NameToProperty("prop");
ASSERT_FALSE(store.CreateIndex(label, prop).HasError());
auto label = store->NameToLabel("label");
auto prop = store->NameToProperty("prop");
ASSERT_FALSE(store->CreateIndex(label, prop).HasError());
std::vector<std::thread> verifiers;
verifiers.reserve(kNumVerifiers);
@@ -123,26 +123,26 @@ TEST(Storage, LabelPropertyIndex) {
gids.reserve(kNumIterations * kVerifierBatchSize);
for (uint64_t i = 0; i < kNumIterations; ++i) {
for (uint64_t j = 0; j < kVerifierBatchSize; ++j) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gids.emplace(vertex.Gid(), false);
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gids.emplace(vertex->Gid(), false);
{
auto ret = vertex.AddLabel(label);
auto ret = vertex->AddLabel(label);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
{
auto old_value = vertex.SetProperty(prop, memgraph::storage::PropertyValue(vertex.Gid().AsInt()));
auto old_value = vertex->SetProperty(prop, memgraph::storage::PropertyValue(vertex->Gid().AsInt()));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store.Access();
auto vertices = acc.Vertices(label, prop, memgraph::storage::View::OLD);
auto acc = store->Access();
auto vertices = acc->Vertices(label, prop, memgraph::storage::View::OLD);
for (auto vertex : vertices) {
auto it = gids.find(vertex.Gid());
auto it = gids.find(vertex->Gid());
if (it != gids.end()) {
ASSERT_FALSE(it->second);
it->second = true;
@@ -167,27 +167,27 @@ TEST(Storage, LabelPropertyIndex) {
gids.resize(kMutatorBatchSize);
while (mutators_run.load(std::memory_order_acquire)) {
for (uint64_t i = 0; i < kMutatorBatchSize; ++i) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gids[i] = vertex.Gid();
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gids[i] = vertex->Gid();
{
auto ret = vertex.AddLabel(label);
auto ret = vertex->AddLabel(label);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
{
auto old_value = vertex.SetProperty(prop, memgraph::storage::PropertyValue(vertex.Gid().AsInt()));
auto old_value = vertex->SetProperty(prop, memgraph::storage::PropertyValue(vertex->Gid().AsInt()));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_FALSE(acc->Commit().HasError());
}
for (uint64_t i = 0; i < kMutatorBatchSize; ++i) {
auto acc = store.Access();
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto acc = store->Access();
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_TRUE(acc.DeleteVertex(&*vertex).HasValue());
ASSERT_FALSE(acc.Commit().HasError());
ASSERT_TRUE(acc->DeleteVertex(&*vertex).HasValue());
ASSERT_FALSE(acc->Commit().HasError());
}
}
});

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -14,7 +14,7 @@
#include <gtest/gtest.h>
#include "storage/v2/constraints.hpp"
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
const int kNumThreads = 8;
@@ -27,23 +27,23 @@ using memgraph::storage::PropertyValue;
class StorageUniqueConstraints : public ::testing::Test {
protected:
StorageUniqueConstraints()
: label(storage.NameToLabel("label")),
prop1(storage.NameToProperty("prop1")),
prop2(storage.NameToProperty("prop2")),
prop3(storage.NameToProperty("prop3")) {}
: label(storage->NameToLabel("label")),
prop1(storage->NameToProperty("prop1")),
prop2(storage->NameToProperty("prop2")),
prop3(storage->NameToProperty("prop3")) {}
void SetUp() override {
// Create initial vertices.
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.CreateVertex();
gids[i] = vertex.Gid();
auto vertex = acc->CreateVertex();
gids[i] = vertex->Gid();
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
memgraph::storage::Storage storage;
std::unique_ptr<memgraph::storage::Storage> storage{new memgraph::storage::InMemoryStorage()};
LabelId label;
PropertyId prop1;
PropertyId prop2;
@@ -56,7 +56,7 @@ void SetProperties(memgraph::storage::Storage *storage, memgraph::storage::Gid g
bool *commit_status) {
ASSERT_EQ(properties.size(), values.size());
auto acc = storage->Access();
auto vertex = acc.FindVertex(gid, memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
int value = 0;
for (int iter = 0; iter < 40000; ++iter) {
@@ -67,37 +67,37 @@ void SetProperties(memgraph::storage::Storage *storage, memgraph::storage::Gid g
for (size_t i = 0; i < properties.size(); ++i) {
ASSERT_OK(vertex->SetProperty(properties[i], values[i]));
}
*commit_status = !acc.Commit().HasError();
*commit_status = !acc->Commit().HasError();
}
void AddLabel(memgraph::storage::Storage *storage, memgraph::storage::Gid gid, LabelId label, bool *commit_status) {
auto acc = storage->Access();
auto vertex = acc.FindVertex(gid, memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
for (int iter = 0; iter < 40000; ++iter) {
ASSERT_OK(vertex->AddLabel(label));
ASSERT_OK(vertex->RemoveLabel(label));
}
ASSERT_OK(vertex->AddLabel(label));
*commit_status = !acc.Commit().HasError();
*commit_status = !acc->Commit().HasError();
}
TEST_F(StorageUniqueConstraints, ChangeProperties) {
{
auto res = storage.CreateUniqueConstraint(label, {prop1, prop2, prop3});
auto res = storage->CreateUniqueConstraint(label, {prop1, prop2, prop3});
ASSERT_TRUE(res.HasValue());
ASSERT_EQ(res.GetValue(), memgraph::storage::UniqueConstraints::CreationStatus::SUCCESS);
}
{
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_OK(vertex->AddLabel(label));
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
std::vector<PropertyId> properties{prop1, prop2, prop3};
@@ -111,7 +111,7 @@ TEST_F(StorageUniqueConstraints, ChangeProperties) {
std::vector<std::thread> threads;
threads.reserve(kNumThreads);
for (int i = 0; i < kNumThreads; ++i) {
threads.emplace_back(SetProperties, &storage, gids[i], properties, values, &status[i]);
threads.emplace_back(SetProperties, storage.get(), gids[i], properties, values, &status[i]);
}
int count_ok = 0;
for (int i = 0; i < kNumThreads; ++i) {
@@ -131,7 +131,7 @@ TEST_F(StorageUniqueConstraints, ChangeProperties) {
std::vector<std::thread> threads;
threads.reserve(kNumThreads);
for (int i = 0; i < kNumThreads; ++i) {
threads.emplace_back(SetProperties, &storage, gids[i], properties, values, &status[i]);
threads.emplace_back(SetProperties, storage.get(), gids[i], properties, values, &status[i]);
}
int count_ok = 0;
for (int i = 0; i < kNumThreads; ++i) {
@@ -152,7 +152,7 @@ TEST_F(StorageUniqueConstraints, ChangeProperties) {
threads.reserve(kNumThreads);
for (int i = 0; i < kNumThreads; ++i) {
std::vector<PropertyValue> values{PropertyValue(value++), PropertyValue(value++), PropertyValue(value++)};
threads.emplace_back(SetProperties, &storage, gids[i], properties, values, &status[i]);
threads.emplace_back(SetProperties, storage.get(), gids[i], properties, values, &status[i]);
}
int count_ok = 0;
for (int i = 0; i < kNumThreads; ++i) {
@@ -166,7 +166,7 @@ TEST_F(StorageUniqueConstraints, ChangeProperties) {
TEST_F(StorageUniqueConstraints, ChangeLabels) {
{
auto res = storage.CreateUniqueConstraint(label, {prop1, prop2, prop3});
auto res = storage->CreateUniqueConstraint(label, {prop1, prop2, prop3});
ASSERT_TRUE(res.HasValue());
ASSERT_EQ(res.GetValue(), memgraph::storage::UniqueConstraints::CreationStatus::SUCCESS);
}
@@ -177,29 +177,29 @@ TEST_F(StorageUniqueConstraints, ChangeLabels) {
// succeed, as the others should result with constraint violation.
{
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_OK(vertex->SetProperty(prop1, PropertyValue(1)));
ASSERT_OK(vertex->SetProperty(prop2, PropertyValue(2)));
ASSERT_OK(vertex->SetProperty(prop3, PropertyValue(3)));
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
for (int iter = 0; iter < 20; ++iter) {
// Clear labels.
{
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_OK(vertex->RemoveLabel(label));
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
bool status[kNumThreads];
@@ -207,7 +207,7 @@ TEST_F(StorageUniqueConstraints, ChangeLabels) {
threads.reserve(kNumThreads);
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
threads.emplace_back(AddLabel, &storage, gids[i], label, &status[i]);
threads.emplace_back(AddLabel, storage.get(), gids[i], label, &status[i]);
}
int count_ok = 0;
// NOLINTNEXTLINE(modernize-loop-convert)
@@ -223,36 +223,36 @@ TEST_F(StorageUniqueConstraints, ChangeLabels) {
// should succeed.
{
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_OK(vertex->SetProperty(prop1, PropertyValue(3 * i)));
ASSERT_OK(vertex->SetProperty(prop2, PropertyValue(3 * i + 1)));
ASSERT_OK(vertex->SetProperty(prop3, PropertyValue(3 * i + 2)));
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
for (int iter = 0; iter < 20; ++iter) {
// Clear labels.
{
auto acc = storage.Access();
auto acc = storage->Access();
// NOLINTNEXTLINE(modernize-loop-convert)
for (int i = 0; i < kNumThreads; ++i) {
auto vertex = acc.FindVertex(gids[i], memgraph::storage::View::OLD);
auto vertex = acc->FindVertex(gids[i], memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
ASSERT_OK(vertex->RemoveLabel(label));
}
ASSERT_OK(acc.Commit());
ASSERT_OK(acc->Commit());
}
bool status[kNumThreads];
std::vector<std::thread> threads;
threads.reserve(kNumThreads);
for (int i = 0; i < kNumThreads; ++i) {
threads.emplace_back(AddLabel, &storage, gids[i], label, &status[i]);
threads.emplace_back(AddLabel, storage.get(), gids[i], label, &status[i]);
}
int count_ok = 0;
for (int i = 0; i < kNumThreads; ++i) {

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -13,16 +13,16 @@
#include <gflags/gflags.h>
#include "storage/v2/storage.hpp"
#include "storage/v2/inmemory/storage.hpp"
DECLARE_int32(min_log_level);
int main(int argc, char *argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
spdlog::set_level(spdlog::level::err);
memgraph::storage::Storage db;
auto storage_dba = db.Access();
memgraph::query::DbAccessor dba(&storage_dba);
std::unique_ptr<memgraph::storage::Storage> db(new memgraph::storage::InMemoryStorage());
auto storage_dba = db->Access();
memgraph::query::DbAccessor dba(storage_dba.get());
RunInteractivePlanning(&dba);
return 0;
}

View File

@@ -13,8 +13,8 @@
#include "license/license.hpp"
#include "query/config.hpp"
#include "query/interpreter.hpp"
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/isolation_level.hpp"
#include "storage/v2/storage.hpp"
#include "utils/on_scope_exit.hpp"
int main(int argc, char *argv[]) {

View File

@@ -29,7 +29,6 @@ QUERY_COUNT_LOWER_BOUND = 30
def parse_args():
parser = argparse.ArgumentParser(
description="Memgraph benchmark executor.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
@@ -205,7 +204,6 @@ def warmup(condition: str, client: runners.BaseRunner, queries: list = None):
def mixed_workload(
vendor: runners.BaseRunner, client: runners.BaseClient, dataset, group, queries, benchmark_context: BenchmarkContext
):
num_of_queries = benchmark_context.mode_config[0]
percentage_distribution = benchmark_context.mode_config[1:]
if sum(percentage_distribution) != 100:
@@ -233,7 +231,7 @@ def mixed_workload(
"analytical": [],
}
for (_, funcname) in queries[group]:
for _, funcname in queries[group]:
for key in queries_by_type.keys():
if key in funcname:
queries_by_type[key].append(funcname)
@@ -349,7 +347,6 @@ def get_query_cache_count(
config_key: list,
benchmark_context: BenchmarkContext,
):
cached_count = config.get_value(*config_key)
if cached_count is None:
log.info(
@@ -403,7 +400,6 @@ def get_query_cache_count(
if __name__ == "__main__":
args = parse_args()
vendor_specific_args = helpers.parse_kwargs(args.vendor_specific)
@@ -593,7 +589,7 @@ if __name__ == "__main__":
ret = client.execute(
queries=get_queries(func, count),
num_workers=benchmark_context.num_workers_for_benchmark,
time_dependent_execution=benchmark_context.time_depended_execution,
time_dependent_execution=benchmark_context.time_dependent_execution,
)[0]
else:
ret = client.execute(
@@ -647,7 +643,6 @@ if __name__ == "__main__":
vendor_runner.stop("authorization")
for query, funcname in queries[group]:
log.info(
"Running query:",
"{}/{}/{}/{}".format(group, query, funcname, WITH_FINE_GRAINED_AUTHORIZATION),

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Memgraph Ltd.
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
@@ -9,6 +9,7 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
#include <memory>
#include <unordered_map>
#include <vector>
@@ -19,7 +20,9 @@
#include <rapidcheck.h>
#include <rapidcheck/gtest.h>
#include "storage/v2/inmemory/storage.hpp"
#include "storage/v2/storage.hpp"
#include "storage/v2/vertex_accessor.hpp"
/**
* It is possible to run test with custom seed with:
@@ -32,45 +35,45 @@ RC_GTEST_PROP(RandomGraph, RandomGraph, (std::vector<std::string> vertex_labels,
int vertices_num = vertex_labels.size();
int edges_num = edge_types.size();
memgraph::storage::Storage db;
std::vector<memgraph::storage::VertexAccessor> vertices;
std::unordered_map<memgraph::storage::VertexAccessor, std::string> vertex_label_map;
std::unordered_map<memgraph::storage::EdgeAccessor, std::string> edge_type_map;
std::unique_ptr<memgraph::storage::Storage> db{new memgraph::storage::InMemoryStorage()};
std::vector<std::unique_ptr<memgraph::storage::VertexAccessor>> vertices;
std::unordered_map<std::unique_ptr<memgraph::storage::VertexAccessor>, std::string> vertex_label_map;
std::unordered_map<std::unique_ptr<memgraph::storage::EdgeAccessor>, std::string> edge_type_map;
auto dba = db.Access();
auto dba = db->Access();
for (auto label : vertex_labels) {
auto vertex_accessor = dba.CreateVertex();
RC_ASSERT(vertex_accessor.AddLabel(dba.NameToLabel(label)).HasValue());
vertex_label_map.insert({vertex_accessor, label});
vertices.push_back(vertex_accessor);
auto vertex_accessor = dba->CreateVertex();
RC_ASSERT(vertex_accessor->AddLabel(dba->NameToLabel(label)).HasValue());
vertex_label_map.emplace(vertex_accessor->Copy(), label);
vertices.push_back(std::move(vertex_accessor));
}
for (auto type : edge_types) {
auto &from = vertices[*rc::gen::inRange(0, vertices_num)];
auto &to = vertices[*rc::gen::inRange(0, vertices_num)];
auto maybe_edge_accessor = dba.CreateEdge(&from, &to, dba.NameToEdgeType(type));
auto maybe_edge_accessor = dba->CreateEdge(from.get(), to.get(), dba->NameToEdgeType(type));
RC_ASSERT(maybe_edge_accessor.HasValue());
edge_type_map.insert({*maybe_edge_accessor, type});
edge_type_map.emplace(std::move(maybe_edge_accessor.GetValue()), type);
}
dba.AdvanceCommand();
dba->AdvanceCommand();
int edges_num_check = 0;
int vertices_num_check = 0;
for (auto vertex : dba.Vertices(memgraph::storage::View::OLD)) {
auto label = vertex_label_map.at(vertex);
auto maybe_labels = vertex.Labels(memgraph::storage::View::OLD);
for (auto vertex : dba->Vertices(memgraph::storage::View::OLD)) {
auto label = vertex_label_map.at(vertex->Copy());
auto maybe_labels = vertex->Labels(memgraph::storage::View::OLD);
RC_ASSERT(maybe_labels.HasValue());
const auto &labels = *maybe_labels;
RC_ASSERT(labels.size() == 1);
RC_ASSERT(dba.LabelToName(labels[0]) == label);
RC_ASSERT(dba->LabelToName(labels[0]) == label);
vertices_num_check++;
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::OLD);
auto maybe_edges = vertex->OutEdges(memgraph::storage::View::OLD);
RC_ASSERT(maybe_edges.HasValue());
for (auto &edge : *maybe_edges) {
const auto &type = edge_type_map.at(edge);
RC_ASSERT(dba.EdgeTypeToName(edge.EdgeType()) == type);
RC_ASSERT(dba->EdgeTypeToName(edge->EdgeType()) == type);
edges_num_check++;
}
}