From 79f49db6abb83b678b14406d9349f545266880a3 Mon Sep 17 00:00:00 2001 From: Matija Date: Wed, 11 Oct 2023 18:19:28 +0200 Subject: [PATCH] Implement algo.cover --- cpp/algo_module/algo_module.cpp | 3 +++ cpp/algo_module/algorithm/algo.cpp | 27 +++++++++++++++++++++++++++ cpp/algo_module/algorithm/algo.hpp | 11 ++++++++++- e2e/algo_test/test_cover1/input.cyp | 1 + e2e/algo_test/test_cover1/test.yml | 9 +++++++++ e2e/algo_test/test_cover2/input.cyp | 1 + e2e/algo_test/test_cover2/test.yml | 6 ++++++ e2e/algo_test/test_cover3/input.cyp | 1 + e2e/algo_test/test_cover3/test.yml | 7 +++++++ 9 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 e2e/algo_test/test_cover1/input.cyp create mode 100644 e2e/algo_test/test_cover1/test.yml create mode 100644 e2e/algo_test/test_cover2/input.cyp create mode 100644 e2e/algo_test/test_cover2/test.yml create mode 100644 e2e/algo_test/test_cover3/input.cyp create mode 100644 e2e/algo_test/test_cover3/test.yml diff --git a/cpp/algo_module/algo_module.cpp b/cpp/algo_module/algo_module.cpp index d0f79a673..abdabfb4d 100644 --- a/cpp/algo_module/algo_module.cpp +++ b/cpp/algo_module/algo_module.cpp @@ -5,6 +5,9 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { try { mgp::MemoryDispatcherGuard guard{memory}; + AddProcedure(Algo::Cover, std::string(Algo::kProcedureCover).c_str(), mgp::ProcedureType::Read, + {mgp::Parameter(std::string(Algo::kCoverArg1).c_str(), {mgp::Type::List, mgp::Type::Node})}, + {mgp::Return(std::string(Algo::kCoverRet1).c_str(), mgp::Type::Relationship)}, module, memory); } catch (const std::exception &e) { return 1; diff --git a/cpp/algo_module/algorithm/algo.cpp b/cpp/algo_module/algorithm/algo.cpp index c42320173..082af992a 100644 --- a/cpp/algo_module/algorithm/algo.cpp +++ b/cpp/algo_module/algorithm/algo.cpp @@ -1 +1,28 @@ #include "algo.hpp" + +void Algo::Cover(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { + mgp::MemoryDispatcherGuard guard{memory}; + const auto arguments = mgp::List(args); + const auto record_factory = mgp::RecordFactory(result); + try { + auto list_nodes = arguments[0].ValueList(); + std::unordered_set nodes; + for (const auto elem : list_nodes) { + auto node = elem.ValueNode(); + nodes.insert(node); + } + + for (auto node : nodes) { + for (auto rel : node.OutRelationships()) { + if (nodes.find(rel.To()) != nodes.end()) { + auto record = record_factory.NewRecord(); + record.Insert(std::string(kCoverRet1).c_str(), rel); + } + } + } + + } catch (const std::exception &e) { + record_factory.SetErrorMessage(e.what()); + return; + } +} \ No newline at end of file diff --git a/cpp/algo_module/algorithm/algo.hpp b/cpp/algo_module/algorithm/algo.hpp index 04d30b4d9..62a73524a 100644 --- a/cpp/algo_module/algorithm/algo.hpp +++ b/cpp/algo_module/algorithm/algo.hpp @@ -1,5 +1,14 @@ #pragma once #include +#include -namespace Algo {} // namespace Algo +namespace Algo { + +/* cover constants */ +constexpr std::string_view kProcedureCover = "cover"; +constexpr std::string_view kCoverArg1 = "nodes"; +constexpr std::string_view kCoverRet1 = "rel"; + +void Cover(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory); +} // namespace Algo diff --git a/e2e/algo_test/test_cover1/input.cyp b/e2e/algo_test/test_cover1/input.cyp new file mode 100644 index 000000000..da76510fc --- /dev/null +++ b/e2e/algo_test/test_cover1/input.cyp @@ -0,0 +1 @@ +CREATE (d:Dog),(h:Human),(ho:House), (d)-[l:LOVES]->(h),(h)-[:LIVES_IN]->(ho),(d)-[se:SELF_REL]->(d) diff --git a/e2e/algo_test/test_cover1/test.yml b/e2e/algo_test/test_cover1/test.yml new file mode 100644 index 000000000..c0b4da05b --- /dev/null +++ b/e2e/algo_test/test_cover1/test.yml @@ -0,0 +1,9 @@ +query: > + MATCH (n) + WITH collect(n) AS list + CALL algo.cover(list) YIELD rel RETURN rel; + +output: + - rel: {'label': 'LIVES_IN','properties': {}} + - rel: {'label': 'LOVES','properties': {}} + - rel: {'label': 'SELF_REL','properties': {}} diff --git a/e2e/algo_test/test_cover2/input.cyp b/e2e/algo_test/test_cover2/input.cyp new file mode 100644 index 000000000..da76510fc --- /dev/null +++ b/e2e/algo_test/test_cover2/input.cyp @@ -0,0 +1 @@ +CREATE (d:Dog),(h:Human),(ho:House), (d)-[l:LOVES]->(h),(h)-[:LIVES_IN]->(ho),(d)-[se:SELF_REL]->(d) diff --git a/e2e/algo_test/test_cover2/test.yml b/e2e/algo_test/test_cover2/test.yml new file mode 100644 index 000000000..3eadf6b85 --- /dev/null +++ b/e2e/algo_test/test_cover2/test.yml @@ -0,0 +1,6 @@ +query: > + MATCH (d:Dog) + CALL algo.cover([d]) YIELD rel RETURN rel; + +output: + - rel: {'label': 'SELF_REL','properties': {}} diff --git a/e2e/algo_test/test_cover3/input.cyp b/e2e/algo_test/test_cover3/input.cyp new file mode 100644 index 000000000..4a6bdaf32 --- /dev/null +++ b/e2e/algo_test/test_cover3/input.cyp @@ -0,0 +1 @@ +MERGE (d:Dog {name: "Rex" ,id:0}) WITH d UNWIND range(0, 1000) AS id MERGE (h:Human {name: "Humie" + id, id:id}) MERGE (d)-[l:LOVES {id:id, how:"very"}]->(h); diff --git a/e2e/algo_test/test_cover3/test.yml b/e2e/algo_test/test_cover3/test.yml new file mode 100644 index 000000000..72a81898d --- /dev/null +++ b/e2e/algo_test/test_cover3/test.yml @@ -0,0 +1,7 @@ +query: > + MATCH (n) + WITH collect(n) AS list + CALL algo.cover(list) YIELD rel RETURN count(rel) AS count; + +output: + - count: 1001