Compare commits
13 Commits
index_temp
...
local_shar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb41396e86 | ||
|
|
614e321ebb | ||
|
|
9a70476872 | ||
|
|
d47372b455 | ||
|
|
9e710aa00b | ||
|
|
59ed253b82 | ||
|
|
dfdba859ff | ||
|
|
01428b49e1 | ||
|
|
b98c9b94ca | ||
|
|
54e6aef954 | ||
|
|
20f16eafa3 | ||
|
|
a69829d01b | ||
|
|
01e0dcdfb4 |
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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[]) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user