Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

67 shortest path bounded #98

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
cfe0649
initial fix of issue 67, need to test further
SiberiaWolfP Feb 8, 2024
1f21138
Merge branch 'main' into 67-shortest-path-bounded
SiberiaWolfP Feb 8, 2024
cb66073
Fix the bug of not being able to find longer paths
SiberiaWolfP Feb 13, 2024
49494a0
Previous commit causes unable to find shortest path
SiberiaWolfP Feb 13, 2024
c90456d
The path returns -1 internally if it does not exist, but should not e…
SiberiaWolfP Feb 13, 2024
d7a7a8a
Fix getting stuck in a dead loop in a cyclic graph
SiberiaWolfP Feb 13, 2024
f1076c0
Adding upper and lower bounds to the shortestpath function
SiberiaWolfP Feb 16, 2024
fd52d46
Merge branch 'main' into 67-shortest-path-bounded
SiberiaWolfP Feb 16, 2024
7708373
Fix bug: path always is [0]
SiberiaWolfP Feb 16, 2024
db60bdf
Code clean
SiberiaWolfP Feb 16, 2024
470ad31
Fix bug: stop too early
SiberiaWolfP Feb 18, 2024
9ef7574
clean match.cpp
SiberiaWolfP Feb 18, 2024
bf84fe3
Bug fix: src == dst search result is always 0
SiberiaWolfP Feb 20, 2024
fbc9303
Merge remote-tracking branch 'origin/main' into 67-shortest-path-bounded
SiberiaWolfP Feb 20, 2024
79b7495
If the lower bound is not greater than 1, the high performance algori…
SiberiaWolfP Feb 20, 2024
90c6085
Keep the original algorithm consistent
SiberiaWolfP Feb 20, 2024
0341634
Format fix
Dtenwolde Feb 21, 2024
04e8e97
Comment
Dtenwolde Feb 21, 2024
29a17bc
Adding extra test case
Dtenwolde Feb 21, 2024
eb7678e
Trigger lowerbound function when lowerbound > 0
Dtenwolde Feb 21, 2024
03558fe
comment
Dtenwolde Feb 21, 2024
c6f0edb
Revert "Trigger lowerbound function when lowerbound > 0"
Dtenwolde Feb 21, 2024
ed4f5ef
Trigger lowerbound function when lowerbound > 0
Dtenwolde Feb 21, 2024
9f913b4
Remove unused dst_pos
Dtenwolde Feb 21, 2024
d39776f
Remove test
Dtenwolde Feb 21, 2024
e17f417
Add column
Dtenwolde Feb 21, 2024
195ff27
Remove test file
Dtenwolde Feb 21, 2024
34559be
Add correct test results
Dtenwolde Feb 21, 2024
a05525d
Add results
Dtenwolde Feb 21, 2024
d61e335
Add correct resutl
Dtenwolde Feb 23, 2024
1ccf97c
Remove condition
Dtenwolde Feb 23, 2024
aa8dfa4
Remove condition
Dtenwolde Feb 23, 2024
81ca5f9
Implement new idea
SiberiaWolfP Feb 26, 2024
737ab85
Merge branch '67-shortest-path-bounded' of https://github.com/cwida/d…
SiberiaWolfP Feb 26, 2024
d3011f4
Merge remote-tracking branch 'origin/main' into 67-shortest-path-bounded
SiberiaWolfP Feb 26, 2024
40530e3
implement path reconstruction
SiberiaWolfP Feb 27, 2024
49c957f
Updating the path record of the old algorithm
SiberiaWolfP Feb 28, 2024
ded74bd
Register all shortest path functions for testing
SiberiaWolfP Feb 29, 2024
9741705
fix build fail
SiberiaWolfP Feb 29, 2024
ac54a7d
Prevents completed lanes from being added to the calculation
SiberiaWolfP Feb 29, 2024
a3fa824
Further optimization
SiberiaWolfP Mar 4, 2024
e6ab7f1
make funtion template
SiberiaWolfP Mar 4, 2024
a1c6833
Optimizing path logging with one-dimensional array
SiberiaWolfP Mar 6, 2024
e307c6c
fix bug: index out of range
SiberiaWolfP Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ duckdb_unittest_tempdir/
testext
test/python/__pycache__/
.Rhistory
.vscode
76 changes: 61 additions & 15 deletions duckpgq/src/duckpgq/functions/scalar/iterativelength.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,36 @@
namespace duckdb {

static bool IterativeLength(int64_t v_size, int64_t *v, vector<int64_t> &e,
vector<vector<unordered_set<int64_t>>> &parents_v,
vector<std::bitset<LANE_LIMIT>> &seen,
vector<std::bitset<LANE_LIMIT>> &visit,
vector<std::bitset<LANE_LIMIT>> &next) {
bool change = false;
for (auto i = 0; i < v_size; i++) {
next[i] = 0;
}
for (auto i = 0; i < v_size; i++) {
if (visit[i].any()) {
for (auto offset = v[i]; offset < v[i + 1]; offset++) {
auto n = e[offset];
next[n] = next[n] | visit[i];

for (auto lane = 0; lane < LANE_LIMIT; lane++) {
for (auto i = 0; i < v_size; i++) {
if (visit[i][lane]) {
for (auto offset = v[i]; offset < v[i + 1]; offset++) {
auto n = e[offset];
if (seen[n][lane] == false || parents_v[i][lane].find(n) == parents_v[i][lane].end()) {
parents_v[n][lane] = parents_v[i][lane];
parents_v[n][lane].insert(i);
next[n][lane] = true;
}
}
}
}
}

for (auto i = 0; i < v_size; i++) {
next[i] = next[i] & ~seen[i];
// next[i] = next[i] & ~seen[i];
seen[i] = seen[i] | next[i];
change |= next[i].any();
}

return change;
}

Expand Down Expand Up @@ -74,6 +84,16 @@ static void IterativeLengthFunction(DataChunk &args, ExpressionState &state,
auto src_data = (int64_t *)vdata_src.data;
auto dst_data = (int64_t *)vdata_dst.data;

// get lowerbound and upperbound
auto &lower_bound = args.data[4];
auto &upper_bound = args.data[5];
UnifiedVectorFormat vdata_lower_bound;
UnifiedVectorFormat vdata_upper_bound;
lower_bound.ToUnifiedFormat(args.size(), vdata_lower_bound);
upper_bound.ToUnifiedFormat(args.size(), vdata_upper_bound);
auto lower_bound_data = (int64_t *)vdata_lower_bound.data;
auto upper_bound_data = (int64_t *)vdata_upper_bound.data;

ValidityMask &result_validity = FlatVector::Validity(result);

// create result vector
Expand All @@ -84,6 +104,7 @@ static void IterativeLengthFunction(DataChunk &args, ExpressionState &state,
vector<std::bitset<LANE_LIMIT>> seen(v_size);
vector<std::bitset<LANE_LIMIT>> visit1(v_size);
vector<std::bitset<LANE_LIMIT>> visit2(v_size);
vector<vector<unordered_set<int64_t>>> parents_v(v_size, std::vector<unordered_set<int64_t>>(LANE_LIMIT));

// maps lane to search number
short lane_to_num[LANE_LIMIT];
Expand All @@ -110,11 +131,13 @@ static void IterativeLengthFunction(DataChunk &args, ExpressionState &state,
int64_t dst_pos = vdata_dst.sel->get_index(search_num);
if (!vdata_src.validity.RowIsValid(src_pos)) {
result_validity.SetInvalid(search_num);
result_data[search_num] = (uint64_t)-1; /* no path */
result_data[search_num] = (int64_t)-1; /* no path */
} else if (src_data[src_pos] == dst_data[dst_pos]) {
result_data[search_num] =
SiberiaWolfP marked this conversation as resolved.
Show resolved Hide resolved
(uint64_t)0; // path of length 0 does not require a search
(int64_t)0; // path of length 0 does not require a search
} else {
result_data[search_num] = (int64_t)-1; /* initialize to no path */
seen[src_data[src_pos]][lane] = true;
visit1[src_data[src_pos]][lane] = true;
lane_to_num[lane] = search_num; // active lane
active++;
Expand All @@ -125,23 +148,45 @@ static void IterativeLengthFunction(DataChunk &args, ExpressionState &state,

// make passes while a lane is still active
for (int64_t iter = 1; active; iter++) {
if (!IterativeLength(v_size, v, e, seen, (iter & 1) ? visit1 : visit2,
(iter & 1) ? visit2 : visit1)) {
break;
}
// if (!IterativeLength(v_size, v, e, seen, (iter & 1) ? visit1 : visit2,
SiberiaWolfP marked this conversation as resolved.
Show resolved Hide resolved
// (iter & 1) ? visit2 : visit1)) {
// break;
// }
bool stop = !IterativeLength(v_size, v, e, parents_v, seen, (iter & 1) ? visit1 : visit2,
(iter & 1) ? visit2 : visit1);
// detect lanes that finished
for (int64_t lane = 0; lane < LANE_LIMIT; lane++) {
int64_t search_num = lane_to_num[lane];
if (search_num >= 0) { // active lane
int64_t dst_pos = vdata_dst.sel->get_index(search_num);
if (seen[dst_data[dst_pos]][lane]) {
result_data[search_num] =
iter; /* found at iter => iter = path length */
if (seen[dst_data[dst_pos]][lane]){

// check if the path length is within bounds
// bound vector is either a constant or a flat vector
if (lower_bound.GetVectorType() == VectorType::CONSTANT_VECTOR ?
iter < lower_bound_data[0] : iter < lower_bound_data[dst_pos]) {
// when reach the destination too early, treat destination as null
// looks like the graph does not have that vertex
seen[dst_data[dst_pos]][lane] = false;
(iter & 1) ? visit2[dst_data[dst_pos]][lane] = false
: visit1[dst_data[dst_pos]][lane] = false;
continue;
} else if (upper_bound.GetVectorType() == VectorType::CONSTANT_VECTOR ?
iter > upper_bound_data[0] : iter > upper_bound_data[dst_pos]) {
result_validity.SetInvalid(search_num);
result_data[search_num] = (int64_t)-1; /* no path */
} else {
result_data[search_num] =
iter; /* found at iter => iter = path length */
}
lane_to_num[lane] = -1; // mark inactive
active--;
}
}
}
if (stop) {
break;
}
}

// no changes anymore: any still active searches have no path
Expand All @@ -160,6 +205,7 @@ static void IterativeLengthFunction(DataChunk &args, ExpressionState &state,
CreateScalarFunctionInfo DuckPGQFunctions::GetIterativeLengthFunction() {
auto fun = ScalarFunction("iterativelength",
{LogicalType::INTEGER, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT,
LogicalType::BIGINT, LogicalType::BIGINT},
LogicalType::BIGINT, IterativeLengthFunction,
IterativeLengthFunctionData::IterativeLengthBind);
Expand Down
Loading
Loading