diff --git a/NEWS b/NEWS index 548dd2517b1..d6a3659bdca 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,30 @@ pgRouting 3.6.0 Release Notes ------------------------------------------------------------------------------- -No Changes Yet +**C/C++ code enhancements** + +* `2504 ` To C++ pg data get, + fetch and check. + + * Stopping support for compilation with MSVC. + +* `2505 ` Using namespace. +* `2512 ` [Dijkstra] Removing + duplicate code on Dijkstra. + +**Documentation** + +* `2490 ` Automatic page + history links. pgRouting 3.5.1 Release Notes ------------------------------------------------------------------------------- -No Changes Yet +**C/C++ code enhancements** + +* `2496 ` Grouping headers. +* `2497 ` Arrays input to C++. + pgRouting 3.5.0 Release Notes ------------------------------------------------------------------------------- diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 7291ac2ae33..dad2628a622 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -19,17 +19,33 @@ To see the full list of changes check the list of `Git commits .. contents:: Contents :local: - - pgRouting 3.6.0 Release Notes ------------------------------------------------------------------------------- -No Changes Yet +.. rubric:: C/C++ code enhancements + +* `2504 ` To C++ pg data get, + fetch and check. + + * Stopping support for compilation with MSVC. + +* `2505 ` Using namespace. +* `2512 ` [Dijkstra] Removing + duplicate code on Dijkstra. + +.. rubric:: Documentation + +* `2490 ` Automatic page + history links. pgRouting 3.5.1 Release Notes ------------------------------------------------------------------------------- -No Changes Yet +.. rubric:: C/C++ code enhancements + +* `2496 ` Grouping headers. +* `2497 ` Arrays input to C++. + pgRouting 3.5.0 Release Notes ------------------------------------------------------------------------------- diff --git a/include/drivers/dijkstra/dijkstra_driver.h b/include/drivers/dijkstra/dijkstra_driver.h index cf80ceb60fc..84d85112960 100644 --- a/include/drivers/dijkstra/dijkstra_driver.h +++ b/include/drivers/dijkstra/dijkstra_driver.h @@ -7,12 +7,13 @@ Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev Copyright (c) 2020 The combinations_sql signature is added by Mahmoud SAKR and Esteban ZIMANYI -mail: m_attia_sakr@yahoo.com, estebanzimanyi@gmail.com +mail: m_attia_sakr at yahoo.com, estebanzimanyi at gmail.com ------ @@ -35,7 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #ifndef INCLUDE_DRIVERS_DIJKSTRA_DIJKSTRA_DRIVER_H_ #define INCLUDE_DRIVERS_DIJKSTRA_DIJKSTRA_DRIVER_H_ -/* for size-t */ #ifdef __cplusplus # include # include @@ -54,50 +54,21 @@ typedef struct II_t_rt II_t_rt; extern "C" { #endif - void do_pgr_many_to_many_dijkstra( - Edge_t *data_edges, - size_t total_tuples, - int64_t *start_vidsArr, - size_t size_start_vidsArr, - int64_t *end_vidsArr, - size_t size_end_vidsArr, - bool directed, - bool only_cost, - bool normal, - int64_t n_goals, - bool global, - - Path_rt **return_tuples, - size_t *return_count, - - char** log_msg, - char** notice_msg, - char** err_msg); - - - // CREATE OR REPLACE FUNCTION pgr_dijkstra( - // sql text, - // combinations_sql text, - // directed boolean default true, - void do_pgr_combinations_dijkstra( - Edge_t *data_edges, - size_t total_tuples, - II_t_rt *combinations, - size_t total_combinations, - bool directed, - bool only_cost, - bool normal, - int64_t n_goals, - bool global, - - Path_rt **return_tuples, - size_t *return_count, - - char** log_msg, - char** notice_msg, - char** err_msg); +void pgr_do_dijkstra( + Edge_t*, size_t, + II_t_rt*, size_t, + int64_t*, size_t, + int64_t*, size_t, + + bool, bool, bool, + int64_t, bool, + + Path_rt**, size_t*, + char**, char**, char**); + + #ifdef __cplusplus - } +} #endif #endif // INCLUDE_DRIVERS_DIJKSTRA_DIJKSTRA_DRIVER_H_ diff --git a/src/dijkstra/dijkstra.c b/src/dijkstra/dijkstra.c index 787be235080..081df9dc78b 100644 --- a/src/dijkstra/dijkstra.c +++ b/src/dijkstra/dijkstra.c @@ -1,18 +1,19 @@ /*PGR-GNU***************************************************************** -File: many_to_many_dijkstra.c +File: dijkstra.c Generated with Template by: Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev Copyright (c) 2020 The combinations_sql signature is added by Mahmoud SAKR and Esteban ZIMANYI -mail: m_attia_sakr@yahoo.com, estebanzimanyi@gmail.com +mail: m_attia_sakr at yahoo.com, estebanzimanyi at gmail.com ------ @@ -51,14 +52,17 @@ PG_FUNCTION_INFO_V1(_pgr_dijkstra); static void process( - char* edges_sql, + char *edges_sql, + char* combinations_sql, ArrayType *starts, ArrayType *ends, + bool directed, bool only_cost, bool normal, int64_t n_goals, bool global, + Path_rt **result_tuples, size_t *result_count) { pgr_SPI_connect(); @@ -74,14 +78,23 @@ process( Edge_t *edges = NULL; size_t total_edges = 0; + + II_t_rt *combinationsArr = NULL; + size_t total_combinations = 0; + if (normal) { pgr_get_edges(edges_sql, &edges, &total_edges, true, false, &err_msg); throw_error(err_msg, edges_sql); - start_vidsArr = pgr_get_bigIntArray(&size_start_vidsArr, starts, false, &err_msg); - throw_error(err_msg, "While getting start vids"); - end_vidsArr = (int64_t*) - pgr_get_bigIntArray(&size_end_vidsArr, ends, false, &err_msg); - throw_error(err_msg, "While getting end vids"); + + if (combinations_sql) { + pgr_get_combinations(combinations_sql, &combinationsArr, &total_combinations, &err_msg); + throw_error(err_msg, combinations_sql); + } else { + start_vidsArr = pgr_get_bigIntArray(&size_start_vidsArr, starts, false, &err_msg); + throw_error(err_msg, "While getting start vids"); + end_vidsArr = pgr_get_bigIntArray(&size_end_vidsArr, ends, false, &err_msg); + throw_error(err_msg, "While getting end vids"); + } } else { pgr_get_edges(edges_sql, &edges, &total_edges, false, false, &err_msg); throw_error(err_msg, edges_sql); @@ -94,13 +107,21 @@ process( if (total_edges == 0) { if (end_vidsArr) pfree(end_vidsArr); if (start_vidsArr) pfree(start_vidsArr); + if (combinationsArr) pfree(combinationsArr); + pgr_SPI_finish(); + return; + } + + if (total_combinations == 0 && (size_end_vidsArr== 0 || size_end_vidsArr == 0)) { + if (edges) pfree(edges); pgr_SPI_finish(); return; } clock_t start_t = clock(); - do_pgr_many_to_many_dijkstra( + pgr_do_dijkstra( edges, total_edges, + combinationsArr, total_combinations, start_vidsArr, size_start_vidsArr, end_vidsArr, size_end_vidsArr, @@ -146,124 +167,28 @@ process( if (edges) pfree(edges); if (start_vidsArr) pfree(start_vidsArr); if (end_vidsArr) pfree(end_vidsArr); + if (combinationsArr) pfree(combinationsArr); pgr_SPI_finish(); } - - -static -void -process_combinations( - char* edges_sql, - char* combinations_sql, - bool directed, - bool only_cost, - int64_t n_goals, - bool global, - Path_rt **result_tuples, - size_t *result_count) { - pgr_SPI_connect(); - char* log_msg = NULL; - char* notice_msg = NULL; - char* err_msg = NULL; - - Edge_t *edges = NULL; - size_t total_edges = 0; - - II_t_rt *combinations = NULL; - size_t total_combinations = 0; - - pgr_get_edges(edges_sql, &edges, &total_edges, true, false, &err_msg); - throw_error(err_msg, edges_sql); - - if (total_edges == 0) { - pgr_SPI_finish(); - return; - } - pgr_get_combinations(combinations_sql, &combinations, &total_combinations, &err_msg); - throw_error(err_msg, combinations_sql); - if (total_combinations == 0) { - if (edges) pfree(edges); - pgr_SPI_finish(); - return; - } - - clock_t start_t = clock(); - do_pgr_combinations_dijkstra( - edges, total_edges, - combinations, total_combinations, - directed, - only_cost, - true, - n_goals, - global, - - result_tuples, - result_count, - - &log_msg, - ¬ice_msg, - &err_msg); - - if (only_cost) { - if (n_goals > 0) { - time_msg("Processing pgr_dijkstraNearCost", start_t, clock()); - } else { - time_msg("Processing pgr_dijkstraCost", start_t, clock()); - } - } else { - if (n_goals > 0) { - time_msg("Processing pgr_dijkstraNear", start_t, clock()); - } else { - time_msg("Processing pgr_dijkstra", start_t, clock()); - } - } - - if (err_msg && (*result_tuples)) { - pfree(*result_tuples); - (*result_tuples) = NULL; - (*result_count) = 0; - } - - pgr_global_report(log_msg, notice_msg, err_msg); - - if (log_msg) pfree(log_msg); - if (notice_msg) pfree(notice_msg); - if (err_msg) pfree(err_msg); - if (edges) pfree(edges); - if (combinations) pfree(combinations); - pgr_SPI_finish(); -} - - - - PGDLLEXPORT Datum _pgr_dijkstra(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tuple_desc; - /**********************************************************************/ Path_rt *result_tuples = NULL; size_t result_count = 0; - /**********************************************************************/ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); if (PG_NARGS() == 7) { - /**********************************************************************/ - // pgr_dijkstra( - // sql TEXT, - // start_vids ANYARRAY, - // end_vids ANYARRAY, - // directed BOOLEAN default true, - // only_cost BOOLEAN default false - // normal BOOLEAN default true - + /* kept for backwards compatibility + * TODO remove on 4.0.0 */ process( text_to_cstring(PG_GETARG_TEXT_P(0)), + NULL, PG_GETARG_ARRAYTYPE_P(1), PG_GETARG_ARRAYTYPE_P(2), PG_GETARG_BOOL(3), @@ -274,27 +199,23 @@ _pgr_dijkstra(PG_FUNCTION_ARGS) { &result_tuples, &result_count); - /**********************************************************************/ } else if (PG_NARGS() == 5) { - /**********************************************************************/ - // pgr_dijkstra( - // edge_sql TEXT, - // combinations_sql TEXT, - // directed BOOLEAN default true, - // only_cost BOOLEAN default false - - process_combinations( + /* kept for backwards compatibility + * TODO remove on 4.0.0 */ + process( text_to_cstring(PG_GETARG_TEXT_P(0)), text_to_cstring(PG_GETARG_TEXT_P(1)), + NULL, NULL, PG_GETARG_BOOL(2), PG_GETARG_BOOL(3), - 0, true, + true, 0, true, &result_tuples, &result_count); } else if (PG_NARGS() == 8) { process( text_to_cstring(PG_GETARG_TEXT_P(0)), + NULL, PG_GETARG_ARRAYTYPE_P(1), PG_GETARG_ARRAYTYPE_P(2), PG_GETARG_BOOL(3), @@ -305,30 +226,21 @@ _pgr_dijkstra(PG_FUNCTION_ARGS) { &result_tuples, &result_count); - /**********************************************************************/ } else /* (PG_NARGS() == 6) */ { - /**********************************************************************/ - // pgr_dijkstra( - // edge_sql TEXT, - // combinations_sql TEXT, - // directed BOOLEAN default true, - // only_cost BOOLEAN default false - - process_combinations( + process( text_to_cstring(PG_GETARG_TEXT_P(0)), text_to_cstring(PG_GETARG_TEXT_P(1)), + NULL, NULL, PG_GETARG_BOOL(2), PG_GETARG_BOOL(3), + true, PG_GETARG_INT64(4), PG_GETARG_BOOL(5), &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) { @@ -353,16 +265,6 @@ _pgr_dijkstra(PG_FUNCTION_ARGS) { bool* nulls; size_t call_cntr = funcctx->call_cntr; - /**********************************************************************/ - // OUT seq INTEGER, - // OUT path_seq INTEGER, - // OUT start_vid BIGINT, - // OUT end_vid BIGINT, - // 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)); @@ -380,7 +282,6 @@ _pgr_dijkstra(PG_FUNCTION_ARGS) { values[5] = Int64GetDatum(result_tuples[call_cntr].edge); values[6] = Float8GetDatum(result_tuples[call_cntr].cost); values[7] = Float8GetDatum(result_tuples[call_cntr].agg_cost); - /**********************************************************************/ tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); diff --git a/src/dijkstra/dijkstra_driver.cpp b/src/dijkstra/dijkstra_driver.cpp index a202f3a6ecc..ddbc7f11098 100644 --- a/src/dijkstra/dijkstra_driver.cpp +++ b/src/dijkstra/dijkstra_driver.cpp @@ -1,17 +1,18 @@ /*PGR-GNU***************************************************************** -File: many_to_many_dijkstra_driver.cpp +File: dijkstra_driver.cpp Generated with Template by: Copyright (c) 2015 pgRouting developers Mail: project@pgrouting.org Function's developer: +Copyright (c) 2023 Celia Virginia Vergara Castillo Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev Copyright (c) 2020 The combinations_sql signature is added by Mahmoud SAKR and Esteban ZIMANYI -mail: m_attia_sakr@yahoo.com, estebanzimanyi@gmail.com +mail: m_attia_sakr at yahoo.com, estebanzimanyi at gmail.com ------ @@ -32,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ #include "drivers/dijkstra/dijkstra_driver.h" -#include #include #include @@ -40,11 +40,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include -#include "dijkstra/pgr_dijkstra.hpp" +#include "c_types/ii_t_rt.h" +#include "cpp_common/combinations.h" #include "cpp_common/pgr_alloc.hpp" #include "cpp_common/pgr_assert.h" +#include "dijkstra/pgr_dijkstra.hpp" + namespace detail { void @@ -95,74 +98,30 @@ post_process(std::deque &paths, bool only_cost, bool normal, si } } - -template < class G > +template std::deque -pgr_dijkstra( +dijkstra( G &graph, - std::vector < int64_t > sources, - std::vector < int64_t > targets, + /* Now it receives a map */ + const std::map> &combinations, bool only_cost, - bool normal, - size_t n_goals, - bool global) { - 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()); - - pgrouting::Pgr_dijkstra< G > fn_dijkstra; - auto paths = fn_dijkstra.dijkstra( - graph, - sources, targets, - only_cost, n_goals); - - post_process(paths, only_cost, normal, n_goals, global); - - return paths; + size_t n_goals) { + std::deque paths; + pgrouting::Pgr_dijkstra fn_dijkstra; + return fn_dijkstra.dijkstra(graph, combinations, only_cost, n_goals); } - -template < class G > -std::deque -pgr_dijkstra( - G &graph, - std::vector < II_t_rt > &combinations, - bool only_cost, - bool normal, - size_t n_goals, - bool global) { - pgrouting::Pgr_dijkstra< G > fn_dijkstra; - auto paths = fn_dijkstra.dijkstra( - graph, - combinations, - only_cost, n_goals); - - post_process(paths, only_cost, normal, n_goals, global); - - return paths; -} } // namespace detail -// CREATE OR REPLACE FUNCTION pgr_dijkstra( -// sql text, -// start_vids anyarray, -// end_vids anyarray, -// directed boolean default true, void -do_pgr_many_to_many_dijkstra( - Edge_t *data_edges, - size_t total_edges, - int64_t *start_vidsArr, - size_t size_start_vidsArr, - int64_t *end_vidsArr, - size_t size_end_vidsArr, +pgr_do_dijkstra( + Edge_t *data_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, bool only_cost, bool normal, @@ -190,32 +149,34 @@ do_pgr_many_to_many_dijkstra( pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); + pgassert(total_combinations != 0 || (size_start_vidsArr != 0 && size_end_vidsArr != 0)); graphType gType = directed? DIRECTED: UNDIRECTED; - std::vector - start_vertices(start_vidsArr, start_vidsArr + size_start_vidsArr); - std::vector< int64_t > - end_vertices(end_vidsArr, end_vidsArr + size_end_vidsArr); - size_t n = n_goals <= 0? (std::numeric_limits::max)() : static_cast(n_goals); + std::dequepaths; + + 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); - std::deque< Path >paths; if (directed) { pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); - paths = detail::pgr_dijkstra( + paths = detail::dijkstra( digraph, - start_vertices, end_vertices, - only_cost, normal, n, global); + combinations, + only_cost, n); } else { pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); - paths = detail::pgr_dijkstra( + paths = detail::dijkstra( undigraph, - start_vertices, end_vertices, - only_cost, normal, n, global); + combinations, + only_cost, n); } + detail::post_process(paths, only_cost, normal, n, global); + combinations.clear(); size_t count(0); count = count_tuples(paths); @@ -223,8 +184,7 @@ do_pgr_many_to_many_dijkstra( if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; - notice << - "No paths found"; + notice << "No paths found"; *log_msg = pgr_msg(notice.str().c_str()); return; } @@ -258,111 +218,3 @@ do_pgr_many_to_many_dijkstra( *log_msg = pgr_msg(log.str().c_str()); } } - - -// CREATE OR REPLACE FUNCTION pgr_dijkstra( -// sql text, -// combinations sql text, -// directed boolean default true, -void -do_pgr_combinations_dijkstra( - Edge_t *data_edges, - size_t total_edges, - II_t_rt *combinations, - size_t total_combinations, - bool directed, - bool only_cost, - bool normal, - int64_t n_goals, - bool global, - - Path_rt **return_tuples, - size_t *return_count, - char ** log_msg, - char ** notice_msg, - char ** err_msg) { - using pgrouting::Path; - using pgrouting::pgr_alloc; - using pgrouting::pgr_msg; - using pgrouting::pgr_free; - - std::ostringstream log; - std::ostringstream err; - std::ostringstream notice; - - try { - pgassert(total_edges != 0); - pgassert(total_combinations != 0); - pgassert(!(*log_msg)); - pgassert(!(*notice_msg)); - pgassert(!(*err_msg)); - pgassert(!(*return_tuples)); - pgassert(*return_count == 0); - - graphType gType = directed? DIRECTED: UNDIRECTED; - - - std::vector - combinations_vector(combinations, combinations + total_combinations); - - size_t n = n_goals <= 0? (std::numeric_limits::max)() : static_cast(n_goals); - - std::deque< Path >paths; - if (directed) { - pgrouting::DirectedGraph digraph(gType); - digraph.insert_edges(data_edges, total_edges); - paths = detail::pgr_dijkstra( - digraph, - combinations_vector, - only_cost, normal, n, global); - } else { - pgrouting::UndirectedGraph undigraph(gType); - undigraph.insert_edges(data_edges, total_edges); - paths = detail::pgr_dijkstra( - undigraph, - combinations_vector, - only_cost, normal, n, global); - } - combinations_vector.clear(); - size_t count(0); - count = count_tuples(paths); - - if (count == 0) { - (*return_tuples) = NULL; - (*return_count) = 0; - notice << "No paths found"; - *log_msg = pgr_msg(notice.str().c_str()); - return; - } - - (*return_tuples) = pgr_alloc(count, (*return_tuples)); - (*return_count) = (collapse_paths(return_tuples, paths)); - - *log_msg = log.str().empty()? - *log_msg : - pgr_msg(log.str().c_str()); - *notice_msg = notice.str().empty()? - *notice_msg : - pgr_msg(notice.str().c_str()); - } catch (AssertFailedException &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 (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(...) { - (*return_tuples) = pgr_free(*return_tuples); - (*return_count) = 0; - err << "Caught unknown exception!"; - *err_msg = pgr_msg(err.str().c_str()); - *log_msg = pgr_msg(log.str().c_str()); - } -} - -