From 816991bc45537518420a94fa449918e248ba1246 Mon Sep 17 00:00:00 2001 From: Vicky Vergara Date: Tue, 6 Jun 2023 09:39:20 -0600 Subject: [PATCH] bdAstar code simplification (#2522) * [bdAstar] code simplification of bdAstar --- NEWS | 2 + doc/src/release_notes.rst | 2 + .../bdAstar/{pgr_bdAstar.hpp => bdAstar.hpp} | 57 +++-- include/drivers/bdAstar/bdAstar_driver.h | 2 +- src/bdAstar/bdAstar.c | 49 ++--- src/bdAstar/bdAstar_driver.cpp | 208 +++--------------- 6 files changed, 92 insertions(+), 228 deletions(-) rename include/bdAstar/{pgr_bdAstar.hpp => bdAstar.hpp} (84%) diff --git a/NEWS b/NEWS index f616fd10299..6b3833b855c 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,8 @@ pgRouting 3.6.0 Release Notes simplification. * `2521 ` Dijkstra code simplification. +* `2522 ` bdAstar code + simplification. **Documentation** diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index c0b151c588c..0d47a9f37b6 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -46,6 +46,8 @@ pgRouting 3.6.0 Release Notes simplification. * `2521 ` Dijkstra code simplification. +* `2522 ` bdAstar code + simplification. .. rubric:: Documentation diff --git a/include/bdAstar/pgr_bdAstar.hpp b/include/bdAstar/bdAstar.hpp similarity index 84% rename from include/bdAstar/pgr_bdAstar.hpp rename to include/bdAstar/bdAstar.hpp index 5ffec506b14..4b51856dddf 100644 --- a/include/bdAstar/pgr_bdAstar.hpp +++ b/include/bdAstar/bdAstar.hpp @@ -1,13 +1,12 @@ /*PGR-GNU***************************************************************** File: pgr_bdAstar.hpp -Generated with Template by: Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: +Mail: vicky at erosion.dev ------ @@ -32,25 +31,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #pragma once -#include "cpp_common/pgr_bidirectional.hpp" - -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include "cpp_common/pgr_bidirectional.hpp" #include "cpp_common/basePath_SSEC.hpp" namespace pgrouting { + namespace bidirectional { -template < typename G > +template class Pgr_bdAstar : public Pgr_bidirectional { - typedef typename Pgr_bidirectional::V V; - typedef typename Pgr_bidirectional::E E; - typedef typename Pgr_bidirectional::Cost_Vertex_pair Cost_Vertex_pair; + using V = typename Pgr_bidirectional::V; + using E = typename Pgr_bidirectional::E; + using Cost_Vertex_pair = typename Pgr_bidirectional::Cost_Vertex_pair; using Pgr_bidirectional::graph; using Pgr_bidirectional::m_log; @@ -192,6 +188,39 @@ class Pgr_bdAstar : public Pgr_bidirectional { }; } // namespace bidirectional + + +namespace algorithms { + +template +std::deque bdastar( + G &graph, + const std::map> &combinations, + int heuristic, + double factor, + double epsilon, + bool only_cost) { + std::deque paths; + pgrouting::bidirectional::Pgr_bdAstar fn_bdAstar(graph); + + for (const auto &c : combinations) { + if (!graph.has_vertex(c.first)) continue; + + for (const auto &destination : c.second) { + if (!graph.has_vertex(destination)) continue; + + fn_bdAstar.clear(); + + paths.push_back(fn_bdAstar.pgr_bdAstar( + graph.get_V(c.first), graph.get_V(destination), + heuristic, factor, epsilon, only_cost)); + } + } + + return paths; +} + +} // namespace algorithms } // namespace pgrouting #endif // INCLUDE_BDASTAR_PGR_BDASTAR_HPP_ diff --git a/include/drivers/bdAstar/bdAstar_driver.h b/include/drivers/bdAstar/bdAstar_driver.h index 2ab2ff4f76d..c73dac74b6e 100644 --- a/include/drivers/bdAstar/bdAstar_driver.h +++ b/include/drivers/bdAstar/bdAstar_driver.h @@ -50,7 +50,7 @@ typedef struct II_t_rt II_t_rt; extern "C" { #endif - void do_pgr_bdAstar( + void pgr_do_bdAstar( Edge_xy_t *data_edges, size_t total_edges, diff --git a/src/bdAstar/bdAstar.c b/src/bdAstar/bdAstar.c index 7303cb25e76..adfba4f9b4f 100644 --- a/src/bdAstar/bdAstar.c +++ b/src/bdAstar/bdAstar.c @@ -7,7 +7,7 @@ Mail: project@pgrouting.org Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: +Mail:vicky at erosion.dev ------ @@ -34,13 +34,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_common/debug_macro.h" #include "c_common/e_report.h" #include "c_common/time_msg.h" - #include "c_common/pgdata_getters.h" #include "c_common/check_parameters.h" - - -#include "drivers/astar/astar_driver.h" #include "drivers/bdAstar/bdAstar_driver.h" PGDLLEXPORT Datum _pgr_bdastar(PG_FUNCTION_ARGS); @@ -73,6 +69,9 @@ process(char* edges_sql, int64_t* end_vidsArr = NULL; size_t size_end_vidsArr = 0; + Edge_xy_t *edges = NULL; + size_t total_edges = 0; + II_t_rt *combinations = NULL; size_t total_combinations = 0; @@ -86,12 +85,8 @@ process(char* edges_sql, throw_error(err_msg, combinations_sql); } - Edge_xy_t *edges = NULL; - size_t total_edges = 0; - pgr_get_edges_xy(edges_sql, &edges, &total_edges, true, &err_msg); throw_error(err_msg, edges_sql); - PGR_DBG("Total %ld edges in query:", total_edges); if (total_edges == 0) { PGR_DBG("No edges found"); @@ -101,36 +96,34 @@ process(char* edges_sql, return; } - PGR_DBG("Starting processing"); clock_t start_t = clock(); - do_pgr_bdAstar( + pgr_do_bdAstar( edges, total_edges, + combinations, total_combinations, + start_vidsArr, size_start_vidsArr, end_vidsArr, size_end_vidsArr, - directed, heuristic, factor, epsilon, only_cost, - - result_tuples, - result_count, + result_tuples, result_count, &log_msg, ¬ice_msg, &err_msg); if (only_cost) { - time_msg("pgr_bdAstarCost()", start_t, clock()); + time_msg("pgr_bdAstarCost", start_t, clock()); } else { - time_msg("pgr_bdAstar()", start_t, clock()); + time_msg("pgr_bdAstar", start_t, clock()); } if (err_msg && (*result_tuples)) { pfree(*result_tuples); - (*result_count) = 0; (*result_tuples) = NULL; + (*result_count) = 0; } pgr_global_report(log_msg, notice_msg, err_msg); @@ -139,6 +132,8 @@ process(char* edges_sql, if (notice_msg) pfree(notice_msg); if (err_msg) pfree(err_msg); if (edges) pfree(edges); + if (start_vidsArr) pfree(start_vidsArr); + if (end_vidsArr) pfree(end_vidsArr); pgr_SPI_finish(); } @@ -148,7 +143,7 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - Path_rt *result_tuples = 0; + Path_rt *result_tuples = NULL; size_t result_count = 0; if (SRF_IS_FIRSTCALL()) { @@ -174,7 +169,6 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { PG_GETARG_BOOL(7), &result_tuples, &result_count); - } else if (PG_NARGS() == 7) { /* * combinations @@ -184,7 +178,6 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { text_to_cstring(PG_GETARG_TEXT_P(1)), NULL, NULL, - PG_GETARG_BOOL(2), PG_GETARG_INT32(3), PG_GETARG_FLOAT8(4), @@ -195,10 +188,7 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { } - - funcctx->max_calls = result_count; - funcctx->user_fctx = result_tuples; if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE) @@ -223,20 +213,10 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { size_t call_cntr = funcctx->call_cntr; - /********************************************************************** - OUT seq INTEGER, - OUT path_seq INTEGER, - OUT node BIGINT, - OUT edge BIGINT, - OUT cost FLOAT, - OUT agg_cost FLOAT - *********************************************************************/ - size_t numb = 8; values = palloc(numb * sizeof(Datum)); nulls = palloc(numb * sizeof(bool)); - size_t i; for (i = 0; i < numb; ++i) { nulls[i] = false; @@ -259,4 +239,3 @@ _pgr_bdastar(PG_FUNCTION_ARGS) { SRF_RETURN_DONE(funcctx); } } - diff --git a/src/bdAstar/bdAstar_driver.cpp b/src/bdAstar/bdAstar_driver.cpp index ada0342acc0..cc9a671ad4d 100644 --- a/src/bdAstar/bdAstar_driver.cpp +++ b/src/bdAstar/bdAstar_driver.cpp @@ -6,8 +6,9 @@ Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2016 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev ------ @@ -34,141 +35,39 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "bdAstar/pgr_bdAstar.hpp" +#include "bdAstar/bdAstar.hpp" +#include "cpp_common/combinations.h" #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" #include "c_types/ii_t_rt.h" - - -/************************************************************ - edges_sql TEXT, - start_vid BIGINT, - end_vid BIGINT, - directed BOOLEAN DEFAULT true, - only_cost BOOLEAN DEFAULT false, - ***********************************************************/ -namespace { -template < class G > -std::deque -pgr_bdAstar( - G &graph, - std::vector < II_t_rt > &combinations, - std::vector < int64_t > sources, - std::vector < int64_t > targets, - - int heuristic, - double factor, - double epsilon, - std::ostream &log, - bool only_cost) { - using pgrouting::Path; - - pgrouting::bidirectional::Pgr_bdAstar fn_bdAstar(graph); - std::deque paths; - - if (combinations.empty()) { - std::sort(sources.begin(), sources.end()); - sources.erase( - std::unique(sources.begin(), sources.end()), - sources.end()); - - std::sort(targets.begin(), targets.end()); - targets.erase( - std::unique(targets.begin(), targets.end()), - targets.end()); - - for (const auto source : sources) { - for (const auto target : targets) { - fn_bdAstar.clear(); - - if (!graph.has_vertex(source) - || !graph.has_vertex(target)) { - paths.push_back(Path(source, target)); - continue; - } - - paths.push_back(fn_bdAstar.pgr_bdAstar( - graph.get_V(source), graph.get_V(target), - heuristic, factor, epsilon, only_cost)); - } - } - - } else { - std::sort(combinations.begin(), combinations.end(), - [](const II_t_rt &lhs, const II_t_rt &rhs)->bool { - return lhs.d2.target < rhs.d2.target; - }); - std::stable_sort(combinations.begin(), combinations.end(), - [](const II_t_rt &lhs, const II_t_rt &rhs)->bool { - return lhs.d1.source < rhs.d1.source; - }); - - II_t_rt previousCombination {{0}, {0}}; - - for (const II_t_rt &comb : combinations) { - fn_bdAstar.clear(); - - if (comb.d1.source == previousCombination.d1.source && - comb.d2.target == previousCombination.d2.target) { - continue; - } - - if (!graph.has_vertex(comb.d1.source) - || !graph.has_vertex(comb.d2.target)) { - paths.push_back(Path(comb.d1.source, comb.d2.target)); - continue; - } - - paths.push_back(fn_bdAstar.pgr_bdAstar( - graph.get_V(comb.d1.source), graph.get_V(comb.d2.target), - heuristic, factor, epsilon, only_cost)); - - previousCombination = comb; - } - } - - log << fn_bdAstar.log(); - - return paths; -} - -} // namespace - void -do_pgr_bdAstar( - Edge_xy_t *edges, - size_t total_edges, - II_t_rt *combinations, - size_t total_combinations, - int64_t *start_vidsArr, - size_t size_start_vidsArr, - int64_t *end_vidsArr, - size_t size_end_vidsArr, +pgr_do_bdAstar( + Edge_xy_t *edges, size_t total_edges, + II_t_rt *combinationsArr, size_t total_combinations, + int64_t *start_vidsArr, size_t size_start_vidsArr, + int64_t *end_vidsArr, size_t size_end_vidsArr, bool directed, int heuristic, double factor, double epsilon, bool only_cost, - Path_rt **return_tuples, - size_t *return_count, - - char ** log_msg, - char ** notice_msg, - char ** err_msg) { + Path_rt **return_tuples, size_t *return_count, + char** log_msg, char** notice_msg, char** err_msg) { using pgrouting::Path; - using pgrouting::pgr_msg; using pgrouting::pgr_alloc; + using pgrouting::pgr_msg; + using pgrouting::pgr_free; std::ostringstream log; - std::ostringstream err; std::ostringstream notice; + std::ostringstream err; try { pgassert(!(*log_msg)); pgassert(!(*notice_msg)); @@ -177,108 +76,61 @@ do_pgr_bdAstar( pgassert(*return_count == 0); pgassert(total_edges != 0); - - log << "Inserting vertices into a c++ vector structure"; - std::vector - start_vertices(start_vidsArr, start_vidsArr + size_start_vidsArr); - std::vector< int64_t > - end_vertices(end_vidsArr, end_vidsArr + size_end_vidsArr); - std::vector< II_t_rt > - combinations_vector(combinations, combinations + total_combinations); + auto combinations = total_combinations? + pgrouting::utilities::get_combinations(combinationsArr, total_combinations) + : pgrouting::utilities::get_combinations(start_vidsArr, size_start_vidsArr, end_vidsArr, size_end_vidsArr); graphType gType = directed? DIRECTED: UNDIRECTED; std::deque paths; - log << "starting process\n"; if (directed) { - log << "Working with directed Graph\n"; - pgrouting::xyDirectedGraph digraph( - pgrouting::extract_vertices(edges, total_edges), - gType); + pgrouting::xyDirectedGraph digraph(pgrouting::extract_vertices(edges, total_edges), gType); digraph.insert_edges(edges, total_edges); - paths = pgr_bdAstar(digraph, - combinations_vector, - start_vertices, - end_vertices, - heuristic, - factor, - epsilon, - log, - only_cost); + paths = pgrouting::algorithms::bdastar(digraph, combinations, heuristic, factor, epsilon, only_cost); } else { - log << "Working with Undirected Graph\n"; - pgrouting::xyUndirectedGraph undigraph( - pgrouting::extract_vertices(edges, total_edges), - gType); + pgrouting::xyUndirectedGraph undigraph(pgrouting::extract_vertices(edges, total_edges), gType); undigraph.insert_edges(edges, total_edges); - paths = pgr_bdAstar( - undigraph, - combinations_vector, - start_vertices, - end_vertices, - heuristic, - factor, - epsilon, - log, - only_cost); + paths = pgrouting::algorithms::bdastar(undigraph, combinations, heuristic, factor, epsilon, only_cost); } size_t count(0); count = count_tuples(paths); if (count == 0) { - (*return_tuples) = NULL; + (*return_tuples) = nullptr; (*return_count) = 0; - notice << - "No paths found"; + notice << "No paths found\n"; *log_msg = pgr_msg(notice.str().c_str()); return; } (*return_tuples) = pgr_alloc(count, (*return_tuples)); - log << "\nConverting a set of paths into the tuples"; (*return_count) = (collapse_paths(return_tuples, paths)); -#if 0 - auto count = path.size(); - - if (count == 0) { - (*return_tuples) = NULL; - (*return_count) = 0; - notice << - "No paths found between start_vid and end_vid vertices"; - } else { - (*return_tuples) = pgr_alloc(count, (*return_tuples)); - size_t sequence = 0; - path.generate_postgres_data(return_tuples, sequence); - (*return_count) = sequence; - } -#endif - - pgassert(*err_msg == NULL); + pgassert(*err_msg == nullptr); *log_msg = log.str().empty()? - nullptr : + *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? - nullptr : + *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { - if (*return_tuples) free(*return_tuples); + (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); - } catch (std::exception& except) { - if (*return_tuples) free(*return_tuples); + } catch (std::exception &except) { + (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { - if (*return_tuples) free(*return_tuples); + (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str());