2024-01-06 00:42:54 +08:00
|
|
|
// Copyright 2024 Memgraph Ltd.
|
2021-10-26 14:53:56 +08:00
|
|
|
//
|
|
|
|
// Use of this software is governed by the Business Source License
|
|
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
|
|
//
|
|
|
|
// As of the Change Date specified in that file, in accordance with
|
|
|
|
// the Business Source License, use of this software will be governed
|
|
|
|
// by the Apache License, Version 2.0, included in the file
|
|
|
|
// licenses/APL.txt.
|
|
|
|
|
2018-09-28 22:29:27 +08:00
|
|
|
#include "bfs_common.hpp"
|
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
#include "disk_test_utils.hpp"
|
|
|
|
#include "storage/v2/disk/storage.hpp"
|
|
|
|
#include "storage/v2/inmemory/storage.hpp"
|
|
|
|
|
2022-02-22 20:33:45 +08:00
|
|
|
using namespace memgraph::query;
|
|
|
|
using namespace memgraph::query::plan;
|
2018-09-28 22:29:27 +08:00
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
template <typename StorageType>
|
2018-09-28 22:29:27 +08:00
|
|
|
class SingleNodeDb : public Database {
|
|
|
|
public:
|
2023-06-29 17:44:55 +08:00
|
|
|
const std::string testSuite = "bfs_single_node";
|
|
|
|
|
|
|
|
SingleNodeDb() : config_(disk_test_utils::GenerateOnDiskConfig(testSuite)), db_(new StorageType(config_)) {}
|
|
|
|
|
|
|
|
~SingleNodeDb() override {
|
|
|
|
if (std::is_same<StorageType, memgraph::storage::DiskStorage>::value) {
|
|
|
|
disk_test_utils::RemoveRocksDbDirs(testSuite);
|
|
|
|
}
|
|
|
|
}
|
2018-09-28 22:29:27 +08:00
|
|
|
|
2024-01-06 00:42:54 +08:00
|
|
|
std::unique_ptr<memgraph::storage::Storage::Accessor> Access() override {
|
2024-01-29 22:34:00 +08:00
|
|
|
return db_->Access(memgraph::replication_coordination_glue::ReplicationRole::MAIN);
|
2024-01-06 00:42:54 +08:00
|
|
|
}
|
2018-09-28 22:29:27 +08:00
|
|
|
|
2021-02-18 22:32:43 +08:00
|
|
|
std::unique_ptr<LogicalOperator> MakeBfsOperator(Symbol source_sym, Symbol sink_sym, Symbol edge_sym,
|
|
|
|
EdgeAtom::Direction direction,
|
2022-02-22 20:33:45 +08:00
|
|
|
const std::vector<memgraph::storage::EdgeTypeId> &edge_types,
|
2021-02-18 22:32:43 +08:00
|
|
|
const std::shared_ptr<LogicalOperator> &input, bool existing_node,
|
|
|
|
Expression *lower_bound, Expression *upper_bound,
|
|
|
|
const ExpansionLambda &filter_lambda) override {
|
|
|
|
return std::make_unique<ExpandVariable>(input, source_sym, sink_sym, edge_sym, EdgeAtom::Type::BREADTH_FIRST,
|
|
|
|
direction, edge_types, false, lower_bound, upper_bound, existing_node,
|
|
|
|
filter_lambda, std::nullopt, std::nullopt);
|
2018-09-28 22:29:27 +08:00
|
|
|
}
|
|
|
|
|
2022-02-22 20:33:45 +08:00
|
|
|
std::pair<std::vector<memgraph::query::VertexAccessor>, std::vector<memgraph::query::EdgeAccessor>> BuildGraph(
|
|
|
|
memgraph::query::DbAccessor *dba, const std::vector<int> &vertex_locations,
|
2018-09-28 22:29:27 +08:00
|
|
|
const std::vector<std::tuple<int, int, std::string>> &edges) override {
|
2022-02-22 20:33:45 +08:00
|
|
|
std::vector<memgraph::query::VertexAccessor> vertex_addr;
|
|
|
|
std::vector<memgraph::query::EdgeAccessor> edge_addr;
|
2018-09-28 22:29:27 +08:00
|
|
|
|
|
|
|
for (size_t id = 0; id < vertex_locations.size(); ++id) {
|
|
|
|
auto vertex = dba->InsertVertex();
|
2021-01-21 22:47:56 +08:00
|
|
|
MG_ASSERT(
|
2022-02-22 20:33:45 +08:00
|
|
|
vertex.SetProperty(dba->NameToProperty("id"), memgraph::storage::PropertyValue(static_cast<int64_t>(id)))
|
|
|
|
.HasValue());
|
2019-11-22 01:25:25 +08:00
|
|
|
vertex_addr.push_back(vertex);
|
2018-09-28 22:29:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto e : edges) {
|
|
|
|
int u, v;
|
|
|
|
std::string type;
|
|
|
|
std::tie(u, v, type) = e;
|
2019-11-22 01:25:25 +08:00
|
|
|
auto &from = vertex_addr[u];
|
|
|
|
auto &to = vertex_addr[v];
|
|
|
|
auto edge = dba->InsertEdge(&from, &to, dba->NameToEdgeType(type));
|
2022-02-22 20:33:45 +08:00
|
|
|
MG_ASSERT(edge->SetProperty(dba->NameToProperty("from"), memgraph::storage::PropertyValue(u)).HasValue());
|
|
|
|
MG_ASSERT(edge->SetProperty(dba->NameToProperty("to"), memgraph::storage::PropertyValue(v)).HasValue());
|
2019-11-22 01:25:25 +08:00
|
|
|
edge_addr.push_back(*edge);
|
2018-09-28 22:29:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(vertex_addr, edge_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2023-06-29 17:44:55 +08:00
|
|
|
memgraph::storage::Config config_;
|
|
|
|
std::unique_ptr<memgraph::storage::Storage> db_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SingleNodeBfsTestInMemory
|
|
|
|
: public ::testing::TestWithParam<
|
|
|
|
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FilterLambdaType>> {
|
|
|
|
public:
|
|
|
|
using StorageType = memgraph::storage::InMemoryStorage;
|
|
|
|
static void SetUpTestCase() { db_ = std::make_unique<SingleNodeDb<StorageType>>(); }
|
|
|
|
static void TearDownTestCase() { db_ = nullptr; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static std::unique_ptr<SingleNodeDb<StorageType>> db_;
|
2018-09-28 22:29:27 +08:00
|
|
|
};
|
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
TEST_P(SingleNodeBfsTestInMemory, All) {
|
|
|
|
int lower_bound;
|
|
|
|
int upper_bound;
|
|
|
|
EdgeAtom::Direction direction;
|
|
|
|
std::vector<std::string> edge_types;
|
|
|
|
bool known_sink;
|
|
|
|
FilterLambdaType filter_lambda_type;
|
|
|
|
std::tie(lower_bound, upper_bound, direction, edge_types, known_sink, filter_lambda_type) = GetParam();
|
|
|
|
this->db_->BfsTest(db_.get(), lower_bound, upper_bound, direction, edge_types, known_sink, filter_lambda_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<SingleNodeDb<SingleNodeBfsTestInMemory::StorageType>> SingleNodeBfsTestInMemory::db_{nullptr};
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(DirectionAndExpansionDepth, SingleNodeBfsTestInMemory,
|
|
|
|
testing::Combine(testing::Range(-1, kVertexCount), testing::Range(-1, kVertexCount),
|
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN,
|
|
|
|
EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}), testing::Bool(),
|
|
|
|
testing::Values(FilterLambdaType::NONE)));
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
EdgeType, SingleNodeBfsTestInMemory,
|
|
|
|
testing::Combine(testing::Values(-1), testing::Values(-1),
|
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN, EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}, std::vector<std::string>{"a"},
|
|
|
|
std::vector<std::string>{"b"}, std::vector<std::string>{"a", "b"}),
|
|
|
|
testing::Bool(), testing::Values(FilterLambdaType::NONE)));
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(FilterLambda, SingleNodeBfsTestInMemory,
|
|
|
|
testing::Combine(testing::Values(-1), testing::Values(-1),
|
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN,
|
|
|
|
EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}), testing::Bool(),
|
|
|
|
testing::Values(FilterLambdaType::NONE, FilterLambdaType::USE_FRAME,
|
|
|
|
FilterLambdaType::USE_FRAME_NULL, FilterLambdaType::USE_CTX,
|
|
|
|
FilterLambdaType::ERROR)));
|
|
|
|
|
|
|
|
class SingleNodeBfsTestOnDisk
|
2018-09-28 22:29:27 +08:00
|
|
|
: public ::testing::TestWithParam<
|
2021-02-18 22:32:43 +08:00
|
|
|
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FilterLambdaType>> {
|
2018-09-28 22:29:27 +08:00
|
|
|
public:
|
2023-06-29 17:44:55 +08:00
|
|
|
using StorageType = memgraph::storage::DiskStorage;
|
|
|
|
static void SetUpTestCase() { db_ = std::make_unique<SingleNodeDb<StorageType>>(); }
|
2018-09-28 22:29:27 +08:00
|
|
|
static void TearDownTestCase() { db_ = nullptr; }
|
|
|
|
|
|
|
|
protected:
|
2023-06-29 17:44:55 +08:00
|
|
|
static std::unique_ptr<SingleNodeDb<StorageType>> db_;
|
2018-09-28 22:29:27 +08:00
|
|
|
};
|
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
TEST_P(SingleNodeBfsTestOnDisk, All) {
|
2018-09-28 22:29:27 +08:00
|
|
|
int lower_bound;
|
|
|
|
int upper_bound;
|
|
|
|
EdgeAtom::Direction direction;
|
|
|
|
std::vector<std::string> edge_types;
|
|
|
|
bool known_sink;
|
|
|
|
FilterLambdaType filter_lambda_type;
|
2021-02-18 22:32:43 +08:00
|
|
|
std::tie(lower_bound, upper_bound, direction, edge_types, known_sink, filter_lambda_type) = GetParam();
|
2023-06-29 17:44:55 +08:00
|
|
|
this->db_->BfsTest(db_.get(), lower_bound, upper_bound, direction, edge_types, known_sink, filter_lambda_type);
|
2018-09-28 22:29:27 +08:00
|
|
|
}
|
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
std::unique_ptr<SingleNodeDb<SingleNodeBfsTestOnDisk::StorageType>> SingleNodeBfsTestOnDisk::db_{nullptr};
|
2018-09-28 22:29:27 +08:00
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
INSTANTIATE_TEST_CASE_P(DirectionAndExpansionDepth, SingleNodeBfsTestOnDisk,
|
2021-02-18 22:32:43 +08:00
|
|
|
testing::Combine(testing::Range(-1, kVertexCount), testing::Range(-1, kVertexCount),
|
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN,
|
|
|
|
EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}), testing::Bool(),
|
|
|
|
testing::Values(FilterLambdaType::NONE)));
|
2018-09-28 22:29:27 +08:00
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
2023-06-29 17:44:55 +08:00
|
|
|
EdgeType, SingleNodeBfsTestOnDisk,
|
2018-09-28 22:29:27 +08:00
|
|
|
testing::Combine(testing::Values(-1), testing::Values(-1),
|
2021-02-18 22:32:43 +08:00
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN, EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}, std::vector<std::string>{"a"},
|
|
|
|
std::vector<std::string>{"b"}, std::vector<std::string>{"a", "b"}),
|
2018-09-28 22:29:27 +08:00
|
|
|
testing::Bool(), testing::Values(FilterLambdaType::NONE)));
|
|
|
|
|
2023-06-29 17:44:55 +08:00
|
|
|
INSTANTIATE_TEST_CASE_P(FilterLambda, SingleNodeBfsTestOnDisk,
|
2021-02-18 22:32:43 +08:00
|
|
|
testing::Combine(testing::Values(-1), testing::Values(-1),
|
|
|
|
testing::Values(EdgeAtom::Direction::OUT, EdgeAtom::Direction::IN,
|
|
|
|
EdgeAtom::Direction::BOTH),
|
|
|
|
testing::Values(std::vector<std::string>{}), testing::Bool(),
|
|
|
|
testing::Values(FilterLambdaType::NONE, FilterLambdaType::USE_FRAME,
|
|
|
|
FilterLambdaType::USE_FRAME_NULL, FilterLambdaType::USE_CTX,
|
|
|
|
FilterLambdaType::ERROR)));
|