From 323cec8bb4e3819e8590cde28b90a3c9b74ae991 Mon Sep 17 00:00:00 2001 From: Aidar Samerkhanov Date: Mon, 23 Oct 2023 16:55:13 +0000 Subject: [PATCH 01/17] Handle analytical mode in community_detection during parallel changes --- cpp/mg_utility/data_structures/graph_view.hpp | 10 ++++++ cpp/mg_utility/mg_graph.hpp | 31 +++++++++++++++++-- cpp/mg_utility/mg_utils.hpp | 4 ++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/cpp/mg_utility/data_structures/graph_view.hpp b/cpp/mg_utility/data_structures/graph_view.hpp index 8f5157efc..9af3ba253 100644 --- a/cpp/mg_utility/data_structures/graph_view.hpp +++ b/cpp/mg_utility/data_structures/graph_view.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "graph_data.hpp" @@ -97,9 +98,18 @@ class GraphView { /// ///@param memgraph_id Memgraph's internal ID ///@return TSize + ///@throws mg_exception::InvalidIDException if vertex does not exist /// virtual TSize GetInnerNodeId(std::uint64_t memgraph_id) const = 0; + /// + ///@brief Get the Inner Node ID from Memgraph ID + /// + ///@param memgraph_id Memgraph's internal ID + ///@return std::optional, which is null if vertex does not exist + /// + virtual std::optional GetInnerNodeIdOpt(std::uint64_t memgraph_id) const = 0; + /// ///@brief Get the Memgraph Edge Id from the inner renumbered node ID /// diff --git a/cpp/mg_utility/mg_graph.hpp b/cpp/mg_utility/mg_graph.hpp index d2679fdb3..3ba665e3e 100644 --- a/cpp/mg_utility/mg_graph.hpp +++ b/cpp/mg_utility/mg_graph.hpp @@ -199,8 +199,14 @@ class Graph : public GraphView { return std::nullopt; } - auto from = GetInnerNodeId(memgraph_id_from); - auto to = GetInnerNodeId(memgraph_id_to); + auto fromOpt = GetInnerNodeIdOpt(memgraph_id_from); + auto toOpt = GetInnerNodeIdOpt(memgraph_id_to); + if (!fromOpt || !toOpt) { + return std::nullopt; + } + + auto from = *fromOpt; + auto to = *toOpt; auto id = edges_.size(); inner_to_memgraph_edge_id_.emplace(id, edge_id); @@ -314,6 +320,21 @@ class Graph : public GraphView { return memgraph_to_inner_id_.at(memgraph_id); } + /// + /// Returns the GraphView ID from Memgraph's internal ID + /// + /// @param node_id Memgraphs's inner ID + /// + std::optional GetInnerNodeIdOpt(std::uint64_t memgraph_id) const override { + if (memgraph_to_inner_id_.find(memgraph_id) == memgraph_to_inner_id_.end()) { + if (IsTransactional()) { + throw mg_exception::InvalidIDException(); + } + return std::nullopt; + } + return memgraph_to_inner_id_.at(memgraph_id); + } + /// /// Returns the Memgraph database ID from graph view /// @@ -381,6 +402,10 @@ class Graph : public GraphView { nodes_to_edge_.clear(); } + void SetIsTransactional(bool is_transactional) { is_transactional_ = is_transactional; } + + bool IsTransactional() const { return is_transactional_; } + private: // Constant is used for marking deleted edges. // If edge id is equal to constant, edge is deleted. @@ -402,5 +427,7 @@ class Graph : public GraphView { std::unordered_map memgraph_to_inner_edge_id_; std::multimap, TSize> nodes_to_edge_; + + bool is_transactional_; }; } // namespace mg_graph diff --git a/cpp/mg_utility/mg_utils.hpp b/cpp/mg_utility/mg_utils.hpp index 41630a31b..6567e5e97 100644 --- a/cpp/mg_utility/mg_utils.hpp +++ b/cpp/mg_utility/mg_utils.hpp @@ -9,9 +9,9 @@ #include #include +#include "_mgp.hpp" #include "mg_graph.hpp" #include "mgp.hpp" -#include "_mgp.hpp" namespace mg_graph { @@ -119,6 +119,8 @@ std::unique_ptr> GetGraphView(mgp_graph *memgraph_graph, const char *weight_property = nullptr, double default_weight = 1.0) { auto graph = std::make_unique>(); + bool isTransactionalStorage = mgp::graph_is_transactional(memgraph_graph); + graph->SetIsTransactional(isTransactionalStorage); /// /// Mapping Memgraph in-memory vertices into the graph view From 8b9d4e01e10699de30954d60073ff2101c64d065 Mon Sep 17 00:00:00 2001 From: Aidar Samerkhanov Date: Tue, 24 Oct 2023 09:42:06 +0000 Subject: [PATCH 02/17] Fix core dump when vertex is already deleted from memgraph graph --- .../community_detection_module.cpp | 9 ++++++++- cpp/mg_utility/mg_utils.hpp | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cpp/community_detection_module/community_detection_module.cpp b/cpp/community_detection_module/community_detection_module.cpp index 3710ba6e4..286a9bba6 100644 --- a/cpp/community_detection_module/community_detection_module.cpp +++ b/cpp/community_detection_module/community_detection_module.cpp @@ -27,7 +27,14 @@ void InsertLouvainRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memor mgp_result_record *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + bool res = mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + if (!res) { + mgp::result_delete_last_record(result); + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } mg_utility::InsertIntValueResult(record, kFieldCommunity, community, memory); } diff --git a/cpp/mg_utility/mg_utils.hpp b/cpp/mg_utility/mg_utils.hpp index 6567e5e97..d214326c5 100644 --- a/cpp/mg_utility/mg_utils.hpp +++ b/cpp/mg_utility/mg_utils.hpp @@ -283,10 +283,15 @@ void InsertNodeValueResult(mgp_result_record *record, const char *field_name, mg /// Inserts a node with its ID node_id to create a vertex and insert /// the node to the field field_name of the record mgp_result_record record. -void InsertNodeValueResult(mgp_graph *graph, mgp_result_record *record, const char *field_name, const int node_id, +/// Returns true is insert is successful, false otherwise +bool InsertNodeValueResult(mgp_graph *graph, mgp_result_record *record, const char *field_name, const int node_id, mgp_memory *memory) { auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = node_id}, memory); + if (!vertex) { + return false; + } InsertNodeValueResult(record, field_name, vertex, memory); + return true; } /// Inserts a relationship of value edge_value to the field field_name of From fa23b72d9960b75efa7bf06216c5f125c93f5840 Mon Sep 17 00:00:00 2001 From: Aidar Samerkhanov Date: Thu, 26 Oct 2023 14:59:45 +0000 Subject: [PATCH 03/17] First create for vertex existence and insert if exists --- .../community_detection_module.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cpp/community_detection_module/community_detection_module.cpp b/cpp/community_detection_module/community_detection_module.cpp index 286a9bba6..a16c2d4a2 100644 --- a/cpp/community_detection_module/community_detection_module.cpp +++ b/cpp/community_detection_module/community_detection_module.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -24,17 +25,20 @@ const double kDefaultWeight = 1.0; void InsertLouvainRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, const std::uint64_t community) { - mgp_result_record *record = mgp::result_new_record(result); - if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - - bool res = mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); - if (!res) { - mgp::result_delete_last_record(result); + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!vertex) { if (mgp::graph_is_transactional(graph)) { throw mg_exception::InvalidIDException(); } + // For Analytical mode it's possible that some vertices/edges are missing + // because of changes in parallel transactions. return; } + + mgp_result_record *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); mg_utility::InsertIntValueResult(record, kFieldCommunity, community, memory); } From 0805098a50d6a8e219ddd010de3964f926110459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Mon, 6 Nov 2023 16:16:48 +0100 Subject: [PATCH 04/17] Add fixes for the C and C++ APIs --- .../community_detection_online_module.cpp | 27 ++++++++++++------- cpp/pagerank_module/pagerank_module.cpp | 13 +++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/cpp/community_detection_module/community_detection_online_module.cpp b/cpp/community_detection_module/community_detection_online_module.cpp index 782e231f2..bd2d6f87f 100644 --- a/cpp/community_detection_module/community_detection_online_module.cpp +++ b/cpp/community_detection_module/community_detection_online_module.cpp @@ -53,7 +53,7 @@ std::string saved_weight_property = kDefaultWeightProperty.data(); void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto graph = mgp::Graph(memgraph_graph); const auto arguments = mgp::List(args); @@ -78,9 +78,18 @@ void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo ::initialized = true; for (const auto [node_id, label] : labels) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldCommunityId.data(), label); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldCommunityId.data(), label); + } catch (const std::exception &e) { + continue; + } } } catch (const std::exception &e) { return; @@ -90,7 +99,7 @@ void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo void Get(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -119,7 +128,7 @@ void Get(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto graph = mgp::Graph(memgraph_graph); const auto arguments = mgp::List(args); @@ -189,7 +198,7 @@ void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m void Reset(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); @@ -203,7 +212,7 @@ void Reset(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_me auto record = record_factory.NewRecord(); record.Insert(kFieldMessage.data(), "The algorithm has been successfully reset!"); } catch (const std::exception &e) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); auto record = record_factory.NewRecord(); @@ -216,7 +225,7 @@ void Reset(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_me extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto node_list = std::make_pair(mgp::Type::List, mgp::Type::Node); const auto relationship_list = std::make_pair(mgp::Type::List, mgp::Type::Relationship); diff --git a/cpp/pagerank_module/pagerank_module.cpp b/cpp/pagerank_module/pagerank_module.cpp index a07694062..49c7429a8 100644 --- a/cpp/pagerank_module/pagerank_module.cpp +++ b/cpp/pagerank_module/pagerank_module.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include "algorithm/pagerank.hpp" @@ -14,9 +16,16 @@ constexpr char const *kArgumentStopEpsilon = "stop_epsilon"; void InsertPagerankRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double rank) { - auto *record = mgp::result_new_record(result); + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!vertex) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + auto *record = mgp::result_new_record(result); + mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); mg_utility::InsertDoubleValueResult(record, kFieldRank, rank, memory); } From c314170c241d0a85bff2689832aa4723fead332b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Thu, 9 Nov 2023 01:31:26 +0100 Subject: [PATCH 05/17] Fix doubled ; after statement --- .../algorithm/collections.cpp | 36 +++++++++---------- cpp/collections_module/collections_module.cpp | 2 +- cpp/create_module/algorithm/create.cpp | 20 +++++------ cpp/create_module/create_module.cpp | 2 +- .../distance_calculator.cpp | 6 ++-- cpp/do_module/do_module.cpp | 6 ++-- .../algorithms/ancestors.hpp | 2 +- .../algorithms/chain_nodes.hpp | 2 +- .../algorithms/connect_nodes.hpp | 2 +- .../algorithms/descendants.hpp | 2 +- .../algorithms/topological_sort.hpp | 2 +- cpp/graph_util_module/graph_util_module.cpp | 2 +- .../katz_centrality_online_module.cpp | 2 +- cpp/label_module/algorithm/label.cpp | 2 +- cpp/label_module/label_module.cpp | 2 +- cpp/map_module/algorithm/map.cpp | 18 +++++----- cpp/map_module/map_module.cpp | 2 +- cpp/neighbors_module/algorithm/neighbors.cpp | 4 +-- cpp/neighbors_module/neighbors_module.cpp | 2 +- cpp/node_module/algorithm/node.cpp | 6 ++-- cpp/node_module/node_module.cpp | 2 +- .../node_similarity_module.cpp | 14 ++++---- cpp/nodes_module/algorithm/nodes.cpp | 8 ++--- cpp/nodes_module/nodes_module.cpp | 2 +- .../pagerank_online_module.cpp | 2 +- cpp/path_module/algorithm/path.cpp | 8 ++--- cpp/path_module/path_module.cpp | 2 +- cpp/periodic_module/periodic_iterate.cpp | 4 +-- cpp/refactor_module/algorithm/refactor.cpp | 4 +-- cpp/schema_module/algorithm/schema.cpp | 4 +-- cpp/schema_module/schema_module.cpp | 2 +- cpp/text_module/algorithm/text.cpp | 2 +- cpp/text_module/text_module.cpp | 2 +- cpp/util_module/algorithm/util.cpp | 2 +- cpp/util_module/util_module.cpp | 2 +- 35 files changed, 91 insertions(+), 91 deletions(-) diff --git a/cpp/collections_module/algorithm/collections.cpp b/cpp/collections_module/algorithm/collections.cpp index f9088c859..6443c3160 100644 --- a/cpp/collections_module/algorithm/collections.cpp +++ b/cpp/collections_module/algorithm/collections.cpp @@ -42,7 +42,7 @@ void Collections::SetResult(mgp::Result &result, const mgp::Value &value) { } void Collections::SumLongs(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -67,7 +67,7 @@ void Collections::SumLongs(mgp_list *args, mgp_func_context *ctx, mgp_func_resul } void Collections::Avg(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -94,7 +94,7 @@ void Collections::Avg(mgp_list *args, mgp_func_context *ctx, mgp_func_result *re } void Collections::ContainsAll(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -104,7 +104,7 @@ void Collections::ContainsAll(mgp_list *args, mgp_func_context *ctx, mgp_func_re const auto list2{arguments[1].ValueList()}; - std::unordered_set values(list2.begin(), list2.end());; + std::unordered_set values(list2.begin(), list2.end()); result.SetValue(std::all_of(values.begin(), values.end(), [&set](const auto &x) { return set.contains(x); })); @@ -115,7 +115,7 @@ void Collections::ContainsAll(mgp_list *args, mgp_func_context *ctx, mgp_func_re } void Collections::Intersection(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -147,7 +147,7 @@ void Collections::Intersection(mgp_list *args, mgp_func_context *ctx, mgp_func_r } void Collections::RemoveAll(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -181,7 +181,7 @@ void Collections::RemoveAll(mgp_list *args, mgp_func_context *ctx, mgp_func_resu } void Collections::Sum(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -204,7 +204,7 @@ void Collections::Sum(mgp_list *args, mgp_func_context *ctx, mgp_func_result *re } void Collections::Union(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -249,7 +249,7 @@ void Collections::Union(mgp_list *args, mgp_func_context *ctx, mgp_func_result * } void Collections::Sort(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -271,7 +271,7 @@ void Collections::Sort(mgp_list *args, mgp_func_context *ctx, mgp_func_result *r } void Collections::ContainsSorted(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -304,7 +304,7 @@ void Collections::ContainsSorted(mgp_list *args, mgp_func_context *ctx, mgp_func } void Collections::Max(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -331,7 +331,7 @@ void Collections::Max(mgp_list *args, mgp_func_context *ctx, mgp_func_result *re } void Collections::Split(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); @@ -370,7 +370,7 @@ void Collections::Split(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *r } void Collections::Pairs(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -401,7 +401,7 @@ void Collections::Pairs(mgp_list *args, mgp_func_context *ctx, mgp_func_result * } void Collections::Contains(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -429,7 +429,7 @@ void Collections::Contains(mgp_list *args, mgp_func_context *ctx, mgp_func_resul } void Collections::UnionAll(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -448,7 +448,7 @@ void Collections::UnionAll(mgp_list *args, mgp_func_context *ctx, mgp_func_resul } void Collections::Min(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -486,7 +486,7 @@ void Collections::Min(mgp_list *args, mgp_func_context *ctx, mgp_func_result *re } void Collections::ToSet(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -506,7 +506,7 @@ void Collections::ToSet(mgp_list *args, mgp_func_context *ctx, mgp_func_result * } void Collections::Partition(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/collections_module/collections_module.cpp b/cpp/collections_module/collections_module.cpp index 1b41c5017..e4b7dbb6f 100644 --- a/cpp/collections_module/collections_module.cpp +++ b/cpp/collections_module/collections_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; mgp::AddFunction(Collections::SumLongs, Collections::kProcedureSumLongs, {mgp::Parameter(Collections::kSumLongsArg1, {mgp::Type::List, mgp::Type::Any})}, module, memory); diff --git a/cpp/create_module/algorithm/create.cpp b/cpp/create_module/algorithm/create.cpp index 7b1369ea0..fb4b9add8 100644 --- a/cpp/create_module/algorithm/create.cpp +++ b/cpp/create_module/algorithm/create.cpp @@ -34,7 +34,7 @@ void ModifyAndOutput(mgp::Relationship &relationship, const mgp::List &keys, con } // namespace void Create::RemoveRelProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); @@ -80,7 +80,7 @@ void Create::RemoveRelProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_ } void Create::SetRelProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); @@ -131,7 +131,7 @@ void Create::SetRelProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_res } void Create::Relationship(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); @@ -181,7 +181,7 @@ void Create::ProcessElement(const mgp::Value &element, const mgp::Graph graph, c } void Create::SetRelProperty(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -256,7 +256,7 @@ void Create::ProcessElement(const mgp::Value &element, const mgp::Graph graph, c } void Create::RemoveLabels(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -278,7 +278,7 @@ void Create::RemoveLabels(mgp_list *args, mgp_graph *memgraph_graph, mgp_result } void Create::RemoveProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -324,7 +324,7 @@ void Create::ProcessElement(const mgp::Value &element, const mgp::Graph graph, c } void Create::SetProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -351,7 +351,7 @@ void Create::SetProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result } void Create::Node(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -379,7 +379,7 @@ void Create::Node(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, } void Create::Nodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -407,7 +407,7 @@ void Create::Nodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result } void Create::SetProperty(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/create_module/create_module.cpp b/cpp/create_module/create_module.cpp index 07cd58777..91baa4c59 100644 --- a/cpp/create_module/create_module.cpp +++ b/cpp/create_module/create_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Create::SetRelProperty, Create::kProcedureSetRelProp, mgp::ProcedureType::Write, {mgp::Parameter(Create::kArgumentsRelationship, mgp::Type::Any), diff --git a/cpp/distance_calculator/distance_calculator.cpp b/cpp/distance_calculator/distance_calculator.cpp index fdcc6da5d..a229a2541 100644 --- a/cpp/distance_calculator/distance_calculator.cpp +++ b/cpp/distance_calculator/distance_calculator.cpp @@ -49,7 +49,7 @@ double distance_calc(const mgp::Node &node1, const mgp::Node &node2, bool use_km } void Single(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { @@ -69,7 +69,7 @@ void Single(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m } void Multiple(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { @@ -102,7 +102,7 @@ void Multiple(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure( Single, kProcedureSingle, mgp::ProcedureType::Read, diff --git a/cpp/do_module/do_module.cpp b/cpp/do_module/do_module.cpp index f70483ba0..7a2a30b00 100644 --- a/cpp/do_module/do_module.cpp +++ b/cpp/do_module/do_module.cpp @@ -309,7 +309,7 @@ bool IsGlobalOperation(std::string_view query) { } void When(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto condition = arguments[0].ValueBool(); @@ -335,7 +335,7 @@ void When(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_mem } void Case(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto conditionals = arguments[0].ValueList(); @@ -391,7 +391,7 @@ void Case(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_mem extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; mgp::AddProcedure(Case, kProcedureCase, mgp::ProcedureType::Read, {mgp::Parameter(kArgumentConditionals, {mgp::Type::List, mgp::Type::Any}), diff --git a/cpp/graph_util_module/algorithms/ancestors.hpp b/cpp/graph_util_module/algorithms/ancestors.hpp index a79b4d78b..885965073 100644 --- a/cpp/graph_util_module/algorithms/ancestors.hpp +++ b/cpp/graph_util_module/algorithms/ancestors.hpp @@ -5,7 +5,7 @@ const char *kResultAncestors = "ancestors"; void Ancestors(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/graph_util_module/algorithms/chain_nodes.hpp b/cpp/graph_util_module/algorithms/chain_nodes.hpp index f0c440080..24b5b5c18 100644 --- a/cpp/graph_util_module/algorithms/chain_nodes.hpp +++ b/cpp/graph_util_module/algorithms/chain_nodes.hpp @@ -4,7 +4,7 @@ const char *kResultChainNodes = "connections"; void ChainNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto graph = mgp::Graph(memgraph_graph); auto factory = mgp::RecordFactory(result); diff --git a/cpp/graph_util_module/algorithms/connect_nodes.hpp b/cpp/graph_util_module/algorithms/connect_nodes.hpp index 1b345f57f..07c5673b6 100644 --- a/cpp/graph_util_module/algorithms/connect_nodes.hpp +++ b/cpp/graph_util_module/algorithms/connect_nodes.hpp @@ -3,7 +3,7 @@ const char *kResultConnections = "connections"; void ConnectNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/graph_util_module/algorithms/descendants.hpp b/cpp/graph_util_module/algorithms/descendants.hpp index 1e2bf96ea..459a62c9e 100644 --- a/cpp/graph_util_module/algorithms/descendants.hpp +++ b/cpp/graph_util_module/algorithms/descendants.hpp @@ -5,7 +5,7 @@ const char *kResultDescendants = "descendants"; void Descendants(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/graph_util_module/algorithms/topological_sort.hpp b/cpp/graph_util_module/algorithms/topological_sort.hpp index 9a73c40f8..cf3cea353 100644 --- a/cpp/graph_util_module/algorithms/topological_sort.hpp +++ b/cpp/graph_util_module/algorithms/topological_sort.hpp @@ -5,7 +5,7 @@ const char *kResultSortedNodes = "sorted_nodes"; void TopologicalSort(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); const auto graph = mgp::Graph(memgraph_graph); mgp::List topological_ordering = mgp::List(); diff --git a/cpp/graph_util_module/graph_util_module.cpp b/cpp/graph_util_module/graph_util_module.cpp index c0ac56956..b8cf4cc1c 100644 --- a/cpp/graph_util_module/graph_util_module.cpp +++ b/cpp/graph_util_module/graph_util_module.cpp @@ -23,7 +23,7 @@ const char *kArgumentNodes = "nodes"; extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; // Register ancestors procedure const auto ancestors_return = std::make_pair(mgp::Type::List, mgp::Type::Node); diff --git a/cpp/katz_centrality_module/katz_centrality_online_module.cpp b/cpp/katz_centrality_module/katz_centrality_online_module.cpp index b6c50d9c4..5802b034e 100644 --- a/cpp/katz_centrality_module/katz_centrality_online_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_online_module.cpp @@ -67,7 +67,7 @@ void SetKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *re void UpdateKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); const auto graph = mgp::Graph(memgraph_graph); diff --git a/cpp/label_module/algorithm/label.cpp b/cpp/label_module/algorithm/label.cpp index 4415691c6..64e197fee 100644 --- a/cpp/label_module/algorithm/label.cpp +++ b/cpp/label_module/algorithm/label.cpp @@ -1,7 +1,7 @@ #include "label.hpp" void Label::Exists(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { diff --git a/cpp/label_module/label_module.cpp b/cpp/label_module/label_module.cpp index c0886dafb..bd4a29474 100644 --- a/cpp/label_module/label_module.cpp +++ b/cpp/label_module/label_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; mgp::AddFunction(Label::Exists, Label::kFunctionExists, {mgp::Parameter(Label::kArgumentsNode, mgp::Type::Any), diff --git a/cpp/map_module/algorithm/map.cpp b/cpp/map_module/algorithm/map.cpp index 328978bdd..42bfa816e 100644 --- a/cpp/map_module/algorithm/map.cpp +++ b/cpp/map_module/algorithm/map.cpp @@ -9,7 +9,7 @@ const auto number_of_elements_in_pair = 2; /*NOTE: FromNodes isn't 1:1 for graphQL, because first, we need to extend C and CPP API to iterate vertices using ctx object, since the `FromNodes` procedure (function if we want to change API) needs to iterate over all graph nodes*/ void Map::FromNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); @@ -55,7 +55,7 @@ void Map::FromNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *resul } void Map::FromValues(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -87,7 +87,7 @@ void Map::FromValues(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res } void Map::SetKey(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); @@ -124,7 +124,7 @@ void Map::RemoveRecursion(mgp::Map &result, bool recursive, std::string_view key } void Map::RemoveKey(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -145,7 +145,7 @@ void Map::RemoveKey(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, } void Map::FromPairs(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -173,7 +173,7 @@ void Map::FromPairs(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, } void Map::Merge(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -209,7 +209,7 @@ void Map::FlattenRecursion(mgp::Map &result, const mgp::Map &input, const std::s } void Map::Flatten(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto result = mgp::Result(res); try { @@ -226,7 +226,7 @@ void Map::Flatten(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, m } void Map::FromLists(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; auto arguments = mgp::List(args); auto result_object = mgp::Result(res); try { @@ -272,7 +272,7 @@ void Map::RemoveRecursionSet(mgp::Map &result, bool recursive, std::unordered_se } void Map::RemoveKeys(mgp_list *args, mgp_func_context *ctx, mgp_func_result *res, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; auto arguments = mgp::List(args); auto result = mgp::Result(res); try { diff --git a/cpp/map_module/map_module.cpp b/cpp/map_module/map_module.cpp index 9245c485b..5c1ec44af 100644 --- a/cpp/map_module/map_module.cpp +++ b/cpp/map_module/map_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; mgp::AddFunction(Map::Flatten, std::string(Map::kProcedureFlatten).c_str(), {mgp::Parameter(std::string(Map::kArgumentMapFlatten).c_str(), {mgp::Type::Map, mgp::Type::Any}), diff --git a/cpp/neighbors_module/algorithm/neighbors.cpp b/cpp/neighbors_module/algorithm/neighbors.cpp index 15ca47505..d7317df7e 100644 --- a/cpp/neighbors_module/algorithm/neighbors.cpp +++ b/cpp/neighbors_module/algorithm/neighbors.cpp @@ -38,7 +38,7 @@ void DetermineDirection(mgp::List &rel_types, std::unordered_set types, mgp::Rel } void Node::RelationshipExists(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -165,7 +165,7 @@ void Node::RelationshipExists(mgp_list *args, mgp_graph *memgraph_graph, mgp_res } void Node::RelationshipTypes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/node_module/node_module.cpp b/cpp/node_module/node_module.cpp index 35fa39b4a..2a1e54c39 100644 --- a/cpp/node_module/node_module.cpp +++ b/cpp/node_module/node_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Node::RelationshipsExist, std::string(Node::kProcedureRelationshipsExist).c_str(), mgp::ProcedureType::Read, {mgp::Parameter(std::string(Node::kArgumentNodesRelationshipsExist).c_str(), mgp::Type::Node), diff --git a/cpp/node_similarity_module/node_similarity_module.cpp b/cpp/node_similarity_module/node_similarity_module.cpp index dd2182c46..a57892386 100644 --- a/cpp/node_similarity_module/node_similarity_module.cpp +++ b/cpp/node_similarity_module/node_similarity_module.cpp @@ -38,7 +38,7 @@ void insert_results(const std::vector> Calculates Jaccard similarity between given pairs of nodes. */ void JaccardPairwise(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); const auto &arguments = mgp::List(args); try { @@ -52,7 +52,7 @@ void JaccardPairwise(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *resu Calculates overlap similarity between given pairs of nodes. */ void OverlapPairwise(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto &arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -67,7 +67,7 @@ Calculates Jaccard similarity between all pairs of nodes. Jacc. similarity of two nodes can be calculated as len(intersection(neighbours(node1), neighbours(node2))) / len(union(neighbours(node1), neighbours(node2))) */ void Jaccard(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { insert_results(node_similarity_algs::CalculateSimilarityCartesian(mgp::Graph(memgraph_graph), node_similarity_util::Similarity::jaccard), record_factory); @@ -81,7 +81,7 @@ Calculates overlap similarity between all pairs of nodes. Overlap similarity of two nodes can be calculated as len(intersection(neighbours(node1), neighbours(node2))) / min(len(neighbours(node1), len(node2))) */ void Overlap(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { insert_results(node_similarity_algs::CalculateSimilarityCartesian(mgp::Graph(memgraph_graph), node_similarity_util::Similarity::overlap), record_factory); @@ -95,7 +95,7 @@ void Overlap(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_ Calculates cosine similarity between all pairs of nodes. */ void Cosine(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); const auto &arguments = mgp::List(args); try { @@ -109,7 +109,7 @@ void Cosine(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m Calculates overlap similarity between given pairs of nodes. */ void CosinePairwise(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); const auto &arguments = mgp::List(args); try { @@ -121,7 +121,7 @@ void CosinePairwise(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *resul extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; // method objects std::vector returns = { mgp::Return(node1_name, mgp::Type::Node), diff --git a/cpp/nodes_module/algorithm/nodes.cpp b/cpp/nodes_module/algorithm/nodes.cpp index ddac2b326..117649690 100644 --- a/cpp/nodes_module/algorithm/nodes.cpp +++ b/cpp/nodes_module/algorithm/nodes.cpp @@ -27,7 +27,7 @@ bool Nodes::RelationshipExist(const mgp::Node &node, std::string &rel_type) { } void Nodes::RelationshipsExist(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -167,7 +167,7 @@ void DetachDeleteNode(const mgp::Value &node, mgp::Graph &graph) { } // namespace void Nodes::RelationshipTypes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -182,7 +182,7 @@ void Nodes::RelationshipTypes(mgp_list *args, mgp_graph *memgraph_graph, mgp_res } void Nodes::Delete(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -206,7 +206,7 @@ void Nodes::Delete(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result void Nodes::Link(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/nodes_module/nodes_module.cpp b/cpp/nodes_module/nodes_module.cpp index aa381e0fc..53eb2c0db 100644 --- a/cpp/nodes_module/nodes_module.cpp +++ b/cpp/nodes_module/nodes_module.cpp @@ -5,7 +5,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Nodes::Link, std::string(Nodes::kProcedureLink).c_str(), mgp::ProcedureType::Write, {mgp::Parameter(std::string(Nodes::kArgumentNodesLink).c_str(), {mgp::Type::List, mgp::Type::Node}), diff --git a/cpp/pagerank_module/pagerank_online_module.cpp b/cpp/pagerank_module/pagerank_online_module.cpp index a904bf3ad..054efd50b 100644 --- a/cpp/pagerank_module/pagerank_online_module.cpp +++ b/cpp/pagerank_module/pagerank_online_module.cpp @@ -69,7 +69,7 @@ void OnlinePageRankSet(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *re void OnlinePageRankUpdate(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto graph = mgp::Graph(memgraph_graph); const auto arguments = mgp::List(args); diff --git a/cpp/path_module/algorithm/path.cpp b/cpp/path_module/algorithm/path.cpp index c5a1371c8..34076e923 100644 --- a/cpp/path_module/algorithm/path.cpp +++ b/cpp/path_module/algorithm/path.cpp @@ -5,7 +5,7 @@ #include "mgp.hpp" void Path::Create(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -250,7 +250,7 @@ void Path::StartFunction(const mgp::Node &node, const mgp::RecordFactory &record } void Path::Expand(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -416,7 +416,7 @@ void SetConfig(mgp::Map &config) { } void Path::SubgraphNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); @@ -454,7 +454,7 @@ void Path::SubgraphNodes(mgp_list *args, mgp_graph *memgraph_graph, mgp_result * } void Path::SubgraphAll(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto graph = mgp::Graph(memgraph_graph); const auto record_factory = mgp::RecordFactory(result); diff --git a/cpp/path_module/path_module.cpp b/cpp/path_module/path_module.cpp index 237743df7..97f16941d 100644 --- a/cpp/path_module/path_module.cpp +++ b/cpp/path_module/path_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure( Path::Expand, std::string(Path::kProcedureExpand).c_str(), mgp::ProcedureType::Read, {mgp::Parameter(std::string(Path::kArgumentStartExpand).c_str(), mgp::Type::Any), diff --git a/cpp/periodic_module/periodic_iterate.cpp b/cpp/periodic_module/periodic_iterate.cpp index 69de092d8..4ddeccc0e 100644 --- a/cpp/periodic_module/periodic_iterate.cpp +++ b/cpp/periodic_module/periodic_iterate.cpp @@ -226,7 +226,7 @@ mg::Client::Params GetClientParams() { } void PeriodicIterate(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); auto num_of_executed_batches = 0; @@ -296,7 +296,7 @@ void PeriodicIterate(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *resu extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; mgp::AddProcedure( PeriodicIterate, kProcedurePeriodic, mgp::ProcedureType::Read, {mgp::Parameter(kArgumentInputQuery, mgp::Type::String), diff --git a/cpp/refactor_module/algorithm/refactor.cpp b/cpp/refactor_module/algorithm/refactor.cpp index 4995fe226..7c976a30c 100644 --- a/cpp/refactor_module/algorithm/refactor.cpp +++ b/cpp/refactor_module/algorithm/refactor.cpp @@ -384,7 +384,7 @@ void Refactor::InvertRel(mgp::Graph &graph, mgp::Relationship &rel) { } void Refactor::Invert(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { @@ -429,7 +429,7 @@ void Refactor::Collapse(mgp::Graph &graph, const mgp::Node &node, const std::str } void Refactor::CollapseNode(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/schema_module/algorithm/schema.cpp b/cpp/schema_module/algorithm/schema.cpp index 107e08932..81e020999 100644 --- a/cpp/schema_module/algorithm/schema.cpp +++ b/cpp/schema_module/algorithm/schema.cpp @@ -56,7 +56,7 @@ void Schema::ProcessPropertiesRel(mgp::Record &record, const std::string_view &t } void Schema::NodeTypeProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { const mgp::Graph graph = mgp::Graph(memgraph_graph); @@ -90,7 +90,7 @@ void Schema::NodeTypeProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_r } void Schema::RelTypeProperties(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto record_factory = mgp::RecordFactory(result); try { const mgp::Graph graph = mgp::Graph(memgraph_graph); diff --git a/cpp/schema_module/schema_module.cpp b/cpp/schema_module/schema_module.cpp index 28de5b99c..ed2d0a3d3 100644 --- a/cpp/schema_module/schema_module.cpp +++ b/cpp/schema_module/schema_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Schema::NodeTypeProperties, std::string(Schema::kProcedureNodeType).c_str(), mgp::ProcedureType::Read, {}, diff --git a/cpp/text_module/algorithm/text.cpp b/cpp/text_module/algorithm/text.cpp index 81ccbbda9..1ab25d844 100644 --- a/cpp/text_module/algorithm/text.cpp +++ b/cpp/text_module/algorithm/text.cpp @@ -1,7 +1,7 @@ #include "text.hpp" void Text::Join(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); diff --git a/cpp/text_module/text_module.cpp b/cpp/text_module/text_module.cpp index 86713b616..96a04bddf 100644 --- a/cpp/text_module/text_module.cpp +++ b/cpp/text_module/text_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Text::Join, Text::kProcedureJoin, mgp::ProcedureType::Read, {mgp::Parameter(Text::kJoinArg1, {mgp::Type::List, mgp::Type::String}), diff --git a/cpp/util_module/algorithm/util.cpp b/cpp/util_module/algorithm/util.cpp index 50b480de6..612111c8d 100644 --- a/cpp/util_module/algorithm/util.cpp +++ b/cpp/util_module/algorithm/util.cpp @@ -2,7 +2,7 @@ #include "md5.hpp" void Util::Md5(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; const auto arguments = mgp::List(args); const auto record_factory = mgp::RecordFactory(result); try { diff --git a/cpp/util_module/util_module.cpp b/cpp/util_module/util_module.cpp index b7a028849..4f9ec3706 100644 --- a/cpp/util_module/util_module.cpp +++ b/cpp/util_module/util_module.cpp @@ -4,7 +4,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { - mgp::MemoryDispatcherGuard guard{memory};; + mgp::MemoryDispatcherGuard guard{memory}; AddProcedure(Util::Md5, std::string(Util::kProcedureMd5).c_str(), mgp::ProcedureType::Write, {mgp::Parameter(std::string(Util::kArgumentValuesMd5).c_str(), {mgp::Type::List, mgp::Type::Any})}, {mgp::Return(std::string(Util::kArgumentResultMd5).c_str(), mgp::Type::String)}, module, memory); From 4c8f5558fc112996ce7f8771aa49daa63d92c9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Thu, 9 Nov 2023 01:54:43 +0100 Subject: [PATCH 06/17] Improve the C and C++ API fixes --- .../community_detection_module.cpp | 3 +- .../community_detection_online_module.cpp | 30 +++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/cpp/community_detection_module/community_detection_module.cpp b/cpp/community_detection_module/community_detection_module.cpp index a16c2d4a2..f497d5eb3 100644 --- a/cpp/community_detection_module/community_detection_module.cpp +++ b/cpp/community_detection_module/community_detection_module.cpp @@ -30,8 +30,7 @@ void InsertLouvainRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memor if (mgp::graph_is_transactional(graph)) { throw mg_exception::InvalidIDException(); } - // For Analytical mode it's possible that some vertices/edges are missing - // because of changes in parallel transactions. + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. return; } diff --git a/cpp/community_detection_module/community_detection_online_module.cpp b/cpp/community_detection_module/community_detection_online_module.cpp index bd2d6f87f..3d41831d3 100644 --- a/cpp/community_detection_module/community_detection_online_module.cpp +++ b/cpp/community_detection_module/community_detection_online_module.cpp @@ -176,17 +176,35 @@ void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m algorithm.UpdateLabels(graph, modified_nodes, modified_relationships, deleted_nodes, deleted_relationships); for (const auto [node_id, label] : labels) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldCommunityId.data(), label); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldCommunityId.data(), label); + } catch (const std::exception &e) { + continue; + } } } else { const auto labels = algorithm.SetLabels(graph); for (const auto [node_id, label] : labels) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldCommunityId.data(), label); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldCommunityId.data(), label); + } catch (const std::exception &e) { + continue; + } } } From f4043058d945838af5e2d5efe1e5e9b7f829b05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Thu, 9 Nov 2023 02:26:47 +0100 Subject: [PATCH 07/17] Fix C API result returning --- .../betweenness_centrality_module.cpp | 12 +++++++++++- .../betweenness_centrality_online_module.cpp | 12 +++++++++++- .../biconnected_components_module.cpp | 16 ++++++++++++++-- cpp/bridges_module/bridges_module.cpp | 16 ++++++++++++++-- cpp/connectivity_module/connectivity_module.cpp | 12 +++++++++++- .../algorithms/balanced_cut_clustering.cu | 12 +++++++++++- .../algorithms/betweenness_centrality.cu | 12 +++++++++++- cpp/cugraph_module/algorithms/hits.cu | 12 +++++++++++- cpp/cugraph_module/algorithms/katz_centrality.cu | 12 +++++++++++- cpp/cugraph_module/algorithms/leiden.cu | 12 +++++++++++- cpp/cugraph_module/algorithms/louvain.cu | 12 +++++++++++- cpp/cugraph_module/algorithms/pagerank.cu | 12 +++++++++++- .../algorithms/personalized_pagerank.cu | 12 +++++++++++- .../algorithms/spectral_clustering.cu | 12 +++++++++++- cpp/cycles_module/cycles_module.cpp | 12 +++++++++++- .../degree_centrality_module.cpp | 14 ++++++++++++-- .../katz_centrality_module.cpp | 12 +++++++++++- .../katz_centrality_online_module.cpp | 12 +++++++++++- cpp/pagerank_module/pagerank_module.cpp | 2 ++ cpp/pagerank_module/pagerank_online_module.cpp | 13 +++++++++++-- cpp/refactor_module/algorithm/refactor.cpp | 11 ++++++++++- rust/rsmgp-sys/mgp/mg_procedure.h | 6 ++++++ 22 files changed, 234 insertions(+), 24 deletions(-) diff --git a/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp b/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp index dddd7aebf..86e2337fa 100644 --- a/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp +++ b/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp @@ -17,9 +17,19 @@ constexpr char const *kArgumentThreads = "threads"; void InsertBCRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double betweenness_centrality, const int node_id) { + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!vertex) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); mg_utility::InsertDoubleValueResult(record, kFieldBCScore, betweenness_centrality, memory); } diff --git a/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp b/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp index 7e18435f8..db48f57ed 100644 --- a/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp +++ b/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp @@ -35,9 +35,19 @@ bool ConnectedVia(std::uint64_t node_id, std::pair void InsertOnlineBCRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double bc_score) { + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!vertex) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); mg_utility::InsertDoubleValueResult(record, kFieldBCScore, bc_score, memory); } diff --git a/cpp/biconnected_components_module/biconnected_components_module.cpp b/cpp/biconnected_components_module/biconnected_components_module.cpp index 3b664e666..4edf793b2 100644 --- a/cpp/biconnected_components_module/biconnected_components_module.cpp +++ b/cpp/biconnected_components_module/biconnected_components_module.cpp @@ -13,13 +13,25 @@ const char *fieldNodeTo = "node_to"; void InsertBiconnectedComponentRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int bcc_id, const int edge_id, const int node_from_id, const int node_to_id) { + auto *node_from = + mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_from_id)}, memory); + auto *node_to = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_to_id)}, memory); + if (!node_from || !node_to) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); mg_utility::InsertIntValueResult(record, fieldBiconnectedComponentID, bcc_id, memory); // TODO: Implement edge getting function // mg_utility::InsertIntValueResult(record, fieldEdgeID, edge_id, memory); - mg_utility::InsertNodeValueResult(graph, record, fieldNodeFrom, node_from_id, memory); - mg_utility::InsertNodeValueResult(graph, record, fieldNodeTo, node_to_id, memory); + mg_utility::InsertNodeValueResult(record, fieldNodeFrom, node_from, memory); + mg_utility::InsertNodeValueResult(record, fieldNodeTo, node_to, memory); } void GetBiconnectedComponents(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { diff --git a/cpp/bridges_module/bridges_module.cpp b/cpp/bridges_module/bridges_module.cpp index 7416e8c38..277cf0f19 100644 --- a/cpp/bridges_module/bridges_module.cpp +++ b/cpp/bridges_module/bridges_module.cpp @@ -13,10 +13,22 @@ const char *k_field_node_to = "node_to"; void InsertBridgeRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_from_id, const std::uint64_t node_to_id) { + auto *node_from = + mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_from_id)}, memory); + auto *node_to = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_to_id)}, memory); + if (!node_from || !node_to) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, k_field_node_from, node_from_id, memory); - mg_utility::InsertNodeValueResult(graph, record, k_field_node_to, node_to_id, memory); + mg_utility::InsertNodeValueResult(record, k_field_node_from, node_from, memory); + mg_utility::InsertNodeValueResult(record, k_field_node_to, node_to, memory); } void GetBridges(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { diff --git a/cpp/connectivity_module/connectivity_module.cpp b/cpp/connectivity_module/connectivity_module.cpp index 207284ae1..50a10a6ce 100644 --- a/cpp/connectivity_module/connectivity_module.cpp +++ b/cpp/connectivity_module/connectivity_module.cpp @@ -13,9 +13,19 @@ constexpr char const *kFieldComponentId = "component_id"; void InsertWeaklyComponentResult(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int component_id, const int vertex_id) { + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(vertex_id)}, memory); + if (!vertex) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldVertex, vertex_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldVertex, vertex, memory); mg_utility::InsertIntValueResult(record, kFieldComponentId, component_id, memory); } diff --git a/cpp/cugraph_module/algorithms/balanced_cut_clustering.cu b/cpp/cugraph_module/algorithms/balanced_cut_clustering.cu index e8096e04d..f9167b166 100644 --- a/cpp/cugraph_module/algorithms/balanced_cut_clustering.cu +++ b/cpp/cugraph_module/algorithms/balanced_cut_clustering.cu @@ -38,8 +38,18 @@ constexpr char const *kDefaultWeightProperty = "weight"; void InsertBalancedCutResult(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, std::int64_t cluster) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertIntValueResult(record, kResultFieldCluster, cluster, memory); } diff --git a/cpp/cugraph_module/algorithms/betweenness_centrality.cu b/cpp/cugraph_module/algorithms/betweenness_centrality.cu index 42a54fb42..da66ca1e3 100644 --- a/cpp/cugraph_module/algorithms/betweenness_centrality.cu +++ b/cpp/cugraph_module/algorithms/betweenness_centrality.cu @@ -35,8 +35,18 @@ constexpr char const *kDefaultWeightProperty = "weight"; void InsertBetweennessRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double rank) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldBetweennessCentrality, rank, memory); } diff --git a/cpp/cugraph_module/algorithms/hits.cu b/cpp/cugraph_module/algorithms/hits.cu index a02863a01..0dfe1b7e5 100644 --- a/cpp/cugraph_module/algorithms/hits.cu +++ b/cpp/cugraph_module/algorithms/hits.cu @@ -33,8 +33,18 @@ constexpr char const *kResultFieldAuthoritiesScore = "authorities"; void InsertHITSRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double hubs, double authorities) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldHubScore, hubs, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldAuthoritiesScore, authorities, memory); } diff --git a/cpp/cugraph_module/algorithms/katz_centrality.cu b/cpp/cugraph_module/algorithms/katz_centrality.cu index b319693bb..6ca143069 100644 --- a/cpp/cugraph_module/algorithms/katz_centrality.cu +++ b/cpp/cugraph_module/algorithms/katz_centrality.cu @@ -34,8 +34,18 @@ constexpr char const *kResultFieldKatzCentrality = "katz_centrality"; void InsertKatzCentralityRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double rank) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldKatzCentrality, rank, memory); } diff --git a/cpp/cugraph_module/algorithms/leiden.cu b/cpp/cugraph_module/algorithms/leiden.cu index b49d38e99..dcca27875 100644 --- a/cpp/cugraph_module/algorithms/leiden.cu +++ b/cpp/cugraph_module/algorithms/leiden.cu @@ -30,8 +30,18 @@ constexpr char const *kResultFieldPartition = "partition"; void InsertLeidenRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, std::int64_t partition) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertIntValueResult(record, kResultFieldPartition, partition, memory); } diff --git a/cpp/cugraph_module/algorithms/louvain.cu b/cpp/cugraph_module/algorithms/louvain.cu index df67d9751..d55575263 100644 --- a/cpp/cugraph_module/algorithms/louvain.cu +++ b/cpp/cugraph_module/algorithms/louvain.cu @@ -30,8 +30,18 @@ constexpr char const *kResultFieldPartition = "partition"; void InsertLouvainRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, std::int64_t partition) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertIntValueResult(record, kResultFieldPartition, partition, memory); } diff --git a/cpp/cugraph_module/algorithms/pagerank.cu b/cpp/cugraph_module/algorithms/pagerank.cu index 5f5106514..42686c34e 100644 --- a/cpp/cugraph_module/algorithms/pagerank.cu +++ b/cpp/cugraph_module/algorithms/pagerank.cu @@ -35,8 +35,18 @@ constexpr char const *kDefaultWeightProperty = "weight"; void InsertPagerankRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double rank) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldPageRank, rank, memory); } diff --git a/cpp/cugraph_module/algorithms/personalized_pagerank.cu b/cpp/cugraph_module/algorithms/personalized_pagerank.cu index 1102d947b..021690da8 100644 --- a/cpp/cugraph_module/algorithms/personalized_pagerank.cu +++ b/cpp/cugraph_module/algorithms/personalized_pagerank.cu @@ -37,8 +37,18 @@ constexpr char const *kDefaultWeightProperty = "weight"; void InsertPersonalizedPagerankRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double rank) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kResultFieldPageRank, rank, memory); } diff --git a/cpp/cugraph_module/algorithms/spectral_clustering.cu b/cpp/cugraph_module/algorithms/spectral_clustering.cu index 5a6613daa..5caa35ca4 100644 --- a/cpp/cugraph_module/algorithms/spectral_clustering.cu +++ b/cpp/cugraph_module/algorithms/spectral_clustering.cu @@ -38,8 +38,18 @@ constexpr char const *kDefaultWeightProperty = "weight"; void InsertSpectralClusteringResult(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, std::int64_t cluster) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); - mg_utility::InsertNodeValueResult(graph, record, kResultFieldNode, node_id, memory); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kResultFieldNode, node, memory); mg_utility::InsertIntValueResult(record, kResultFieldCluster, cluster, memory); } diff --git a/cpp/cycles_module/cycles_module.cpp b/cpp/cycles_module/cycles_module.cpp index 458d203e2..d11224eda 100644 --- a/cpp/cycles_module/cycles_module.cpp +++ b/cpp/cycles_module/cycles_module.cpp @@ -11,10 +11,20 @@ constexpr char const *kFieldNode = "node"; void InsertCycleRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int cycle_id, const int node_id) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); mg_utility::InsertIntValueResult(record, kFieldCycleId, cycle_id, memory); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); } void GetCycles(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { diff --git a/cpp/degree_centrality_module/degree_centrality_module.cpp b/cpp/degree_centrality_module/degree_centrality_module.cpp index ef5189499..73b99e017 100644 --- a/cpp/degree_centrality_module/degree_centrality_module.cpp +++ b/cpp/degree_centrality_module/degree_centrality_module.cpp @@ -19,11 +19,21 @@ const char *kAlgorithmUndirected = "undirected"; const char *kAlgorithmOut = "out"; const char *kAlgorithmIn = "in"; -void InsertDegreeCentralityRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, std::uint64_t node, +void InsertDegreeCentralityRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, std::uint64_t node_id, double degree) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldDegree, degree, memory); } diff --git a/cpp/katz_centrality_module/katz_centrality_module.cpp b/cpp/katz_centrality_module/katz_centrality_module.cpp index 763352bf2..f010fb5bc 100644 --- a/cpp/katz_centrality_module/katz_centrality_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_module.cpp @@ -14,9 +14,19 @@ constexpr char const *kFieldRank = "rank"; void InsertKatzRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double katz_centrality, const int node_id) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldRank, katz_centrality, memory); } diff --git a/cpp/katz_centrality_module/katz_centrality_online_module.cpp b/cpp/katz_centrality_module/katz_centrality_online_module.cpp index 5802b034e..17d0e6253 100644 --- a/cpp/katz_centrality_module/katz_centrality_online_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_online_module.cpp @@ -22,9 +22,19 @@ constexpr char const *kArgumentDeletedEdges = "deleted_edges"; void InsertKatzRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double katz_centrality, const int node_id) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldRank, katz_centrality, memory); } diff --git a/cpp/pagerank_module/pagerank_module.cpp b/cpp/pagerank_module/pagerank_module.cpp index 49c7429a8..8cc49de2b 100644 --- a/cpp/pagerank_module/pagerank_module.cpp +++ b/cpp/pagerank_module/pagerank_module.cpp @@ -25,6 +25,8 @@ void InsertPagerankRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memo } auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); mg_utility::InsertDoubleValueResult(record, kFieldRank, rank, memory); } diff --git a/cpp/pagerank_module/pagerank_online_module.cpp b/cpp/pagerank_module/pagerank_online_module.cpp index 054efd50b..46bfb18ab 100644 --- a/cpp/pagerank_module/pagerank_online_module.cpp +++ b/cpp/pagerank_module/pagerank_online_module.cpp @@ -21,9 +21,18 @@ constexpr char const *kArgumentDeletedEdges = "deleted_edges"; void InsertPageRankRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, const double rank) { - auto *record = mgp::result_new_record(result); + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } - mg_utility::InsertNodeValueResult(graph, record, kFieldNode, node_id, memory); + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); + + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldRank, rank, memory); } diff --git a/cpp/refactor_module/algorithm/refactor.cpp b/cpp/refactor_module/algorithm/refactor.cpp index 7c976a30c..37717bc99 100644 --- a/cpp/refactor_module/algorithm/refactor.cpp +++ b/cpp/refactor_module/algorithm/refactor.cpp @@ -104,10 +104,19 @@ void Refactor::RenameNodeProperty(mgp_list *args, mgp_graph *memgraph_graph, mgp void Refactor::InsertCloneNodesRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int cycle_id, const int node_id) { + auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!node) { + if (mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return; + } + auto *record = mgp::result_new_record(result); + if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); mg_utility::InsertIntValueResult(record, std::string(kResultClonedNodeId).c_str(), cycle_id, memory); - mg_utility::InsertNodeValueResult(graph, record, std::string(kResultNewNode).c_str(), node_id, memory); + mg_utility::InsertNodeValueResult(record, std::string(kResultNewNode).c_str(), node, memory); mg_utility::InsertStringValueResult(record, std::string(kResultCloneNodeError).c_str(), "", memory); } diff --git a/rust/rsmgp-sys/mgp/mg_procedure.h b/rust/rsmgp-sys/mgp/mg_procedure.h index ca24b737d..b1d4e323a 100644 --- a/rust/rsmgp-sys/mgp/mg_procedure.h +++ b/rust/rsmgp-sys/mgp/mg_procedure.h @@ -814,6 +814,12 @@ enum mgp_error mgp_graph_get_vertex_by_id(struct mgp_graph *g, struct mgp_vertex /// Current implementation always returns without errors. enum mgp_error mgp_graph_is_mutable(struct mgp_graph *graph, int *result); +/// Result is non-zero if the graph is in transactional storage mode. +/// If a graph is not in transactional mode (i.e. analytical mode), then vertices and edges can be missing +/// because changes from other transactions are visible. +/// Current implementation always returns without errors. +enum mgp_error mgp_graph_is_transactional(struct mgp_graph *graph, int *result); + /// Add a new vertex to the graph. /// Resulting vertex must be freed using mgp_vertex_destroy. /// Return MGP_ERROR_IMMUTABLE_OBJECT if `graph` is immutable. From 57e5909329b5eeae128b925e46d78966afe4cbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Fri, 10 Nov 2023 02:37:26 +0100 Subject: [PATCH 08/17] Add remaining deletion checks in the C++ API --- .../katz_centrality_online_module.cpp | 30 +++++++++++++++---- .../pagerank_online_module.cpp | 15 ++++++++-- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/cpp/katz_centrality_module/katz_centrality_online_module.cpp b/cpp/katz_centrality_module/katz_centrality_online_module.cpp index 17d0e6253..cd892d3ea 100644 --- a/cpp/katz_centrality_module/katz_centrality_online_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_online_module.cpp @@ -90,9 +90,18 @@ void UpdateKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result katz_centralities = katz_alg::SetKatz(*legacy_graph); for (auto &[node_id, centrality] : katz_centralities) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldRank, centrality); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldRank, centrality); + } catch (const std::exception &e) { + continue; + } } return; @@ -134,9 +143,18 @@ void UpdateKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result deleted_nodes, deleted_relationships); for (auto &[node_id, centrality] : katz_centralities) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldRank, centrality); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldRank, centrality); + } catch (const std::exception &e) { + continue; + } } } catch (const std::exception &e) { mgp::result_set_error_msg(result, e.what()); diff --git a/cpp/pagerank_module/pagerank_online_module.cpp b/cpp/pagerank_module/pagerank_online_module.cpp index 46bfb18ab..f522a3beb 100644 --- a/cpp/pagerank_module/pagerank_online_module.cpp +++ b/cpp/pagerank_module/pagerank_online_module.cpp @@ -120,9 +120,18 @@ void OnlinePageRankUpdate(mgp_list *args, mgp_graph *memgraph_graph, mgp_result } for (auto const &[node_id, rank] : pageranks) { - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); - record.Insert(kFieldRank, rank); + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + // Otherwise: + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldRank, rank); + } catch (const std::exception &e) { + continue; + } } } catch (const std::exception &e) { mgp::result_set_error_msg(result, e.what()); From 507aec0eab1b3772fd6e4c96a855612d5a4fb3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Sat, 25 Nov 2023 17:13:44 +0100 Subject: [PATCH 09/17] Add review suggestions --- cpp/mg_utility/mg_graph.hpp | 5 +++-- cpp/pagerank_module/pagerank_module.cpp | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/mg_utility/mg_graph.hpp b/cpp/mg_utility/mg_graph.hpp index 3ba665e3e..67a51a735 100644 --- a/cpp/mg_utility/mg_graph.hpp +++ b/cpp/mg_utility/mg_graph.hpp @@ -326,13 +326,14 @@ class Graph : public GraphView { /// @param node_id Memgraphs's inner ID /// std::optional GetInnerNodeIdOpt(std::uint64_t memgraph_id) const override { - if (memgraph_to_inner_id_.find(memgraph_id) == memgraph_to_inner_id_.end()) { + auto maybe_found = memgraph_to_inner_edge_id_.find(memgraph_id); + if (maybe_found == memgraph_to_inner_edge_id_.end()) { if (IsTransactional()) { throw mg_exception::InvalidIDException(); } return std::nullopt; } - return memgraph_to_inner_id_.at(memgraph_id); + return maybe_found->second; } /// diff --git a/cpp/pagerank_module/pagerank_module.cpp b/cpp/pagerank_module/pagerank_module.cpp index 8cc49de2b..6a58f8e10 100644 --- a/cpp/pagerank_module/pagerank_module.cpp +++ b/cpp/pagerank_module/pagerank_module.cpp @@ -1,6 +1,4 @@ -#include #include -#include #include "algorithm/pagerank.hpp" From a8106dc8f24f77106482d58b14427b3f976bc545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Mon, 27 Nov 2023 11:02:54 +0100 Subject: [PATCH 10/17] Add review comments --- .../community_detection_online_module.cpp | 16 ++++++++-------- .../katz_centrality_online_module.cpp | 8 ++++---- cpp/mg_utility/mg_graph.hpp | 14 +++++++------- cpp/mg_utility/mg_utils.hpp | 3 +-- cpp/pagerank_module/pagerank_online_module.cpp | 4 ++-- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/cpp/community_detection_module/community_detection_online_module.cpp b/cpp/community_detection_module/community_detection_online_module.cpp index 3d41831d3..76b1b6a89 100644 --- a/cpp/community_detection_module/community_detection_online_module.cpp +++ b/cpp/community_detection_module/community_detection_online_module.cpp @@ -81,11 +81,11 @@ void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode.data(), node); record.Insert(kFieldCommunityId.data(), label); } catch (const std::exception &e) { continue; @@ -110,11 +110,11 @@ void Get(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo // Previously-computed communities may contain nodes since deleted try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode.data(), node); record.Insert(kFieldCommunityId.data(), label); } catch (const std::exception &e) { continue; @@ -179,11 +179,11 @@ void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode.data(), node); record.Insert(kFieldCommunityId.data(), label); } catch (const std::exception &e) { continue; @@ -196,11 +196,11 @@ void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode.data(), node); record.Insert(kFieldCommunityId.data(), label); } catch (const std::exception &e) { continue; diff --git a/cpp/katz_centrality_module/katz_centrality_online_module.cpp b/cpp/katz_centrality_module/katz_centrality_online_module.cpp index cd892d3ea..97f203ad6 100644 --- a/cpp/katz_centrality_module/katz_centrality_online_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_online_module.cpp @@ -93,11 +93,11 @@ void UpdateKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode, node); record.Insert(kFieldRank, centrality); } catch (const std::exception &e) { continue; @@ -146,11 +146,11 @@ void UpdateKatzCentrality(mgp_list *args, mgp_graph *memgraph_graph, mgp_result // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode, node); record.Insert(kFieldRank, centrality); } catch (const std::exception &e) { continue; diff --git a/cpp/mg_utility/mg_graph.hpp b/cpp/mg_utility/mg_graph.hpp index 67a51a735..fe82e9075 100644 --- a/cpp/mg_utility/mg_graph.hpp +++ b/cpp/mg_utility/mg_graph.hpp @@ -326,14 +326,14 @@ class Graph : public GraphView { /// @param node_id Memgraphs's inner ID /// std::optional GetInnerNodeIdOpt(std::uint64_t memgraph_id) const override { - auto maybe_found = memgraph_to_inner_edge_id_.find(memgraph_id); - if (maybe_found == memgraph_to_inner_edge_id_.end()) { - if (IsTransactional()) { - throw mg_exception::InvalidIDException(); - } - return std::nullopt; + auto it = memgraph_to_inner_edge_id_.find(memgraph_id); + if (it != memgraph_to_inner_edge_id_.end()) { + return it->second; + } + if (IsTransactional()) { + throw mg_exception::InvalidIDException(); } - return maybe_found->second; + return std::nullopt; } /// diff --git a/cpp/mg_utility/mg_utils.hpp b/cpp/mg_utility/mg_utils.hpp index d214326c5..02b0dc61e 100644 --- a/cpp/mg_utility/mg_utils.hpp +++ b/cpp/mg_utility/mg_utils.hpp @@ -119,8 +119,7 @@ std::unique_ptr> GetGraphView(mgp_graph *memgraph_graph, const char *weight_property = nullptr, double default_weight = 1.0) { auto graph = std::make_unique>(); - bool isTransactionalStorage = mgp::graph_is_transactional(memgraph_graph); - graph->SetIsTransactional(isTransactionalStorage); + graph->SetIsTransactional(mgp::graph_is_transactional(memgraph_graph)); /// /// Mapping Memgraph in-memory vertices into the graph view diff --git a/cpp/pagerank_module/pagerank_online_module.cpp b/cpp/pagerank_module/pagerank_online_module.cpp index f522a3beb..1e96d5497 100644 --- a/cpp/pagerank_module/pagerank_online_module.cpp +++ b/cpp/pagerank_module/pagerank_online_module.cpp @@ -123,11 +123,11 @@ void OnlinePageRankUpdate(mgp_list *args, mgp_graph *memgraph_graph, mgp_result // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist try { // If so, throw an exception: - const auto maybe_node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); // Otherwise: auto record = record_factory.NewRecord(); - record.Insert(kFieldNode, graph.GetNodeById(mgp::Id::FromUint(node_id))); + record.Insert(kFieldNode, node); record.Insert(kFieldRank, rank); } catch (const std::exception &e) { continue; From 23cb924073068ec6491528c1e1b2fccce885619f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Mon, 27 Nov 2023 11:03:03 +0100 Subject: [PATCH 11/17] Fix build --- cpp/refactor_module/algorithm/refactor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/refactor_module/algorithm/refactor.cpp b/cpp/refactor_module/algorithm/refactor.cpp index bb29f794e..762717800 100644 --- a/cpp/refactor_module/algorithm/refactor.cpp +++ b/cpp/refactor_module/algorithm/refactor.cpp @@ -546,7 +546,7 @@ void Refactor::RenameTypeProperty(mgp_list *args, mgp_graph *memgraph_graph, mgp const auto rels{arguments[2].ValueList()}; int64_t rels_changed{0}; - for (auto &rel_value : rels) { + for (auto rel_value : rels) { auto rel = rel_value.ValueRelationship(); const auto prop_value = rel.GetProperty(old_name); /*since there is no bug(prop map cant have null values), it is faster to just check isNull @@ -822,7 +822,7 @@ void Refactor::RenameType(mgp_list *args, mgp_graph *memgraph_graph, mgp_result auto graph{mgp::Graph(memgraph_graph)}; int64_t rels_changed{0}; - for (auto &relationship_value : relationships) { + for (auto relationship_value : relationships) { auto relationship{relationship_value.ValueRelationship()}; if (relationship.Type() == old_type) { graph.ChangeType(relationship, new_type); From c67d1613af47e1500f9967610ec977622c8b4819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 15:12:20 +0100 Subject: [PATCH 12/17] Get checks to use latest memgraph --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c4967e553..6f9fbf36d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ env: MEMGRAPH_PORT: 7687 NEO4J_PORT: 7688 NEO4J_CONTAINER: "neo4j_test" - OFFICIAL: "true" + OFFICIAL: "false" on: [pull_request, workflow_dispatch] @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: True env: - MEMGRAPH_VERSION: 2.12.1 + MEMGRAPH_VERSION: 2.13.1 strategy: matrix: architecture: ["amd64", "arm64"] From 05e08b99003b1a12df9b53634b87566f3e097b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 15:14:54 +0100 Subject: [PATCH 13/17] Fix version --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f9fbf36d..4454d481d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: True env: - MEMGRAPH_VERSION: 2.13.1 + MEMGRAPH_VERSION: 2.13 strategy: matrix: architecture: ["amd64", "arm64"] From bc70a80c608fb159a7a28f0e2f81d9f3ded0503e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 15:47:03 +0100 Subject: [PATCH 14/17] Update submodule to current master --- cpp/memgraph | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/memgraph b/cpp/memgraph index da9d6dd8e..eceed274d 160000 --- a/cpp/memgraph +++ b/cpp/memgraph @@ -1 +1 @@ -Subproject commit da9d6dd8e13db91e1c6657270da0a612c4befab4 +Subproject commit eceed274d983d6f135189d945c407b30b6e506a6 From 508425a8781c120e3972cded98bf2195ebaad98d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 18:03:42 +0100 Subject: [PATCH 15/17] Fix node existence check --- cpp/mg_utility/mg_graph.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/mg_utility/mg_graph.hpp b/cpp/mg_utility/mg_graph.hpp index fe82e9075..64e1686ec 100644 --- a/cpp/mg_utility/mg_graph.hpp +++ b/cpp/mg_utility/mg_graph.hpp @@ -326,8 +326,8 @@ class Graph : public GraphView { /// @param node_id Memgraphs's inner ID /// std::optional GetInnerNodeIdOpt(std::uint64_t memgraph_id) const override { - auto it = memgraph_to_inner_edge_id_.find(memgraph_id); - if (it != memgraph_to_inner_edge_id_.end()) { + auto it = memgraph_to_inner_id_.find(memgraph_id); + if (it != memgraph_to_inner_id_.end()) { return it->second; } if (IsTransactional()) { From e8180fcda6da4360f45912620aed18b5a1bd4779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 19:28:39 +0100 Subject: [PATCH 16/17] Extract duplicate code into a method --- .../betweenness_centrality_module.cpp | 12 +++--------- .../betweenness_centrality_online_module.cpp | 12 +++--------- .../biconnected_components_module.cpp | 13 +++---------- cpp/bridges_module/bridges_module.cpp | 13 +++---------- .../community_detection_module.cpp | 10 ++-------- cpp/connectivity_module/connectivity_module.cpp | 10 ++-------- cpp/cycles_module/cycles_module.cpp | 10 ++-------- .../degree_centrality_module.cpp | 10 ++-------- .../katz_centrality_module.cpp | 10 ++-------- .../katz_centrality_online_module.cpp | 10 ++-------- cpp/mg_utility/mg_utils.hpp | 16 ++++++++++++++++ 11 files changed, 40 insertions(+), 86 deletions(-) diff --git a/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp b/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp index 86e2337fa..f188bf76e 100644 --- a/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp +++ b/cpp/betweenness_centrality_module/betweenness_centrality_module.cpp @@ -17,19 +17,13 @@ constexpr char const *kArgumentThreads = "threads"; void InsertBCRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double betweenness_centrality, const int node_id) { - auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!vertex) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldBCScore, betweenness_centrality, memory); } diff --git a/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp b/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp index db48f57ed..9ca23e654 100644 --- a/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp +++ b/cpp/betweenness_centrality_module/betweenness_centrality_online_module.cpp @@ -35,19 +35,13 @@ bool ConnectedVia(std::uint64_t node_id, std::pair void InsertOnlineBCRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, double bc_score) { - auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!vertex) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); - mg_utility::InsertNodeValueResult(record, kFieldNode, vertex, memory); + mg_utility::InsertNodeValueResult(record, kFieldNode, node, memory); mg_utility::InsertDoubleValueResult(record, kFieldBCScore, bc_score, memory); } diff --git a/cpp/biconnected_components_module/biconnected_components_module.cpp b/cpp/biconnected_components_module/biconnected_components_module.cpp index 4edf793b2..ca9ba6bb5 100644 --- a/cpp/biconnected_components_module/biconnected_components_module.cpp +++ b/cpp/biconnected_components_module/biconnected_components_module.cpp @@ -13,16 +13,9 @@ const char *fieldNodeTo = "node_to"; void InsertBiconnectedComponentRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int bcc_id, const int edge_id, const int node_from_id, const int node_to_id) { - auto *node_from = - mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_from_id)}, memory); - auto *node_to = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_to_id)}, memory); - if (!node_from || !node_to) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node_from = mg_utility::GetNodeForInsertion(node_from_id, graph, memory); + auto *node_to = mg_utility::GetNodeForInsertion(node_to_id, graph, memory); + if (!node_from || !node_to) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/bridges_module/bridges_module.cpp b/cpp/bridges_module/bridges_module.cpp index 277cf0f19..50c113c36 100644 --- a/cpp/bridges_module/bridges_module.cpp +++ b/cpp/bridges_module/bridges_module.cpp @@ -13,16 +13,9 @@ const char *k_field_node_to = "node_to"; void InsertBridgeRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_from_id, const std::uint64_t node_to_id) { - auto *node_from = - mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_from_id)}, memory); - auto *node_to = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_to_id)}, memory); - if (!node_from || !node_to) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node_from = mg_utility::GetNodeForInsertion(node_from_id, graph, memory); + auto *node_to = mg_utility::GetNodeForInsertion(node_to_id, graph, memory); + if (!node_from || !node_to) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/community_detection_module/community_detection_module.cpp b/cpp/community_detection_module/community_detection_module.cpp index f497d5eb3..ffb5d5875 100644 --- a/cpp/community_detection_module/community_detection_module.cpp +++ b/cpp/community_detection_module/community_detection_module.cpp @@ -25,14 +25,8 @@ const double kDefaultWeight = 1.0; void InsertLouvainRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const std::uint64_t node_id, const std::uint64_t community) { - auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!vertex) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *vertex = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!vertex) return; mgp_result_record *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/connectivity_module/connectivity_module.cpp b/cpp/connectivity_module/connectivity_module.cpp index 50a10a6ce..3c7ba608c 100644 --- a/cpp/connectivity_module/connectivity_module.cpp +++ b/cpp/connectivity_module/connectivity_module.cpp @@ -13,14 +13,8 @@ constexpr char const *kFieldComponentId = "component_id"; void InsertWeaklyComponentResult(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int component_id, const int vertex_id) { - auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(vertex_id)}, memory); - if (!vertex) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *vertex = mg_utility::GetNodeForInsertion(vertex_id, graph, memory); + if (!vertex) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/cycles_module/cycles_module.cpp b/cpp/cycles_module/cycles_module.cpp index d11224eda..b50e9cd5c 100644 --- a/cpp/cycles_module/cycles_module.cpp +++ b/cpp/cycles_module/cycles_module.cpp @@ -11,14 +11,8 @@ constexpr char const *kFieldNode = "node"; void InsertCycleRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const int cycle_id, const int node_id) { - auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!node) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/degree_centrality_module/degree_centrality_module.cpp b/cpp/degree_centrality_module/degree_centrality_module.cpp index 73b99e017..a10f75be4 100644 --- a/cpp/degree_centrality_module/degree_centrality_module.cpp +++ b/cpp/degree_centrality_module/degree_centrality_module.cpp @@ -21,14 +21,8 @@ const char *kAlgorithmIn = "in"; void InsertDegreeCentralityRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, std::uint64_t node_id, double degree) { - auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!node) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/katz_centrality_module/katz_centrality_module.cpp b/cpp/katz_centrality_module/katz_centrality_module.cpp index f010fb5bc..732e130b7 100644 --- a/cpp/katz_centrality_module/katz_centrality_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_module.cpp @@ -14,14 +14,8 @@ constexpr char const *kFieldRank = "rank"; void InsertKatzRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double katz_centrality, const int node_id) { - auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!node) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/katz_centrality_module/katz_centrality_online_module.cpp b/cpp/katz_centrality_module/katz_centrality_online_module.cpp index 97f203ad6..51b69e168 100644 --- a/cpp/katz_centrality_module/katz_centrality_online_module.cpp +++ b/cpp/katz_centrality_module/katz_centrality_online_module.cpp @@ -22,14 +22,8 @@ constexpr char const *kArgumentDeletedEdges = "deleted_edges"; void InsertKatzRecord(mgp_graph *graph, mgp_result *result, mgp_memory *memory, const double katz_centrality, const int node_id) { - auto *node = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); - if (!node) { - if (mgp::graph_is_transactional(graph)) { - throw mg_exception::InvalidIDException(); - } - // In IN_MEMORY_ANALYTICAL mode, vertices/edges may be erased by parallel transactions. - return; - } + auto *node = mg_utility::GetNodeForInsertion(node_id, graph, memory); + if (!node) return; auto *record = mgp::result_new_record(result); if (record == nullptr) throw mg_exception::NotEnoughMemoryException(); diff --git a/cpp/mg_utility/mg_utils.hpp b/cpp/mg_utility/mg_utils.hpp index 02b0dc61e..7f81e2cc8 100644 --- a/cpp/mg_utility/mg_utils.hpp +++ b/cpp/mg_utility/mg_utils.hpp @@ -280,6 +280,22 @@ void InsertNodeValueResult(mgp_result_record *record, const char *field_name, mg InsertRecord(record, field_name, value); } +/// @brief Retrieves a node with the given ID to be fed into InsertNodeValueResult. If no node is found, the behavior’s +/// up to the storage mode: +/// * In transactional (ACID-compliant) storage modes one can expect vertices to not be erased -> InvalidIDException +/// * In IN_MEMORY_ANALYTICAL mode, vertices might be erased by parallel transactions -> nullptr +/// @param node_id +/// @param graph +/// @param memory +/// @return +mgp_vertex *GetNodeForInsertion(const int node_id, mgp_graph *graph, mgp_memory *memory) { + auto *vertex = mgp::graph_get_vertex_by_id(graph, mgp_vertex_id{.as_int = static_cast(node_id)}, memory); + if (!vertex && mgp::graph_is_transactional(graph)) { + throw mg_exception::InvalidIDException(); + } + return vertex; +} + /// Inserts a node with its ID node_id to create a vertex and insert /// the node to the field field_name of the record mgp_result_record record. /// Returns true is insert is successful, false otherwise From 1cd20ac7f2d6a36f52aed1de04a1056c164e3375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Pu=C5=A1i=C4=87?= Date: Tue, 5 Dec 2023 19:42:11 +0100 Subject: [PATCH 17/17] Remove duplication in community_detection_online --- .../community_detection_online_module.cpp | 54 +++++++------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/cpp/community_detection_module/community_detection_online_module.cpp b/cpp/community_detection_module/community_detection_online_module.cpp index 76b1b6a89..3d35031ad 100644 --- a/cpp/community_detection_module/community_detection_online_module.cpp +++ b/cpp/community_detection_module/community_detection_online_module.cpp @@ -51,6 +51,21 @@ auto saved_directedness = kDefaultDirected; auto saved_weightedness = kDefaultWeighted; std::string saved_weight_property = kDefaultWeightProperty.data(); +void WriteResults(const std::uint64_t node_id, const std::int64_t label, const mgp::Graph &graph, + const mgp::RecordFactory &record_factory) { + // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist + try { + // If so, throw an exception: + const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); + + auto record = record_factory.NewRecord(); + record.Insert(kFieldNode.data(), node); + record.Insert(kFieldCommunityId.data(), label); + } catch (const std::exception &) { + // If no node has been found, it’s enough to not write the result + } +} + void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { try { mgp::MemoryDispatcherGuard guard{memory}; @@ -78,18 +93,7 @@ void Set(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memo ::initialized = true; for (const auto [node_id, label] : labels) { - // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist - try { - // If so, throw an exception: - const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); - - // Otherwise: - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), node); - record.Insert(kFieldCommunityId.data(), label); - } catch (const std::exception &e) { - continue; - } + WriteResults(node_id, label, graph, record_factory); } } catch (const std::exception &e) { return; @@ -176,35 +180,13 @@ void Update(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_m algorithm.UpdateLabels(graph, modified_nodes, modified_relationships, deleted_nodes, deleted_relationships); for (const auto [node_id, label] : labels) { - // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist - try { - // If so, throw an exception: - const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); - - // Otherwise: - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), node); - record.Insert(kFieldCommunityId.data(), label); - } catch (const std::exception &e) { - continue; - } + WriteResults(node_id, label, graph, record_factory); } } else { const auto labels = algorithm.SetLabels(graph); for (const auto [node_id, label] : labels) { - // As IN_MEMORY_ANALYTICAL doesn’t offer ACID guarantees, check if the graph elements in the result exist - try { - // If so, throw an exception: - const auto node = graph.GetNodeById(mgp::Id::FromUint(node_id)); - - // Otherwise: - auto record = record_factory.NewRecord(); - record.Insert(kFieldNode.data(), node); - record.Insert(kFieldCommunityId.data(), label); - } catch (const std::exception &e) { - continue; - } + WriteResults(node_id, label, graph, record_factory); } }