diff --git a/NEWS.md b/NEWS.md index 1be7654c95c..b492785002e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,10 @@ Bug Fixes * [#2966](https://github.com/pgRouting/pgrouting/issues/2966): pgr_withPoints does not pick optimal route when fraction = 1 +Code enhancement + +* [#3025](https://github.com/pgRouting/pgrouting/issues/3025): Ordering functions standardized + ## pgRouting 4.0 diff --git a/doc/src/pgRouting-introduction.rst b/doc/src/pgRouting-introduction.rst index 6a0660ddca7..f6e38adb6c1 100644 --- a/doc/src/pgRouting-introduction.rst +++ b/doc/src/pgRouting-introduction.rst @@ -63,7 +63,7 @@ Contributors This Release Contributors +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Individuals in this release v4.0.0 (in alphabetical order) +Individuals in this release |release| (in alphabetical order) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Mohit Rawat, diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index db3ae6065a2..0362d27f39d 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -46,6 +46,11 @@ Bug Fixes * :issue:`2966`: pgr_withPoints does not pick optimal route when fraction = 1 +Code enhancement +............................................................................... + +* :issue:`3025`: Ordering functions standardized + .. current pgRouting 4.0 diff --git a/include/c_types/i_rt.h b/include/c_common/enums.h similarity index 63% rename from include/c_types/i_rt.h rename to include/c_common/enums.h index f70d9a99333..4134f3bbbd5 100644 --- a/include/c_types/i_rt.h +++ b/include/c_common/enums.h @@ -1,41 +1,35 @@ /*PGR-GNU***************************************************************** -File: i_rt.h +File: enums.h -Copyright (c) 2015 pgRouting developers +Copyright (c) 2025 pgRouting developers Mail: project@pgrouting.org -Function's developer: -Copyright (c) 2019 Hang Wu -mail: nike0good@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*/ -/*! @file */ - -#ifndef INCLUDE_C_TYPES_I_RT_H_ -#define INCLUDE_C_TYPES_I_RT_H_ -#pragma once - -/* for int64_t */ -#ifdef __cplusplus -# include -#else -# include -#endif - -struct I_rt { - int64_t id; + + ********************************************************************PGR-GNU*/ + +#ifndef INCLUDE_C_COMMON_ENUMS_H_ +#define INCLUDE_C_COMMON_ENUMS_H_ + +enum Which { + /** undirected graph + results: vertex id */ + SLOAN = 0, CUTCHILL, KING, + /** directed graph + results: vertex id */ + TOPOSORT = 11 }; -#endif // INCLUDE_C_TYPES_I_RT_H_ +#endif // INCLUDE_C_COMMON_ENUMS_H_ diff --git a/include/cpp_common/basic_vertex.hpp b/include/cpp_common/basic_vertex.hpp index bcdf23b80dd..452175ba13d 100644 --- a/include/cpp_common/basic_vertex.hpp +++ b/include/cpp_common/basic_vertex.hpp @@ -64,6 +64,7 @@ class Basic_vertex { friend std::ostream& operator<<(std::ostream& log, const Basic_vertex &v); + public: int64_t id; }; diff --git a/include/cpp_common/to_postgres.hpp b/include/cpp_common/to_postgres.hpp index 7ae8d901f21..2fcbcbe7571 100644 --- a/include/cpp_common/to_postgres.hpp +++ b/include/cpp_common/to_postgres.hpp @@ -71,6 +71,31 @@ count_rows( } // namespace detail +/** @brief Vector of vertices id are saved on a C array + * + * @param[in] graph Created graph with the base Graph + * @param[in] data data[i] -> the ith element of the vector contains the vertex id + * @param[out] result_count The size of the vector + * @param[out] result_tuples The C array of bigint + * + * bigint results[i] + */ +template +void get_vertexId( + const G &graph, + const std::vector &data, + size_t &result_count, + int64_t **result_tuples) { + result_count = data.size(); + *result_tuples = pgrouting::pgr_alloc(result_count, (*result_tuples)); + + size_t seq = 0; + for (auto const &v : data) { + (*result_tuples)[seq] = graph.graph[v].id; + ++seq; + } +} + /** @brief Stored results on a vector are saved on a C array * * @param[in] graph Created graph with the base Graph diff --git a/include/drivers/ordering/cuthillMckeeOrdering_driver.h b/include/drivers/ordering/cuthillMckeeOrdering_driver.h deleted file mode 100644 index efd9582dc42..00000000000 --- a/include/drivers/ordering/cuthillMckeeOrdering_driver.h +++ /dev/null @@ -1,63 +0,0 @@ -/*PGR-GNU***************************************************************** -File: cuthillMckeeOrdering_driver.h - -Generated with Template by: -Copyright (c) 2022 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2022 Shobhit Chaurasia -Mail: 000shobhitchaurasia at 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_ORDERING_CUTHILLMCKEEORDERING_DRIVER_H_ -#define INCLUDE_DRIVERS_ORDERING_CUTHILLMCKEEORDERING_DRIVER_H_ - - -#ifdef __cplusplus -# include -# include -using Edge_t = struct Edge_t; -using II_t_rt = struct II_t_rt; -#else -# include -# include -typedef struct Edge_t Edge_t; -typedef struct II_t_rt II_t_rt; -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -void -pgr_do_cuthillMckeeOrdering( - const char*, - - II_t_rt**, size_t*, - char **, char **, char **); - - -#ifdef __cplusplus -} -#endif - -#endif // INCLUDE_DRIVERS_ORDERING_CUTHILLMCKEEORDERING_DRIVER_H_ diff --git a/include/drivers/ordering/topologicalSort_driver.h b/include/drivers/ordering/topologicalSort_driver.h deleted file mode 100644 index 627befd30b1..00000000000 --- a/include/drivers/ordering/topologicalSort_driver.h +++ /dev/null @@ -1,56 +0,0 @@ -/*PGR-GNU***************************************************************** - -File: topologicalSort_driver.h - -Generated with Template by: -Copyright (c) 2015 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2019 Hang Wu -mail: nike0good@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_ORDERING_TOPOLOGICALSORT_DRIVER_H_ -#define INCLUDE_DRIVERS_ORDERING_TOPOLOGICALSORT_DRIVER_H_ - -#ifdef __cplusplus -# include -using I_rt = struct I_rt; -#else -# include -typedef struct I_rt I_rt; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -void pgr_do_topologicalSort( - const char*, - - I_rt**, size_t*, - char**, char**, char**); - -#ifdef __cplusplus - } -#endif - -#endif // INCLUDE_DRIVERS_ORDERING_TOPOLOGICALSORT_DRIVER_H_ diff --git a/include/drivers/ordering_driver.hpp b/include/drivers/ordering_driver.hpp index 48b0eda8f63..38e7faf82fd 100644 --- a/include/drivers/ordering_driver.hpp +++ b/include/drivers/ordering_driver.hpp @@ -39,9 +39,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include +#include "c_common/enums.h" void do_ordering( - std::string, int, + const std::string&, Which, int64_t**, size_t*, char **, char **, char **); diff --git a/include/ordering/cuthillMckeeOrdering.hpp b/include/ordering/cuthillMckeeOrdering.hpp index 121b4b3258d..c358850a336 100644 --- a/include/ordering/cuthillMckeeOrdering.hpp +++ b/include/ordering/cuthillMckeeOrdering.hpp @@ -31,128 +31,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #define INCLUDE_ORDERING_CUTHILLMCKEEORDERING_HPP_ #pragma once -#include #include -#include -#include - -#include -#include -#include -#include -#include -#include - #include "cpp_common/base_graph.hpp" -#include "cpp_common/interruption.hpp" -#include "cpp_common/messages.hpp" - -#include "c_types/ii_t_rt.h" - -/** @file cuthillMckeeOrdering.hpp - * @brief The main file which calls the respective boost function. - * - * Contains actual implementation of the function and the calling - * of the respective boost function. - */ namespace pgrouting { namespace functions { -template -class CuthillMckeeOrdering : public Pgr_messages { - public: - typedef typename G::V V; - typedef typename G::E E; - typedef boost::adjacency_list Graph; - typedef boost::graph_traits::vertices_size_type size_type; - typedef boost::graph_traits::vertex_descriptor Vertex; - - /** @name CuthillMckeeOrdering - * @{ - * - */ - - /** @brief cuthillMckeeOrdering function - * - * It does all the processing and returns the results. - * - * @param graph the graph containing the edges - * - * @returns results, when results are found - * - * @see [boost::cuthill_mckee_ordering] - * (https://www.boost.org/libs/graph/doc/cuthill_mckee_ordering.html) - */ - - std::vector - cuthillMckeeOrdering(G &graph) { - std::vectorresults; - - // map which store the indices with their nodes. - auto i_map = boost::get(boost::vertex_index, graph.graph); - - // vector which will store the order of the indices. - std::vector inv_perm(boost::num_vertices(graph.graph)); - - // vector which will store the color of all the vertices in the graph - std::vector colors(boost::num_vertices(graph.graph)); - - // An iterator property map which records the color of each vertex - auto color_map = boost::make_iterator_property_map(&colors[0], i_map, colors[0]); - - // map which store the degree of each vertex. - auto out_deg = boost::make_out_degree_map(graph.graph); - - /* abort in case of an interruption occurs (e.g. the query is being cancelled) */ - CHECK_FOR_INTERRUPTS(); - - try { - boost::cuthill_mckee_ordering(graph.graph, inv_perm.rbegin(), color_map, out_deg); - } catch (boost::exception const& ex) { - (void)ex; - throw; - } catch (std::exception &e) { - (void)e; - throw; - } catch (...) { - throw; - } - - results = get_results(inv_perm, graph); - - return results; - } - - //@} - - private: - /** @brief to get the results - * - * Uses the `inv_perm` vector to get the results i.e. the ordering. - * - * @param inv_perm vector which contains the new ordering of indices. - * @param graph the graph containing the edges - * - * @returns `results` vector - */ - std::vector get_results( - std::vector & inv_perm, - const G &graph) { - std::vector results; - - for (std::vector::const_iterator i = inv_perm.begin(); - i != inv_perm.end(); ++i) { - log << inv_perm[*i] << " "; - auto seq = graph[*i].id; - results.push_back({{seq}, {static_cast(graph.graph[*i].id)}}); - seq++; - } +std::vector +cuthillMckeeOrdering(pgrouting::UndirectedGraph &graph); - return results; - } -}; } // namespace functions } // namespace pgrouting diff --git a/include/ordering/kingOrdering.hpp b/include/ordering/kingOrdering.hpp index 0b1e6a43822..f5d520f6b7b 100644 --- a/include/ordering/kingOrdering.hpp +++ b/include/ordering/kingOrdering.hpp @@ -32,54 +32,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #pragma once #include -#include -#include -#include -#include - -#include -#include -#include - - #include "cpp_common/base_graph.hpp" -#include "cpp_common/interruption.hpp" -#include - - -namespace pgrouting { - -template -std::vector -kingOrdering(G &graph) { - using V = typename G::V; - - size_t n = boost::num_vertices(graph.graph); - std::vector results(n); - - auto index_map = boost::get(boost::vertex_index, graph.graph); - - std::vector colors(n); - auto color_map = boost::make_iterator_property_map(colors.begin(), index_map); - auto degree_map = boost::make_degree_map(graph.graph); - std::vector inv_permutation(n); - CHECK_FOR_INTERRUPTS(); - boost::king_ordering( - graph.graph, - inv_permutation.rbegin(), - color_map, - degree_map, - index_map); - size_t j = 0; - for (auto i = inv_permutation.begin(); i != inv_permutation.end(); ++i, ++j) { - results[j] = static_cast(graph.graph[index_map[*i]].id); - } +namespace pgrouting { +namespace functions { - return results; -} +std::vector +kingOrdering(pgrouting::UndirectedGraph &graph); +} // namespace functions } // namespace pgrouting #endif // INCLUDE_ORDERING_KINGORDERING_HPP_ diff --git a/include/ordering/sloanOrdering.hpp b/include/ordering/sloanOrdering.hpp index 655b279bf59..5d99b601102 100644 --- a/include/ordering/sloanOrdering.hpp +++ b/include/ordering/sloanOrdering.hpp @@ -31,79 +31,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #define INCLUDE_ORDERING_SLOANORDERING_HPP_ #pragma once -#include #include -#include -#include - -#include -#include -#include -#include -#include -#include - #include "cpp_common/base_graph.hpp" -#include "cpp_common/interruption.hpp" -#include "cpp_common/messages.hpp" namespace pgrouting { namespace functions { -template -class SloanOrdering : public Pgr_messages { - public: - typedef typename G::V V; - typedef typename G::E E; - typedef boost::adjacency_list Graph; - typedef boost::graph_traits::vertices_size_type size_type; - typedef boost::graph_traits::vertex_descriptor Vertex; - - std::vector - sloanOrdering(G &graph) { - std::vectorresults; - - auto i_map = boost::get(boost::vertex_index, graph.graph); - std::vector inv_perm(boost::num_vertices(graph.graph)); - std::vector colors(boost::num_vertices(graph.graph)); - auto color_map = boost::make_iterator_property_map(&colors[0], i_map, colors[0]); - auto out_deg = boost::make_out_degree_map(graph.graph); - std::vector priorities(boost::num_vertices(graph.graph)); - auto priority_map = boost::make_iterator_property_map(&priorities[0], i_map, priorities[0]); - - CHECK_FOR_INTERRUPTS(); - - try { - boost::sloan_ordering(graph.graph, inv_perm.begin(), color_map, out_deg, priority_map); - } catch (boost::exception const& ex) { - (void)ex; - throw; - } catch (std::exception &e) { - (void)e; - throw; - } catch (...) { - throw; - } - - results = get_results(inv_perm, graph); - - return results; - } - - private: - std::vector get_results( - std::vector & inv_perm, - const G &graph) { - std::vector results; - for (std::vector::const_iterator i = inv_perm.begin(); - i != inv_perm.end(); ++i) { - log << inv_perm[*i] << " "; - results.push_back(static_cast(graph.graph[*i].id)); - } +std::vector +sloanOrdering(pgrouting::UndirectedGraph &graph); - return results; -} -}; } // namespace functions } // namespace pgrouting diff --git a/include/ordering/topologicalSort.hpp b/include/ordering/topologicalSort.hpp index 851706dd0ec..e76e0295742 100644 --- a/include/ordering/topologicalSort.hpp +++ b/include/ordering/topologicalSort.hpp @@ -1,6 +1,8 @@ /*PGR-GNU***************************************************************** + File: topologicalSort.hpp +Generated with Template by: Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org @@ -9,93 +11,38 @@ Copyright (c) 2019 Hang Wu mail: nike0good@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_ORDERING_TOPOLOGICALSORT_HPP_ #define INCLUDE_ORDERING_TOPOLOGICALSORT_HPP_ #pragma once - -#include -#include #include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "cpp_common/path.hpp" #include "cpp_common/base_graph.hpp" -#include "cpp_common/interruption.hpp" -#include "c_types//i_rt.h" - -// user's functions -// for development - -//****************************************** - -template < class G > -class Pgr_topologicalSort { - public: - typedef typename G::V V; - - std::vector topologicalSort( - G &graph); - - private: - std::vector< I_rt > - generatetopologicalSort( - const G &graph ) { - std::vector< I_rt > results; - - typedef typename std::vector< V > container; - container c; - - /* abort in case of an interruption occurs (e.g. the query is being cancelled) */ - CHECK_FOR_INTERRUPTS(); - - try { - boost::topological_sort(graph.graph, std::back_inserter(c)); - } catch (...) { - throw std::string("Graph is not DAG"); - } - typename std::vector< V >::reverse_iterator ii; - for (ii = c.rbegin(); ii != c.rend(); ++ii) { - auto t = *ii; - I_rt tmp; - tmp.id = graph.graph[t].id; - results.push_back(tmp); - } - return results; - } -}; +namespace pgrouting { +namespace functions { -template < class G > -std::vector -Pgr_topologicalSort< G >::topologicalSort( - G &graph) { - return generatetopologicalSort( - graph); -} +std::vector +topologicalSort(const pgrouting::DirectedGraph &graph); +} // namespace functions +} // namespace pgrouting #endif // INCLUDE_ORDERING_TOPOLOGICALSORT_HPP_ diff --git a/include/process/ordering_process.h b/include/process/ordering_process.h index 392b5e0ef58..87da1d0f054 100644 --- a/include/process/ordering_process.h +++ b/include/process/ordering_process.h @@ -38,11 +38,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #endif +#include "c_common/enums.h" #ifdef __cplusplus extern "C" { #endif -void pgr_process_ordering(const char*, int, int64_t**, size_t*); +void pgr_process_ordering(const char*, enum Which, int64_t**, size_t*); #ifdef __cplusplus } diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index 928380a0f6d..b66336eb746 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-01-06 18:37+0000\n" +"POT-Creation-Date: 2026-01-08 15:44+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -8323,7 +8323,7 @@ msgstr "" msgid "This Release Contributors" msgstr "" -msgid "Individuals in this release v4.0.0 (in alphabetical order)" +msgid "Individuals in this release |release| (in alphabetical order)" msgstr "" msgid "Mohit Rawat, Regina Obe, Vicky Vergara" @@ -16164,6 +16164,14 @@ msgid "" "pgr_withPoints does not pick optimal route when fraction = 1" msgstr "" +msgid "Code enhancement" +msgstr "" + +msgid "" +"`#3025 `__: Ordering " +"functions standardized" +msgstr "" + msgid "pgRouting 3" msgstr "" @@ -16436,9 +16444,6 @@ msgstr "" msgid "``pgr_lineGraph``" msgstr "``pgr_lineGraph``" -msgid "Code enhancement" -msgstr "" - msgid "" "`#2599 `__: Driving " "distance cleanup" diff --git a/locale/pot/pgrouting_doc_strings.pot b/locale/pot/pgrouting_doc_strings.pot index 4756c5b1b37..16353b5ed1d 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-01-06 18:37+0000\n" +"POT-Creation-Date: 2026-01-08 15:44+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -7144,7 +7144,7 @@ msgstr "" msgid "This Release Contributors" msgstr "" -msgid "Individuals in this release v4.0.0 (in alphabetical order)" +msgid "Individuals in this release |release| (in alphabetical order)" msgstr "" msgid "Mohit Rawat, Regina Obe, Vicky Vergara" @@ -13507,6 +13507,12 @@ msgstr "" msgid "`#2966 `__: pgr_withPoints does not pick optimal route when fraction = 1" msgstr "" +msgid "Code enhancement" +msgstr "" + +msgid "`#3025 `__: Ordering functions standardized" +msgstr "" + msgid "pgRouting 3" msgstr "" @@ -13705,9 +13711,6 @@ msgstr "" msgid "``pgr_lineGraph``" msgstr "" -msgid "Code enhancement" -msgstr "" - msgid "`#2599 `__: Driving distance cleanup" msgstr "" diff --git a/src/ordering/CMakeLists.txt b/src/ordering/CMakeLists.txt index 03380171c5d..4716b5de4ea 100644 --- a/src/ordering/CMakeLists.txt +++ b/src/ordering/CMakeLists.txt @@ -1,11 +1,14 @@ ADD_LIBRARY(ordering OBJECT kingOrdering.c cuthillMckeeOrdering.c - cuthillMckeeOrdering_driver.cpp sloanOrdering.c topologicalSort.c - topologicalSort_driver.cpp ordering_driver.cpp ordering_process.cpp + + cuthillMckeeOrdering.cpp + kingOrdering.cpp + sloanOrdering.cpp + topologicalSort.cpp ) diff --git a/src/ordering/cuthillMckeeOrdering.c b/src/ordering/cuthillMckeeOrdering.c index 6ac06bcdaa9..f0a25da5de2 100644 --- a/src/ordering/cuthillMckeeOrdering.c +++ b/src/ordering/cuthillMckeeOrdering.c @@ -32,57 +32,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_common/e_report.h" #include "c_common/time_msg.h" -#include "c_types/ii_t_rt.h" - - -#include "drivers/ordering/cuthillMckeeOrdering_driver.h" +#include "process/ordering_process.h" PGDLLEXPORT Datum _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(_pgr_cuthillmckeeordering); -static -void -process( - char* edges_sql, - - II_t_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_cuthillMckeeOrdering( - edges_sql, - - result_tuples, - result_count, - &log_msg, - ¬ice_msg, - &err_msg); - time_msg("processing cuthillmckeeordering", start_t, clock()); - - if (err_msg && (*result_tuples)) { - pfree(*result_tuples); - (*result_tuples) = NULL; - (*result_count) = 0; - } - - pgr_global_report(&log_msg, ¬ice_msg, &err_msg); - - pgr_SPI_finish(); -} PGDLLEXPORT Datum _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - II_t_rt *result_tuples = NULL; + int64_t *result_tuples = NULL; size_t result_count = 0; if (SRF_IS_FIRSTCALL()) { @@ -90,8 +51,10 @@ _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS) { funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - process( + + pgr_process_ordering( text_to_cstring(PG_GETARG_TEXT_P(0)), + CUTCHILL, &result_tuples, &result_count); @@ -111,7 +74,7 @@ _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS) { funcctx = SRF_PERCALL_SETUP(); tuple_desc = funcctx->tuple_desc; - result_tuples = (II_t_rt*) funcctx->user_fctx; + result_tuples = (int64_t*) funcctx->user_fctx; if (funcctx->call_cntr < funcctx->max_calls) { HeapTuple tuple; @@ -119,7 +82,7 @@ _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - size_t num = 3; + size_t num = 2; values = palloc(num * sizeof(Datum)); nulls = palloc(num * sizeof(bool)); @@ -130,7 +93,7 @@ _pgr_cuthillmckeeordering(PG_FUNCTION_ARGS) { } values[0] = Int64GetDatum((int64_t)funcctx->call_cntr + 1); - values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].d2.value); + values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr]); tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); diff --git a/src/ordering/cuthillMckeeOrdering.cpp b/src/ordering/cuthillMckeeOrdering.cpp new file mode 100644 index 00000000000..c8d995d4a5f --- /dev/null +++ b/src/ordering/cuthillMckeeOrdering.cpp @@ -0,0 +1,100 @@ +/*PGR-GNU***************************************************************** +File: cuthillMckeeOrdering.cpp + +Generated with Template by: +Copyright (c) 2022 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2022 Shobhit Chaurasia +Mail: 000shobhitchaurasia at 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 "ordering/cuthillMckeeOrdering.hpp" + +#include +#include + +#include + +#include "cpp_common/base_graph.hpp" +#include "cpp_common/interruption.hpp" +#include + +#include + + +namespace pgrouting { +namespace functions { + + +/** @brief cuthillMckeeOrdering function + * + * It does all the processing and returns the results. + * + * @param graph the graph containing the edges + * + * @returns results, when results are found + * + * @see [boost::cuthill_mckee_ordering] + * (https://www.boost.org/libs/graph/doc/cuthill_mckee_ordering.html) + */ +std::vector +cuthillMckeeOrdering(pgrouting::UndirectedGraph &graph) { + using V = typename pgrouting::UndirectedGraph::V; + + /* number of vertices */ + size_t n = boost::num_vertices(graph.graph); + + /* map which store the indices with their nodes. */ + auto index_map = boost::get(boost::vertex_index, graph.graph); + + /* vector which will store the order of the indices. */ + std::vector inv_permutation(n); + + /* vector which will store the color of all the vertices in the graph */ + std::vector colors(n); + + /* An iterator property map which records the color of each vertex */ + auto color_map = boost::make_iterator_property_map(colors.begin(), index_map, colors[0]); + + /* map which store the degree of each vertex. */ + auto degree_map = boost::make_out_degree_map(graph.graph); + + + CHECK_FOR_INTERRUPTS(); + + try { + boost::cuthill_mckee_ordering(graph.graph, inv_permutation.rbegin(), color_map, degree_map); + } catch (boost::exception const& ex) { + (void)ex; + throw; + } catch (std::exception &e) { + (void)e; + throw; + } catch (...) { + throw; + } + + return inv_permutation; +} + +} // namespace functions +} // namespace pgrouting diff --git a/src/ordering/cuthillMckeeOrdering_driver.cpp b/src/ordering/cuthillMckeeOrdering_driver.cpp deleted file mode 100644 index 0666270c7f3..00000000000 --- a/src/ordering/cuthillMckeeOrdering_driver.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*PGR-GNU***************************************************************** -File: cuthillMckeeOrdering_driver.cpp -Generated with Template by: -Copyright (c) 2022 pgRouting developers -Mail: project@pgrouting.org -Function's developer: -Copyright (c) 2022 Shobhit Chaurasia -Mail: 000shobhitchaurasia at 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/ordering/cuthillMckeeOrdering_driver.h" - -#include -#include -#include -#include - -#include "cpp_common/pgdata_getters.hpp" -#include "cpp_common/alloc.hpp" -#include "cpp_common/assert.hpp" -#include "c_types/ii_t_rt.h" - -#include "ordering/cuthillMckeeOrdering.hpp" - -/** @file cuthillMckeeOrdering_driver.cpp - * @brief Handles actual calling of function in the `cuthillMckeeOrdering.hpp` file. - * - */ - -/*********************************************************************** - * - * pgr_cuthillMckeeOrdering(edges_sql TEXT); - * - ***********************************************************************/ - -namespace { - -/** @brief Calls the main function defined in the C++ Header file. - * - * @param graph the graph containing the edges - * - * @returns results, when results are found - */ - -template -std::vector -cuthillMckeeOrdering(G &graph) { - pgrouting::functions::CuthillMckeeOrdering fn_cuthillMckeeOrdering; - auto results = fn_cuthillMckeeOrdering.cuthillMckeeOrdering(graph); - return results; -} - -} // namespace - - -void pgr_do_cuthillMckeeOrdering( - const char *edges_sql, - - II_t_rt **return_tuples, - size_t *return_count, - - char **log_msg, - char **notice_msg, - char **err_msg) { - using pgrouting::pgr_alloc; - using pgrouting::to_pg_msg; - using pgrouting::pgr_free; - - std::ostringstream log; - std::ostringstream err; - std::ostringstream notice; - const char *hint = nullptr; - - try { - pgassert(!(*log_msg)); - pgassert(!(*notice_msg)); - pgassert(!(*err_msg)); - pgassert(!(*return_tuples)); - pgassert(*return_count == 0); - - hint = edges_sql; - auto edges = pgrouting::pgget::get_edges(std::string(edges_sql), true, 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::vectorresults; - pgrouting::UndirectedGraph undigraph; - undigraph.insert_edges(edges); - results = cuthillMckeeOrdering(undigraph); - - auto count = results.size(); - - if (count == 0) { - (*return_tuples) = NULL; - (*return_count) = 0; - notice << "No results found"; - *log_msg = to_pg_msg(log); - } - - (*return_tuples) = pgr_alloc(count, (*return_tuples)); - for (size_t i = 0; i < count; i++) { - *((*return_tuples) + i) = results[i]; - } - (*return_count) = count; - - pgassert(*err_msg == NULL); - *log_msg = log.str().empty() ? - *log_msg : - to_pg_msg(log); - *notice_msg = notice.str().empty() ? - *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/ordering/kingOrdering.c b/src/ordering/kingOrdering.c index e44aebf80a3..192b98198b3 100644 --- a/src/ordering/kingOrdering.c +++ b/src/ordering/kingOrdering.c @@ -54,7 +54,7 @@ _pgr_kingordering(PG_FUNCTION_ARGS) { pgr_process_ordering( text_to_cstring(PG_GETARG_TEXT_P(0)), - 2, /*King Ordering*/ + KING, /*King Ordering*/ &result_tuples, &result_count); diff --git a/src/ordering/kingOrdering.cpp b/src/ordering/kingOrdering.cpp new file mode 100644 index 00000000000..e8af104acc6 --- /dev/null +++ b/src/ordering/kingOrdering.cpp @@ -0,0 +1,87 @@ +/*PGR-GNU***************************************************************** +File: kingOrdering.cpp + +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 Fan Wu +Mail: wifiblack0131 at 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 "ordering/kingOrdering.hpp" + +#include +#include + +#include + +#include "cpp_common/base_graph.hpp" +#include "cpp_common/interruption.hpp" +#include + +#include + +namespace pgrouting { +namespace functions { + +std::vector +kingOrdering(pgrouting::UndirectedGraph &graph) { + using V = typename pgrouting::UndirectedGraph::V; + + /* number of vertices */ + size_t n = boost::num_vertices(graph.graph); + + /* map which store the indices with their nodes. */ + auto index_map = boost::get(boost::vertex_index, graph.graph); + + /* vector which will store the order of the indices. */ + std::vector inv_permutation(n); + + /* vector which will store the color of all the vertices in the graph */ + std::vector colors(n); + + /* An iterator property map which records the color of each vertex */ + auto color_map = boost::make_iterator_property_map(colors.begin(), index_map, colors[0]); + + /* map which store the degree of each vertex. */ + auto degree_map = boost::make_degree_map(graph.graph); + + + CHECK_FOR_INTERRUPTS(); + + try { + boost::king_ordering(graph.graph, inv_permutation.rbegin(), color_map, degree_map, index_map); + } catch (boost::exception const& ex) { + (void)ex; + throw; + } catch (std::exception &e) { + (void)e; + throw; + } catch (...) { + throw; + } + + return inv_permutation; +} + +} // namespace functions +} // namespace pgrouting diff --git a/src/ordering/ordering_driver.cpp b/src/ordering/ordering_driver.cpp index 67e7e869a85..9fb69ffdbbc 100644 --- a/src/ordering/ordering_driver.cpp +++ b/src/ordering/ordering_driver.cpp @@ -37,29 +37,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include #include - +#include #include "cpp_common/pgdata_getters.hpp" -#include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" +#include "cpp_common/to_postgres.hpp" #include "ordering/sloanOrdering.hpp" #include "ordering/kingOrdering.hpp" +#include "ordering/cuthillMckeeOrdering.hpp" +#include "ordering/topologicalSort.hpp" -namespace { -template -std::vector -sloanOrdering(G &graph) { - pgrouting::functions::SloanOrdering fn_sloanOrdering; - auto results = fn_sloanOrdering.sloanOrdering(graph); - return results; -} +template +void +process(const std::vector &edges, G &graph, Func ordering, + size_t &return_count, + int64_t **return_tuples) { + using pgrouting::to_postgres::get_vertexId; + graph.insert_edges(edges); + auto results = ordering(graph); + get_vertexId(graph, results, return_count, return_tuples); } void do_ordering( - std::string edges_sql, - int which, + const std::string &edges_sql, + Which which, int64_t **return_tuples, size_t *return_count, @@ -67,13 +70,18 @@ do_ordering( char **log_msg, char **notice_msg, char **err_msg) { - using pgrouting::pgr_alloc; using pgrouting::to_pg_msg; using pgrouting::pgr_free; - using pgrouting::kingOrdering; using pgrouting::pgget::get_edges; using pgrouting::UndirectedGraph; + using pgrouting::DirectedGraph; + using pgrouting::to_postgres::get_vertexId; + + using pgrouting::functions::sloanOrdering; + using pgrouting::functions::kingOrdering; + using pgrouting::functions::cuthillMckeeOrdering; + using pgrouting::functions::topologicalSort; std::ostringstream log; std::ostringstream err; @@ -88,46 +96,54 @@ do_ordering( pgassert(*return_count == 0); hint = edges_sql; - auto edges = get_edges(std::string(edges_sql), true, false); + auto edges = get_edges(edges_sql, true, false); if (edges.empty()) { *notice_msg = to_pg_msg("No edges found"); + *log_msg = to_pg_msg(hint); *return_tuples = nullptr; *return_count = 0; return; } hint = ""; - std::vector results; - - auto vertices(pgrouting::extract_vertices(edges)); - UndirectedGraph undigraph(vertices); - undigraph.insert_edges(edges); - if (which == 0) { - results = sloanOrdering(undigraph); - } else if (which == 2) { - results = kingOrdering(undigraph); + auto vertices = which == 0 || which == 2? + pgrouting::extract_vertices(edges) + : std::vector(); + + UndirectedGraph undigraph = which < 11? UndirectedGraph(vertices) : UndirectedGraph(); + DirectedGraph digraph = which >= 11? DirectedGraph(vertices) : DirectedGraph();; + + + switch (which) { + case SLOAN: { + process(edges, undigraph, &sloanOrdering, *return_count, return_tuples); + break; + } + case CUTCHILL: { + process(edges, undigraph, &cuthillMckeeOrdering, *return_count, return_tuples); + break; + } + case KING: { + process(edges, undigraph, &kingOrdering, *return_count, return_tuples); + break; + } + case TOPOSORT: { + process(edges, digraph, &topologicalSort, *return_count, return_tuples); + break; + } + default: + break; } - auto count = results.size(); - - if (count == 0) { - *notice_msg = to_pg_msg("No results found \n"); - *err_msg = to_pg_msg(err); + if ((*return_count) == 0) { + *notice_msg = to_pg_msg("No results found"); *return_tuples = nullptr; *return_count = 0; return; } - (*return_tuples) = pgr_alloc(count, (*return_tuples)); - - for (size_t i = 0; i < count; ++i) { - (*return_tuples)[i] = results[i]; - } - - (*return_count) = count; - - pgassert(*err_msg == NULL); + pgassert(*err_msg == nullptr); *log_msg = to_pg_msg(log); *notice_msg = to_pg_msg(notice); } catch (AssertFailedException &except) { diff --git a/src/ordering/ordering_process.cpp b/src/ordering/ordering_process.cpp index 4f58d7b5c72..bd81c0108c6 100644 --- a/src/ordering/ordering_process.cpp +++ b/src/ordering/ordering_process.cpp @@ -49,7 +49,7 @@ extern "C" { */ void pgr_process_ordering( const char* edges_sql, - int which, + enum Which which, int64_t **result_tuples, size_t *result_count) { pgassert(edges_sql); @@ -67,12 +67,21 @@ void pgr_process_ordering( result_tuples, result_count, &log_msg , ¬ice_msg, &err_msg); - if (which == 0) { - time_msg(std::string(" processing pgr_sloanOrdering").c_str(), start_t, clock()); - } else if (which == 1) { - time_msg(std::string("processing pgr_cuthillMckeeOrdering").c_str(), start_t, clock()); - } else if (which == 2) { - time_msg(std::string("processing pgr_kingOrdering").c_str(), start_t, clock()); + switch (which) { + case SLOAN: + time_msg(std::string(" processing pgr_sloanOrdering").c_str(), start_t, clock()); + break; + case CUTCHILL: + time_msg(std::string(" processing pgr_cuthillMckeeOrdering").c_str(), start_t, clock()); + break; + case KING: + time_msg(std::string(" processing pgr_kingOrdering").c_str(), start_t, clock()); + break; + case TOPOSORT: + time_msg(std::string(" processing pgr_topologicalSort").c_str(), start_t, clock()); + break; + default: + break; } if (err_msg && (*result_tuples)) { diff --git a/src/ordering/sloanOrdering.c b/src/ordering/sloanOrdering.c index 25f61676b43..094567bad1b 100644 --- a/src/ordering/sloanOrdering.c +++ b/src/ordering/sloanOrdering.c @@ -54,7 +54,7 @@ _pgr_sloanordering(PG_FUNCTION_ARGS) { pgr_process_ordering( text_to_cstring(PG_GETARG_TEXT_P(0)), - 0, /* Sloan */ + SLOAN, /* Sloan */ &result_tuples, &result_count); diff --git a/src/ordering/sloanOrdering.cpp b/src/ordering/sloanOrdering.cpp new file mode 100644 index 00000000000..a3c5a96ce91 --- /dev/null +++ b/src/ordering/sloanOrdering.cpp @@ -0,0 +1,92 @@ +/*PGR-GNU***************************************************************** +File: sloanOrdering.cpp + +Generated with Template by: +Copyright (c) 2022 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2025 Bipasha Gayary +Mail: bipashagayary at 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 "ordering/sloanOrdering.hpp" + +#include +#include + +#include + +#include "cpp_common/base_graph.hpp" +#include "cpp_common/interruption.hpp" +#include + +#include + +namespace pgrouting { +namespace functions { + +std::vector +sloanOrdering(pgrouting::UndirectedGraph &graph) { + using V = typename pgrouting::UndirectedGraph::V; + + /* number of vertices */ + size_t n = boost::num_vertices(graph.graph); + + /* map which store the indices with their nodes. */ + auto index_map = boost::get(boost::vertex_index, graph.graph); + + /* vector which will store the order of the indices. */ + std::vector inv_permutation(n); + + /* vector which will store the color of all the vertices in the graph */ + std::vector colors(n); + + /* An iterator property map which records the color of each vertex */ + auto color_map = boost::make_iterator_property_map(colors.begin(), index_map, colors[0]); + + /* map which store the degree of each vertex. */ + auto degree_map = boost::make_out_degree_map(graph.graph); + + /* store the priority of each vertex. */ + std::vector priorities(n); + + /* Iterator over priorities */ + auto priority_map = boost::make_iterator_property_map(&priorities[0], index_map, priorities[0]); + + CHECK_FOR_INTERRUPTS(); + + try { + boost::sloan_ordering(graph.graph, inv_permutation.begin(), color_map, degree_map, priority_map); + } catch (boost::exception const& ex) { + (void)ex; + throw; + } catch (std::exception &e) { + (void)e; + throw; + } catch (...) { + throw; + } + + return inv_permutation; +} + +} // namespace functions +} // namespace pgrouting diff --git a/src/ordering/topologicalSort.c b/src/ordering/topologicalSort.c index 6c567e26322..14fc08f4296 100644 --- a/src/ordering/topologicalSort.c +++ b/src/ordering/topologicalSort.c @@ -28,57 +28,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ #include - #include "c_common/postgres_connection.h" -#include "c_types/i_rt.h" #include "c_common/debug_macro.h" #include "c_common/e_report.h" #include "c_common/time_msg.h" -#include "drivers/ordering/topologicalSort_driver.h" + +#include "process/ordering_process.h" PGDLLEXPORT Datum _pgr_topologicalsort(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(_pgr_topologicalsort); -static -void -process( - char* edges_sql, - I_rt **result_tuples, - size_t *result_count) { - pgr_SPI_connect(); - char* log_msg = NULL; - char* notice_msg = NULL; - char* err_msg = NULL; - - clock_t start_t = clock(); - pgr_do_topologicalSort( - edges_sql, - result_tuples, - result_count, - &log_msg, - ¬ice_msg, - &err_msg); - - time_msg("processing pgr_topologicalSort", start_t, clock()); - - if (err_msg && (*result_tuples)) { - pfree(*result_tuples); - (*result_tuples) = NULL; - (*result_count) = 0; - } - - pgr_global_report(&log_msg, ¬ice_msg, &err_msg); - - pgr_SPI_finish(); -} - PGDLLEXPORT Datum _pgr_topologicalsort(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; - TupleDesc tuple_desc; + TupleDesc tuple_desc; - I_rt *result_tuples = NULL; + int64_t *result_tuples = NULL; size_t result_count = 0; if (SRF_IS_FIRSTCALL()) { @@ -86,13 +52,13 @@ _pgr_topologicalsort(PG_FUNCTION_ARGS) { funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - process( + pgr_process_ordering( text_to_cstring(PG_GETARG_TEXT_P(0)), + TOPOSORT, &result_tuples, &result_count); funcctx->max_calls = result_count; - funcctx->user_fctx = result_tuples; if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE) { @@ -108,26 +74,25 @@ _pgr_topologicalsort(PG_FUNCTION_ARGS) { funcctx = SRF_PERCALL_SETUP(); tuple_desc = funcctx->tuple_desc; - result_tuples = (I_rt*) funcctx->user_fctx; + result_tuples = (int64_t*) funcctx->user_fctx; if (funcctx->call_cntr < funcctx->max_calls) { HeapTuple tuple; Datum result; Datum *values; bool* nulls; - size_t call_cntr = funcctx->call_cntr; - size_t numb = 2; - values = palloc(numb * sizeof(Datum)); - nulls = palloc(numb * sizeof(bool)); + size_t num = 2; + values = palloc(num * sizeof(Datum)); + nulls = palloc(num * sizeof(bool)); size_t i; - for (i = 0; i < numb; ++i) { + for (i = 0; i < num; ++i) { nulls[i] = false; } - values[0] = Int32GetDatum((int32_t)call_cntr + 1); - values[1] = Int64GetDatum(result_tuples[call_cntr].id); + values[0] = Int64GetDatum((int64_t)funcctx->call_cntr + 1); + values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr]); tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); diff --git a/src/ordering/topologicalSort.cpp b/src/ordering/topologicalSort.cpp new file mode 100644 index 00000000000..1096d6ac741 --- /dev/null +++ b/src/ordering/topologicalSort.cpp @@ -0,0 +1,71 @@ +/*PGR-GNU***************************************************************** +File: topologicalSort.cpp + +Copyright (c) 2015 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2019 Hang Wu +mail: nike0good@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 "ordering/topologicalSort.hpp" + +#include +#include +#include +#include + +#include + +#include "cpp_common/base_graph.hpp" +#include "cpp_common/interruption.hpp" +#include + +#include + +namespace pgrouting { +namespace functions { + +std::vector +topologicalSort(const pgrouting::DirectedGraph &graph) { + using V = typename pgrouting::DirectedGraph::V; + + std::vector results; + + CHECK_FOR_INTERRUPTS(); + + try { + boost::topological_sort(graph.graph, std::back_inserter(results)); + } catch (boost::exception const& ex) { + throw std::string("Graph is not DAG"); + } catch (std::exception &e) { + (void)e; + throw; + } catch (...) { + throw; + } + + std::reverse(results.begin(), results.end()); + return results; +} + +} // namespace functions +} // namespace pgrouting diff --git a/src/ordering/topologicalSort_driver.cpp b/src/ordering/topologicalSort_driver.cpp deleted file mode 100644 index 94f47063722..00000000000 --- a/src/ordering/topologicalSort_driver.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/*PGR-GNU***************************************************************** -File: topologicalSort_driver.cpp - -Generated with Template by: -Copyright (c) 2015 pgRouting developers -Mail: project@pgrouting.org - -Function's developer: -Copyright (c) 2019 Hang Wu -mail: nike0good@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/ordering/topologicalSort_driver.h" - -#include -#include -#include -#include -#include -#include - -#include "ordering/topologicalSort.hpp" - -#include "c_types/i_rt.h" -#include "cpp_common/pgdata_getters.hpp" -#include "cpp_common/alloc.hpp" -#include "cpp_common/assert.hpp" - -namespace { - -template < class G > -std::vector -pgr_topologicalSort( - G &graph) { - Pgr_topologicalSort< G > fn_topologicalSort; - return fn_topologicalSort.topologicalSort(graph); -} - -} // namespace - -// CREATE OR REPLACE FUNCTION pgr_topologicalSort( -// sql text, -void -pgr_do_topologicalSort( - const char *edges_sql, - - I_rt **return_tuples, - size_t *return_count, - char ** log_msg, - char ** notice_msg, - char ** err_msg) { - using pgrouting::pgr_alloc; - using pgrouting::to_pg_msg; - using pgrouting::pgr_free; - - std::ostringstream log; - std::ostringstream err; - std::ostringstream notice; - const char *hint = nullptr; - - try { - pgassert(!(*log_msg)); - pgassert(!(*notice_msg)); - pgassert(!(*err_msg)); - pgassert(!(*return_tuples)); - pgassert(*return_count == 0); - - hint = edges_sql; - auto edges = pgrouting::pgget::get_edges(std::string(edges_sql), true, 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::vector results; - pgrouting::DirectedGraph digraph; - digraph.insert_edges(edges); - results = pgr_topologicalSort( - digraph); - - auto count = results.size(); - - if (count == 0) { - (*return_tuples) = NULL; - (*return_count) = 0; - notice << - "No vertices"; - return; - } - - (*return_tuples) = pgr_alloc(count, (*return_tuples)); - for (size_t i = 0; i < count; i++) { - *((*return_tuples) + i) = results[i]; - } - (*return_count) = count; - - pgassert(*err_msg == NULL); - *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); - } -}