[master < T1110] Add merge optimization to expand dynamically during runtime (#1110)

This commit is contained in:
Josipmrden
2023-09-08 17:12:25 +02:00
committed by GitHub
parent bd1852f407
commit 07dea328d8
29 changed files with 2164 additions and 1905 deletions

View File

@@ -304,7 +304,7 @@ TYPED_TEST(QueryPlanTest, CreateExpand) {
dba.PrefetchOutEdges(vertex);
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::OLD);
MG_ASSERT(maybe_edges.HasValue());
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
EXPECT_EQ(edge.EdgeType(), edge_type);
EXPECT_EQ(edge.GetProperty(memgraph::storage::View::OLD, property.second)->ValueInt(), 3);
}
@@ -1129,7 +1129,7 @@ TYPED_TEST(QueryPlanTest, SetProperty) {
dba.PrefetchOutEdges(vertex);
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(maybe_edges.HasValue());
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
ASSERT_EQ(edge.GetProperty(memgraph::storage::View::OLD, prop1)->type(),
memgraph::storage::PropertyValue::Type::Int);
EXPECT_EQ(edge.GetProperty(memgraph::storage::View::OLD, prop1)->ValueInt(), 42);
@@ -1184,7 +1184,7 @@ TYPED_TEST(QueryPlanTest, SetProperties) {
dba.PrefetchOutEdges(vertex);
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(maybe_edges.HasValue());
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
auto from = edge.From();
EXPECT_EQ(from.Properties(memgraph::storage::View::OLD)->size(), update ? 2 : 1);
if (update) {
@@ -1365,7 +1365,7 @@ TYPED_TEST(QueryPlanTest, RemoveProperty) {
dba.PrefetchOutEdges(vertex);
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(maybe_edges.HasValue());
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
EXPECT_EQ(edge.GetProperty(memgraph::storage::View::OLD, prop1)->type(),
memgraph::storage::PropertyValue::Type::Null);
auto from = edge.From();
@@ -2258,7 +2258,7 @@ TYPED_TEST(UpdatePropertiesWithAuthFixture, SetPropertyExpandWithAuthChecker) {
for (auto vertex : this->dba.Vertices(memgraph::storage::View::NEW)) {
if (vertex.OutEdges(memgraph::storage::View::NEW).HasValue()) {
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::NEW);
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
EXPECT_EQ(edge.EdgeType(), edge_type_id);
auto maybe_properties = edge.Properties(memgraph::storage::View::NEW);
ASSERT_TRUE(maybe_properties.HasValue());
@@ -2276,7 +2276,7 @@ TYPED_TEST(UpdatePropertiesWithAuthFixture, SetPropertyExpandWithAuthChecker) {
for (auto vertex : this->dba.Vertices(memgraph::storage::View::NEW)) {
if (vertex.OutEdges(memgraph::storage::View::NEW).HasValue()) {
auto maybe_edges = vertex.OutEdges(memgraph::storage::View::NEW);
for (auto edge : *maybe_edges) {
for (auto edge : maybe_edges->edges) {
EXPECT_EQ(edge.EdgeType(), edge_type_id);
auto maybe_properties = edge.Properties(memgraph::storage::View::NEW);
ASSERT_TRUE(maybe_properties.HasValue());
@@ -2495,3 +2495,112 @@ TYPED_TEST(UpdatePropertiesWithAuthFixture, SetPropertyExpandWithAuthChecker) {
}
}
#endif
template <typename StorageType>
class DynamicExpandFixture : public testing::Test {
protected:
const std::string testSuite = "query_plan_create_set_remove_delete_dynamic_expand";
memgraph::storage::Config config = disk_test_utils::GenerateOnDiskConfig(testSuite);
std::unique_ptr<memgraph::storage::Storage> db{new StorageType(config)};
std::unique_ptr<memgraph::storage::Storage::Accessor> storage_dba{db->Access()};
memgraph::query::DbAccessor dba{storage_dba.get()};
SymbolTable symbol_table;
AstStorage storage;
// make 2 nodes connected to the third node
memgraph::query::VertexAccessor v1{dba.InsertVertex()};
memgraph::query::VertexAccessor v2{dba.InsertVertex()};
memgraph::query::VertexAccessor v3{dba.InsertVertex()};
memgraph::query::VertexAccessor v4{dba.InsertVertex()};
memgraph::query::VertexAccessor v5{dba.InsertVertex()};
memgraph::storage::EdgeTypeId edge_type{db->NameToEdgeType("Edge")};
memgraph::query::EdgeAccessor r1{*dba.InsertEdge(&v1, &v5, edge_type)};
memgraph::query::EdgeAccessor r2{*dba.InsertEdge(&v2, &v5, edge_type)};
memgraph::query::EdgeAccessor r3{*dba.InsertEdge(&v3, &v5, edge_type)};
memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v4, &v5, edge_type)};
memgraph::storage::LabelId node_label{dba.NameToLabel("Node")};
memgraph::storage::LabelId supernode_label{dba.NameToLabel("Supernode")};
void SetUp() override {
ASSERT_TRUE(v1.AddLabel(node_label).HasValue());
ASSERT_TRUE(v2.AddLabel(node_label).HasValue());
ASSERT_TRUE(v3.AddLabel(node_label).HasValue());
ASSERT_TRUE(v4.AddLabel(node_label).HasValue());
ASSERT_TRUE(v5.AddLabel(supernode_label).HasValue());
memgraph::license::global_license_checker.EnableTesting();
dba.AdvanceCommand();
}
void TearDown() override {
if (std::is_same<StorageType, memgraph::storage::DiskStorage>::value) {
disk_test_utils::RemoveRocksDbDirs(testSuite);
}
}
};
using StorageTypes = ::testing::Types<memgraph::storage::InMemoryStorage, memgraph::storage::DiskStorage>;
TYPED_TEST_CASE(DynamicExpandFixture, StorageTypes);
TYPED_TEST(DynamicExpandFixture, Expand) {
using ExpandCursor = memgraph::query::plan::Expand::ExpandCursor;
auto scan_node_by_label = MakeScanAllByLabel(this->storage, this->symbol_table, "n", this->node_label);
auto scan_supernode_by_label =
MakeScanAllByLabel(this->storage, this->symbol_table, "s", this->supernode_label, scan_node_by_label.op_);
auto once = std::make_shared<Once>();
auto edge_sym = this->symbol_table.CreateSymbol("r", true);
auto my_expand = std::make_shared<Expand>(
scan_supernode_by_label.op_, scan_supernode_by_label.sym_, scan_node_by_label.sym_, edge_sym,
EdgeAtom::Direction::OUT, std::vector<memgraph::storage::EdgeTypeId>{}, true, memgraph::storage::View::OLD);
auto context = MakeContext(this->storage, this->symbol_table, &this->dba);
Frame frame{context.symbol_table.max_position()};
frame[scan_supernode_by_label.sym_] = this->v4;
frame[scan_node_by_label.sym_] = this->v1;
auto *mem = memgraph::utils::NewDeleteResource();
auto initial_cursor_ptr = MakeUniqueCursorPtr<ExpandCursor>(mem, *my_expand, -1, -1, mem);
auto *initial_cursor = dynamic_cast<ExpandCursor *>(initial_cursor_ptr.get());
auto expansion_info = initial_cursor->GetExpansionInfo(frame);
ASSERT_EQ(expansion_info.input_node.value(), this->v4);
ASSERT_EQ(expansion_info.direction, EdgeAtom::Direction::OUT);
ASSERT_EQ(expansion_info.existing_node.value(), this->v1);
auto expanded_first_cursor_ptr = MakeUniqueCursorPtr<ExpandCursor>(mem, *my_expand, 1, -1, mem);
auto *expanded_first_cursor = dynamic_cast<ExpandCursor *>(expanded_first_cursor_ptr.get());
expansion_info = expanded_first_cursor->GetExpansionInfo(frame);
ASSERT_EQ(expansion_info.input_node.value(), this->v1);
ASSERT_EQ(expansion_info.direction, EdgeAtom::Direction::IN);
ASSERT_EQ(expansion_info.existing_node.value(), this->v4);
auto expanded_both_take_first_cursor_ptr = MakeUniqueCursorPtr<ExpandCursor>(mem, *my_expand, 1, 100, mem);
auto *expanded_both_take_first = dynamic_cast<ExpandCursor *>(expanded_both_take_first_cursor_ptr.get());
expansion_info = expanded_both_take_first->GetExpansionInfo(frame);
ASSERT_EQ(expansion_info.input_node.value(), this->v4);
ASSERT_EQ(expansion_info.direction, EdgeAtom::Direction::OUT);
ASSERT_EQ(expansion_info.existing_node.value(), this->v1);
auto expanded_both_take_second_cursor_ptr = MakeUniqueCursorPtr<ExpandCursor>(mem, *my_expand, 100, 1, mem);
auto *expanded_both_take_second = dynamic_cast<ExpandCursor *>(expanded_both_take_second_cursor_ptr.get());
expansion_info = expanded_both_take_second->GetExpansionInfo(frame);
ASSERT_EQ(expansion_info.input_node.value(), this->v1);
ASSERT_EQ(expansion_info.direction, EdgeAtom::Direction::IN);
ASSERT_EQ(expansion_info.existing_node.value(), this->v4);
auto expanded_equal_take_second_cursror_ptr = MakeUniqueCursorPtr<ExpandCursor>(mem, *my_expand, 5, 5, mem);
auto *expanded_equal_take_second = dynamic_cast<ExpandCursor *>(expanded_equal_take_second_cursror_ptr.get());
expansion_info = expanded_equal_take_second->GetExpansionInfo(frame);
ASSERT_EQ(expansion_info.input_node.value(), this->v1);
ASSERT_EQ(expansion_info.direction, EdgeAtom::Direction::IN);
ASSERT_EQ(expansion_info.existing_node.value(), this->v4);
}