Skip to content

Commit

Permalink
implement path reconstruction
Browse files Browse the repository at this point in the history
  • Loading branch information
SiberiaWolfP committed Feb 27, 2024
1 parent d3011f4 commit 40530e3
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 51 deletions.
20 changes: 10 additions & 10 deletions duckpgq/src/duckpgq/functions/scalar/iterativelength_lowerbound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,15 @@ static void IterativeLengthLowerBoundFunction(DataChunk &args,
duckpgq_state->csr_to_delete.insert(info.csr_id);
}

CreateScalarFunctionInfo
DuckPGQFunctions::GetIterativeLengthLowerBoundFunction() {
auto fun = ScalarFunction(
"iterativelength_lowerbound",
{LogicalType::INTEGER, LogicalType::BIGINT, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT},
LogicalType::BIGINT, IterativeLengthLowerBoundFunction,
IterativeLengthFunctionData::IterativeLengthBind);
return CreateScalarFunctionInfo(fun);
}
// CreateScalarFunctionInfo
// DuckPGQFunctions::GetIterativeLengthLowerBoundFunction() {
// auto fun = ScalarFunction(
// "iterativelength_lowerbound",
// {LogicalType::INTEGER, LogicalType::BIGINT, LogicalType::BIGINT,
// LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT},
// LogicalType::BIGINT, IterativeLengthLowerBoundFunction,
// IterativeLengthFunctionData::IterativeLengthBind);
// return CreateScalarFunctionInfo(fun);
// }

} // namespace duckdb
21 changes: 10 additions & 11 deletions duckpgq/src/duckpgq/functions/scalar/iterativelength_two_phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ static void IterativeLengthLowerBoundFunction(DataChunk &args, ExpressionState &
auto result_data = FlatVector::GetData<int64_t>(result);

// create temp SIMD arrays
vector<std::bitset<LANE_LIMIT>> seen(v_size);
vector<std::bitset<LANE_LIMIT>> visit1(v_size);
vector<std::bitset<LANE_LIMIT>> visit2(v_size);

Expand All @@ -178,7 +177,6 @@ static void IterativeLengthLowerBoundFunction(DataChunk &args, ExpressionState &

// empty visit vectors
for (auto i = 0; i < v_size; i++) {
seen[i] = 0;
visit1[i] = 0;
}

Expand Down Expand Up @@ -236,14 +234,15 @@ static void IterativeLengthLowerBoundFunction(DataChunk &args, ExpressionState &
duckpgq_state->csr_to_delete.insert(info.csr_id);
}

// CreateScalarFunctionInfo DuckPGQFunctions::GetIterativeLengthLowerBoundFunction() {
// auto fun = ScalarFunction("iterativelength_lowerbound",
// {LogicalType::INTEGER, LogicalType::BIGINT,
// LogicalType::BIGINT, LogicalType::BIGINT,
// LogicalType::BIGINT, LogicalType::BIGINT},
// LogicalType::BIGINT, IterativeLengthLowerBoundFunction,
// IterativeLengthFunctionData::IterativeLengthBind);
// return CreateScalarFunctionInfo(fun);
// }
CreateScalarFunctionInfo
DuckPGQFunctions::GetIterativeLengthLowerBoundFunction() {
auto fun = ScalarFunction(
"iterativelength_lowerbound",
{LogicalType::INTEGER, LogicalType::BIGINT, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT},
LogicalType::BIGINT, IterativeLengthLowerBoundFunction,
IterativeLengthFunctionData::IterativeLengthBind);
return CreateScalarFunctionInfo(fun);
}

} // namespace duckdb
41 changes: 18 additions & 23 deletions duckpgq/src/duckpgq/functions/scalar/shortest_path_two_phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ static bool IterativeLengthPhaseOne(int64_t v_size, int64_t *V, vector<int64_t>
int64_t iter, vector<int64_t> &edge_ids,
vector<vector<unordered_map<int64_t, int64_t>>> &paths_v,
vector<vector<unordered_map<int64_t, int64_t>>> &paths_e,
vector<std::bitset<LANE_LIMIT>> &seen,
vector<std::bitset<LANE_LIMIT>> &visit,
vector<std::bitset<LANE_LIMIT>> &next) {
bool change = false;
for (auto v = 0; v < v_size; v++) {
next[v] = 0;
seen[v] = 0;
}
//! Keep track of edge id through which the node was reached
for (auto v = 0; v < v_size; v++) {
Expand All @@ -41,7 +39,6 @@ static bool IterativeLengthPhaseOne(int64_t v_size, int64_t *V, vector<int64_t>
}

for (auto v = 0; v < v_size; v++) {
seen[v] = seen[v] | next[v];
change |= next[v].any();
}
return change;
Expand Down Expand Up @@ -208,7 +205,6 @@ static void ShortestPathLowerBoundFunction(DataChunk &args, ExpressionState &sta
ValidityMask &result_validity = FlatVector::Validity(result);

// create temp SIMD arrays
vector<std::bitset<LANE_LIMIT>> seen(v_size);
vector<std::bitset<LANE_LIMIT>> visit1(v_size);
vector<std::bitset<LANE_LIMIT>> visit2(v_size);

Expand All @@ -230,7 +226,6 @@ static void ShortestPathLowerBoundFunction(DataChunk &args, ExpressionState &sta

// empty visit vectors
for (auto i = 0; i < v_size; i++) {
seen[i] = 0;
visit1[i] = 0;
}

Expand All @@ -252,15 +247,14 @@ static void ShortestPathLowerBoundFunction(DataChunk &args, ExpressionState &sta

int64_t iter = 1;
for (; iter < lower_bound; iter++) {
IterativeLengthPhaseOne(v_size, v, e, iter, edge_ids, paths_v, paths_e, seen,
IterativeLengthPhaseOne(v_size, v, e, iter, edge_ids, paths_v, paths_e,
(iter & 1) ? visit1 : visit2,
(iter & 1) ? visit2 : visit1);
}

for (int64_t lane = 0; lane < LANE_LIMIT; lane++) {
auto search_num = lane_to_num[lane];
if (search_num >= 0) {
int64_t src_pos = vdata_src.sel->get_index(search_num);
int64_t dst_pos = vdata_dst.sel->get_index(search_num);
auto phase_two_result = ShortestPathInternal(lane, v_size, dst_data[dst_pos],
upper_bound - lower_bound + 1, v, e, edge_ids, (iter & 1) ? visit1 : visit2);
Expand All @@ -270,17 +264,17 @@ static void ShortestPathLowerBoundFunction(DataChunk &args, ExpressionState &sta
vector<int64_t> output_vector;
// construct the path of phase one
if (paths_v[phase_two_src][lane].size() > 0) {
auto parent_vertex = paths_v[phase_two_src][lane][lower_bound - 1];
auto parent_edge = paths_e[phase_two_src][lane][lower_bound - 1];
auto iterations = lower_bound - 1;
auto parent_vertex = paths_v[phase_two_src][lane][iterations];
auto parent_edge = paths_e[phase_two_src][lane][iterations];

output_vector.push_back(parent_edge);
while (parent_vertex != src_data[src_pos]) {
output_vector.push_back(parent_vertex);
parent_edge = paths_e[parent_vertex][lane][lower_bound - 1];
parent_vertex = paths_v[parent_vertex][lane][lower_bound - 1];
while (iterations > 0) {
output_vector.push_back(parent_edge);
output_vector.push_back(parent_vertex);
iterations--;
parent_edge = paths_e[parent_vertex][lane][iterations];
parent_vertex = paths_v[parent_vertex][lane][iterations];
}
output_vector.push_back(src_data[src_pos]);
std::reverse(output_vector.begin(), output_vector.end());
}

Expand Down Expand Up @@ -320,14 +314,15 @@ static void ShortestPathLowerBoundFunction(DataChunk &args, ExpressionState &sta
duckpgq_state->csr_to_delete.insert(info.csr_id);
}

CreateScalarFunctionInfo DuckPGQFunctions::GetShortestPathLowerBoundFunction() {
auto fun = ScalarFunction("shortestpath_lowerbound",
{LogicalType::INTEGER, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT},
LogicalType::LIST(LogicalType::BIGINT),
ShortestPathLowerBoundFunction,
IterativeLengthFunctionData::IterativeLengthBind);
CreateScalarFunctionInfo
DuckPGQFunctions::GetShortestPathLowerBoundFunction() {
auto fun = ScalarFunction(
"shortestpath_lowerbound",
{LogicalType::INTEGER, LogicalType::BIGINT, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT},
LogicalType::LIST(LogicalType::BIGINT),
ShortestPathLowerBoundFunction,
IterativeLengthFunctionData::IterativeLengthBind);
return CreateScalarFunctionInfo(fun);
}

Expand Down
40 changes: 33 additions & 7 deletions test/sql/path-finding/shortest_path_bound.test
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ WITH cte1 AS (

# Graph to test shortest path bound with a cycle
# (1) <- (0) <-> (2)
# 0 to 1 is 1 hop

statement ok
CREATE TABLE Point4(id BIGINT); INSERT INTO Point4 VALUES (0), (1), (2);
Expand Down Expand Up @@ -240,9 +239,37 @@ query III
2 1 [2, 2, 0, 0, 1]
2 2 [2, 2, 0, 1, 2]

query IIIII
-FROM GRAPH_TABLE (pg4
MATCH
p = ANY SHORTEST (a:Point4)-[k:know4]->{1,5}(b:Point4)
COLUMNS (a.id as id1, b.id as id2, element_id(p) as elements, vertices(p) as vertices, path_length(p) as length)
) tmp
order by tmp.id1, tmp.id2;
----
0 0 [0, 1, 2, 2, 0] [0, 2, 0] 2
0 1 [0, 0, 1] [0, 1] 1
0 2 [0, 1, 2] [0, 2] 1
2 0 [2, 2, 0] [2, 0] 1
2 1 [2, 2, 0, 0, 1] [2, 0, 1] 2
2 2 [2, 2, 0, 1, 2] [2, 0, 2] 2

query IIIII
-FROM GRAPH_TABLE (pg4
MATCH
p = ANY SHORTEST (a:Point4)-[k:know4]->{10,15}(b:Point4)
COLUMNS (a.id as id1, b.id as id2, element_id(p) as elements, vertices(p) as vertices, path_length(p) as length)
) tmp
order by tmp.id1, tmp.id2;
----
0 0 [0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0] [0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0] 10
0 1 [0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1] [0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1] 11
0 2 [0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2] [0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2] 11
2 0 [2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0] [2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0] 11
2 1 [2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1] [2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1] 10
2 2 [2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2] [2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2] 10

# Description: Test algorithm's capability to ignore isolated nodes.
# Graph Structure:
# (0) <-> (2), (1), (3)

statement ok
Expand Down Expand Up @@ -275,8 +302,7 @@ query III
2 2 [2, 1, 0, 0, 2]

# Description: Test shortest paths in a graph with cycles.
# Graph Structure:
# (0) <-> (2) <-> (3) -> (1) (selfloop)
# (0) <-> (2) <-> (3) -> (1) ⮌
# ↑ |
# └----------------------┘

Expand Down Expand Up @@ -309,16 +335,16 @@ query III
0 1 [0, 0, 2, 2, 3, 4, 1]
0 2 [0, 0, 2, 1, 0, 0, 2]
0 3 [0, 0, 2, 2, 3]
1 0 [1, 5, 0, 0, 2, 1, 0]
1 1 [1, 5, 0, 0, 2, 2, 3, 4, 1]
1 0 [1, 6, 1, 5, 0]
1 1 [1, 6, 1, 6, 1]
1 2 [1, 5, 0, 0, 2]
1 3 [1, 5, 0, 0, 2, 2, 3]
2 0 [2, 1, 0, 0, 2, 1, 0]
2 1 [2, 2, 3, 4, 1]
2 2 [2, 1, 0, 0, 2]
2 3 [2, 1, 0, 0, 2, 2, 3]
3 0 [3, 4, 1, 5, 0]
3 1 [3, 3, 2, 2, 3, 4, 1]
3 1 [3, 4, 1, 6, 1]
3 2 [3, 4, 1, 5, 0, 0, 2]
3 3 [3, 3, 2, 2, 3]

Expand Down

0 comments on commit 40530e3

Please sign in to comment.