diff --git a/NEWS.md b/NEWS.md index e2d3d32bd8..bb71bae5e0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -18,6 +18,7 @@ To see all issues & pull requests closed by this release see the * [#3054](https://github.com/pgRouting/pgrouting/issues/3054): Change error message when edges_sql is empty * [#3055](https://github.com/pgRouting/pgrouting/issues/3055): bdDijkstra: use the shortest_path process and driver * [#3056](https://github.com/pgRouting/pgrouting/issues/3056): edwardMoore: use the shortest_path process and driver +* [#3060](https://github.com/pgRouting/pgrouting/issues/3060): dagShortestPath: use the shortest_path process and driver ## pgRouting 4.0 diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 3562cd1f43..c462159daf 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -43,6 +43,7 @@ To see all issues & pull requests closed by this release see the * :issue:`3054`: Change error message when edges_sql is empty * :issue:`3055`: bdDijkstra: use the shortest_path process and driver * :issue:`3056`: edwardMoore: use the shortest_path process and driver +* :issue:`3060`: dagShortestPath: use the shortest_path process and driver pgRouting 4.0 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/include/c_common/enums.h b/include/c_common/enums.h index e1b3bacf83..89d88ae06e 100644 --- a/include/c_common/enums.h +++ b/include/c_common/enums.h @@ -32,6 +32,7 @@ enum Which { TOPOSORT = 11, /** shortest_paths */ DIJKSTRA = 21, WITHPOINTS, OLD_WITHPOINTS, BDDIJKSTRA, EDWARDMOORE, + DAGSP, /** allpairs **/ FLOYD = 31, JOHNSON, /** metrics **/ diff --git a/include/dagShortestPath/dagShortestPath.hpp b/include/dagShortestPath/dagShortestPath.hpp index 5b78b5ffa7..3401d4a392 100644 --- a/include/dagShortestPath/dagShortestPath.hpp +++ b/include/dagShortestPath/dagShortestPath.hpp @@ -218,6 +218,20 @@ class Pgr_dag { }; }; +namespace algorithms { + +template +std::deque +dagShortestPath( + G &graph, + std::map> &combinations, + bool only_cost = false) { + pgrouting::Pgr_dag fn_dag; + auto paths = fn_dag.dag(graph, combinations, only_cost); + return paths; +} + +} // namespace algorithms } // namespace pgrouting #endif // INCLUDE_DAGSHORTESTPATH_DAGSHORTESTPATH_HPP_ diff --git a/include/drivers/dagShortestPath/dagShortestPath_driver.h b/include/drivers/dagShortestPath/dagShortestPath_driver.h deleted file mode 100644 index 4e2f78d12f..0000000000 --- a/include/drivers/dagShortestPath/dagShortestPath_driver.h +++ /dev/null @@ -1,76 +0,0 @@ -/*PGR-GNU***************************************************************** -File: dagShortestPath_driver.h - -Generated with Template by: -Copyright (c) 2007-2026 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2018 Sourabh Garg -Mail: sourabh.garg.mat@gmail.com - ------- - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - ********************************************************************PGR-GNU*/ - -#ifndef INCLUDE_DRIVERS_DAGSHORTESTPATH_DAGSHORTESTPATH_DRIVER_H_ -#define INCLUDE_DRIVERS_DAGSHORTESTPATH_DAGSHORTESTPATH_DRIVER_H_ -#pragma once - - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#ifdef __cplusplus -} -#endif - -#include "cpp_common/undefPostgresDefine.hpp" - -#ifdef __cplusplus -# include -# include -using Path_rt = struct Path_rt; -#else -# include -# include -typedef struct Path_rt Path_rt; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -void pgr_do_dagShortestPath( - const char*, - const char*, - ArrayType*, ArrayType*, - bool, bool, - Path_rt **, size_t*, - char**, char**, char**); - - -#ifdef __cplusplus -} -#endif - -#endif // INCLUDE_DRIVERS_DAGSHORTESTPATH_DAGSHORTESTPATH_DRIVER_H_ diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index 07c9b1af42..e6bb3f049e 100644 --- a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po +++ b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v4.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-06 17:38+0000\n" +"POT-Creation-Date: 2026-02-07 19:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3946,6 +3946,11 @@ msgid "" "use the shortest_path process and driver" msgstr "" +msgid "" +"`#3060 `__: " +"dagShortestPath: use the shortest_path process and driver" +msgstr "" + msgid "All releases" msgstr "" diff --git a/locale/pot/pgrouting_doc_strings.pot b/locale/pot/pgrouting_doc_strings.pot index 0f446e9380..940ded88c1 100644 --- a/locale/pot/pgrouting_doc_strings.pot +++ b/locale/pot/pgrouting_doc_strings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v4.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-06 17:38+0000\n" +"POT-Creation-Date: 2026-02-07 19:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3541,6 +3541,9 @@ msgstr "" msgid "`#3056 `__: edwardMoore: use the shortest_path process and driver" msgstr "" +msgid "`#3060 `__: dagShortestPath: use the shortest_path process and driver" +msgstr "" + msgid "All releases" msgstr "" diff --git a/pgtap/others/dagShortestPath/no_crash_test.pg b/pgtap/others/dagShortestPath/no_crash_test.pg index f92353ccb2..742393777a 100644 --- a/pgtap/others/dagShortestPath/no_crash_test.pg +++ b/pgtap/others/dagShortestPath/no_crash_test.pg @@ -6,7 +6,7 @@ BEGIN; UPDATE edges SET cost = sign(cost), reverse_cost = -sign(cost); -SELECT CASE WHEN min_version('4.0.0') THEN plan(81) ELSE plan(1) END; +SELECT CASE WHEN min_version('4.0.0') THEN plan(82) ELSE plan(1) END; CREATE OR REPLACE FUNCTION no_crash() RETURNS SETOF TEXT AS @@ -135,6 +135,7 @@ BEGIN 'NULL::TEXT' ]::TEXT[]; RETURN query SELECT * FROM no_crash_test('pgr_dagShortestPath', params, subs); + RETURN query SELECT throw_on_empty_edges_sql('pgr_dagShortestPath', ',1,5'); END $BODY$ diff --git a/src/cpp_common/utilities.cpp b/src/cpp_common/utilities.cpp index 15ab3044b1..f6c98eba38 100644 --- a/src/cpp_common/utilities.cpp +++ b/src/cpp_common/utilities.cpp @@ -78,6 +78,9 @@ get_name(Which which, bool is_only_cost, bool is_near, bool is_matrix) { case EDWARDMOORE: base = "pgr_edwardMoore"; break; + case DAGSP : + base = "pgr_dagShortestPath"; + break; case OLD_WITHPOINTS: case WITHPOINTS: base = "pgr_withPoints"; @@ -96,26 +99,21 @@ estimate_drivingSide(char driving_side, Which which) { d_side = ' '; } switch (which) { + case DAGSP : case EDWARDMOORE: case BDDIJKSTRA: case DIJKSTRA: - { return ' '; break; - } case WITHPOINTS: - { if (d_side == ' ') { throw std::make_pair(std::string("Invalid value of 'driving side'"), std::string("Valid value are 'r', 'l', 'b'")); } break; - } default: - { /* For the moment its old signature of pgr_withPoints */ if (!((d_side == 'r') || (d_side == 'l'))) d_side = 'b'; - } } return d_side; } diff --git a/src/dagShortestPath/CMakeLists.txt b/src/dagShortestPath/CMakeLists.txt index 94aad67376..a82e31c987 100644 --- a/src/dagShortestPath/CMakeLists.txt +++ b/src/dagShortestPath/CMakeLists.txt @@ -3,5 +3,4 @@ # License: GPL-2 See https://github.com/pgRouting/pgrouting/blob/main/LICENSE ADD_LIBRARY(dagShortestPath OBJECT dagShortestPath.c - dagShortestPath_driver.cpp - ) +) diff --git a/src/dagShortestPath/dagShortestPath.c b/src/dagShortestPath/dagShortestPath.c index fad07f9882..4e454f7ca3 100644 --- a/src/dagShortestPath/dagShortestPath.c +++ b/src/dagShortestPath/dagShortestPath.c @@ -30,59 +30,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include "c_common/postgres_connection.h" - #include "c_types/path_rt.h" -#include "c_common/debug_macro.h" -#include "c_common/e_report.h" -#include "c_common/time_msg.h" -#include "drivers/dagShortestPath/dagShortestPath_driver.h" +#include "process/shortestPath_process.h" PGDLLEXPORT Datum _pgr_dagshortestpath_v4(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(_pgr_dagshortestpath_v4); - -static -void -process( - char* edges_sql, - char* combinations_sql, - ArrayType *starts, - ArrayType *ends, - bool only_cost, - bool normal, - Path_rt **result_tuples, - size_t *result_count) { - pgr_SPI_connect(); - char* log_msg = NULL; - char* notice_msg = NULL; - char* err_msg = NULL; - (*result_tuples) = NULL; - (*result_count) = 0; - - clock_t start_t = clock(); - pgr_do_dagShortestPath( - edges_sql, - combinations_sql, - starts, ends, - - only_cost, - normal, - - result_tuples, - result_count, - &log_msg, - ¬ice_msg, - &err_msg); - time_msg(" processing pgr_dagShortestPath", start_t, clock()); - - if (err_msg) { - if (*result_tuples) pfree(*result_tuples); - } - pgr_global_report(&log_msg, ¬ice_msg, &err_msg); - - pgr_SPI_finish(); -} - PGDLLEXPORT Datum _pgr_dagshortestpath_v4(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; @@ -99,13 +52,24 @@ PGDLLEXPORT Datum _pgr_dagshortestpath_v4(PG_FUNCTION_ARGS) { /* * many to many */ - process( + pgr_process_shortestPath( text_to_cstring(PG_GETARG_TEXT_P(0)), NULL, + NULL, + PG_GETARG_ARRAYTYPE_P(1), PG_GETARG_ARRAYTYPE_P(2), + + true, PG_GETARG_BOOL(3), PG_GETARG_BOOL(4), + + 0, + true, + ' ', + true, + + DAGSP, &result_tuples, &result_count); @@ -113,12 +77,23 @@ PGDLLEXPORT Datum _pgr_dagshortestpath_v4(PG_FUNCTION_ARGS) { /* * combinations */ - process( + pgr_process_shortestPath( text_to_cstring(PG_GETARG_TEXT_P(0)), + NULL, text_to_cstring(PG_GETARG_TEXT_P(1)), + NULL, NULL, + + true, PG_GETARG_BOOL(2), true, + + 0, + true, + ' ', + true, + + DAGSP, &result_tuples, &result_count); } @@ -129,7 +104,8 @@ PGDLLEXPORT Datum _pgr_dagshortestpath_v4(PG_FUNCTION_ARGS) { != TYPEFUNC_COMPOSITE) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context that cannot accept type record"))); + errmsg("function returning record called in context " + "that cannot accept type record"))); } funcctx->tuple_desc = tuple_desc; diff --git a/src/dagShortestPath/dagShortestPath_driver.cpp b/src/dagShortestPath/dagShortestPath_driver.cpp deleted file mode 100644 index 755fde8da6..0000000000 --- a/src/dagShortestPath/dagShortestPath_driver.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/*PGR-GNU***************************************************************** -File: dagShortestPath_driver.cpp - -Generated with Template by: -Copyright (c) 2015-2026 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2018 Sourabh Garg -Mail: sourabh.garg.mat@gmail.com - ------- - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - ********************************************************************PGR-GNU*/ - -#include "drivers/dagShortestPath/dagShortestPath_driver.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "dagShortestPath/dagShortestPath.hpp" - -#include "cpp_common/combinations.hpp" -#include "cpp_common/pgdata_getters.hpp" -#include "cpp_common/to_postgres.hpp" -#include "cpp_common/assert.hpp" - -namespace { - -template < class G > -std::deque -pgr_dagShortestPath( - G &graph, - std::map> &combinations, - bool only_cost = false) { - pgrouting::Pgr_dag fn_dag; - auto paths = fn_dag.dag(graph, combinations, only_cost); - - return paths; -} - -} // namespace - -void -pgr_do_dagShortestPath( - const char *edges_sql, - const char *combinations_sql, - ArrayType *starts, - ArrayType *ends, - - bool only_cost, - bool normal, - - Path_rt **return_tuples, size_t *return_count, - char **log_msg, - char **notice_msg, - char **err_msg) { - using pgrouting::Path; - using pgrouting::to_pg_msg; - using pgrouting::pgr_free; - using pgrouting::utilities::get_combinations; - using pgrouting::pgget::get_edges; - - - std::ostringstream log; - std::ostringstream notice; - std::ostringstream err; - const char *hint = nullptr; - - try { - pgassert(!(*log_msg)); - pgassert(!(*notice_msg)); - pgassert(!(*err_msg)); - pgassert(!(*return_tuples)); - pgassert(*return_count == 0); - - using pgrouting::to_postgres::get_tuples; - - hint = combinations_sql; - auto combinations = get_combinations(combinations_sql, starts, ends, normal); - hint = nullptr; - - if (combinations.empty() && combinations_sql) { - *notice_msg = to_pg_msg("No (source, target) pairs found"); - *log_msg = to_pg_msg(combinations_sql); - return; - } - - - - hint = edges_sql; - auto edges = get_edges(std::string(edges_sql), normal, false); - - if (edges.empty()) { - *notice_msg = to_pg_msg("No edges found"); - *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log); - return; - } - hint = nullptr; - - std::deque paths; - pgrouting::DirectedGraph graph; - graph.insert_edges(edges); - paths = pgr_dagShortestPath(graph, combinations, only_cost); - - (*return_count) = get_tuples(paths, (*return_tuples)); - - if (*return_count == 0) { - *log_msg = to_pg_msg("No paths found"); - return; - } - - *log_msg = to_pg_msg(log); - *notice_msg = to_pg_msg(notice); - } catch (AssertFailedException &except) { - (*return_tuples) = pgr_free(*return_tuples); - (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err); - *log_msg = to_pg_msg(log); - } catch (const std::string &ex) { - *err_msg = to_pg_msg(ex); - *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log); - } catch (std::exception &except) { - (*return_tuples) = pgr_free(*return_tuples); - (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err); - *log_msg = to_pg_msg(log); - } catch(...) { - (*return_tuples) = pgr_free(*return_tuples); - (*return_count) = 0; - err << "Caught unknown exception!"; - *err_msg = to_pg_msg(err); - *log_msg = to_pg_msg(log); - } -} diff --git a/src/dijkstra/shortestPath_driver.cpp b/src/dijkstra/shortestPath_driver.cpp index d6cb788678..9edf78cd1c 100644 --- a/src/dijkstra/shortestPath_driver.cpp +++ b/src/dijkstra/shortestPath_driver.cpp @@ -54,6 +54,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "bellman_ford/edwardMoore.hpp" #include "bdDijkstra/bdDijkstra.hpp" #include "withPoints/withPoints.hpp" +#include "dagShortestPath/dagShortestPath.hpp" namespace { @@ -153,6 +154,7 @@ do_shortestPath( using pgrouting::algorithms::dijkstra; using pgrouting::algorithms::bdDijkstra; using pgrouting::algorithms::edwardMoore; + using pgrouting::algorithms::dagShortestPath; hint = combinations_sql; auto combinations = get_combinations(combinations_sql, starts, ends, normal, is_matrix); @@ -238,6 +240,9 @@ do_shortestPath( case EDWARDMOORE: paths = edwardMoore(digraph, combinations); break; + case DAGSP: + paths = dagShortestPath(digraph, combinations, only_cost); + break; default: err << "INTERNAL: wrong function call: " << which; return; @@ -255,8 +260,8 @@ do_shortestPath( paths = bdDijkstra(undigraph, combinations, only_cost); break; case EDWARDMOORE: - paths = edwardMoore(undigraph, combinations); - break; + paths = edwardMoore(undigraph, combinations); + break; default: err << "INTERNAL: wrong function call: " << which; return;