From c1a15a8552251d99ff7cb643117b84cf604e1123 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sat, 21 Feb 2026 10:00:01 -0600 Subject: [PATCH 01/10] (maxFlow) renaming files for the new process and driver --- .../max_flow/max_flow_driver.h => process/maxFlow_process.h} | 0 src/max_flow/{max_flow_driver.cpp => maxFlow_driver.cpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename include/{drivers/max_flow/max_flow_driver.h => process/maxFlow_process.h} (100%) rename src/max_flow/{max_flow_driver.cpp => maxFlow_driver.cpp} (100%) diff --git a/include/drivers/max_flow/max_flow_driver.h b/include/process/maxFlow_process.h similarity index 100% rename from include/drivers/max_flow/max_flow_driver.h rename to include/process/maxFlow_process.h diff --git a/src/max_flow/max_flow_driver.cpp b/src/max_flow/maxFlow_driver.cpp similarity index 100% rename from src/max_flow/max_flow_driver.cpp rename to src/max_flow/maxFlow_driver.cpp From 9c61c207401b8c8693f6a6e7d4c835ce93c5f5ed Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sat, 21 Feb 2026 10:06:53 -0600 Subject: [PATCH 02/10] (maxFlow) creating missing files of new process and driver --- include/drivers/maxFlow_driver.hpp | 57 ++++++++++++++++++++ src/max_flow/maxFlow_process.cpp | 87 ++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 include/drivers/maxFlow_driver.hpp create mode 100644 src/max_flow/maxFlow_process.cpp diff --git a/include/drivers/maxFlow_driver.hpp b/include/drivers/maxFlow_driver.hpp new file mode 100644 index 0000000000..ad857357b8 --- /dev/null +++ b/include/drivers/maxFlow_driver.hpp @@ -0,0 +1,57 @@ +/*PGR-GNU***************************************************************** +File: maxFlow_driver.h + +Generated with Template by: +Copyright (c) 2007-2026 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2016 Andrea Nardelli +Mail: nrd.nardelli@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_MAXFLOW_DRIVER_H_ +#define INCLUDE_DRIVERS_MAXFLOW_DRIVER_H_ + +#include +#include +#include +#include + +#include "c_common/enums.h" + +using Flow_t = struct Flow_t; +using ArrayType = struct ArrayType; + +namespace pgrouting { +namespace drivers { + +void do_maxFlow( + const std::string&, const std::string&, + ArrayType*, ArrayType*, + + Which, + Flow_t*&, size_t&, + std::ostringstream&, std::ostringstream&, std::ostringstream&); + +} // namespace drivers +} // namespace pgrouting + +#endif // INCLUDE_DRIVERS_MAXFLOW_DRIVER_H_ diff --git a/src/max_flow/maxFlow_process.cpp b/src/max_flow/maxFlow_process.cpp new file mode 100644 index 0000000000..3175b94c1c --- /dev/null +++ b/src/max_flow/maxFlow_process.cpp @@ -0,0 +1,87 @@ +/*PGR-GNU***************************************************************** +File: max_flow.c + +Generated with Template by: +Copyright (c) 2015-2026 pgRouting developers +Mail: project@pgrouting.org + +Function's developer: +Copyright (c) 2016 Andrea Nardelli +Mail: nrd.nardelli@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 "process/maxFlow_process.h" + +extern "C" { +#include "c_common/postgres_connection.h" +#include "c_common/e_report.h" +#include "c_common/time_msg.h" +} + +#include +#include + +#include "c_types/flow_t.h" +#include "cpp_common/report_messages.hpp" +#include "cpp_common/utilities.hpp" +#include "cpp_common/assert.hpp" +#include "cpp_common/alloc.hpp" + +#include "drivers/maxFlow_driver.hpp" + +void pgr_process_maxFlow( + const char *edges_sql, + const char *combinations_sql, + + ArrayType *starts, ArrayType *ends, + + enum Which which, + Flow_t **result_tuples, size_t *result_count) { + pgassert(edges_sql); + pgassert(!(*result_tuples)); + pgassert(*result_count == 0); + pgr_SPI_connect(); + + std::ostringstream log; + std::ostringstream err; + std::ostringstream notice; + + clock_t start_t = clock(); + pgrouting::drivers::do_maxFlow( + edges_sql? edges_sql : "", + combinations_sql? combinations_sql : "", + starts, ends, + + which, + (*result_tuples), (*result_count), + log, notice, err); + + auto name = std::string(" processing ") + pgrouting::get_name(which); + time_msg(name.c_str(), start_t, clock()); + + if (!err.str().empty() && (*result_tuples)) { + pfree(*result_tuples); + (*result_tuples) = nullptr; + (*result_count) = 0; + } + + pgrouting::report_messages(log, notice, err); + pgr_SPI_finish(); +} From 3a4ac137bf0c760180b392ed8256a8ef417d9d5f Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sat, 21 Feb 2026 10:08:52 -0600 Subject: [PATCH 03/10] (maxFlow) Adjusting code of new process and driver --- include/process/maxFlow_process.h | 45 ++++----- src/max_flow/maxFlow_driver.cpp | 148 ++++++++++++------------------ 2 files changed, 78 insertions(+), 115 deletions(-) diff --git a/include/process/maxFlow_process.h b/include/process/maxFlow_process.h index ad58f61809..48522aa9dd 100644 --- a/include/process/maxFlow_process.h +++ b/include/process/maxFlow_process.h @@ -1,5 +1,5 @@ /*PGR-GNU***************************************************************** -File: max_flow_driver.h +File: maxFlow_process.h Generated with Template by: Copyright (c) 2007-2026 pgRouting developers @@ -27,49 +27,38 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -#ifndef INCLUDE_DRIVERS_MAX_FLOW_MAX_FLOW_DRIVER_H_ -#define INCLUDE_DRIVERS_MAX_FLOW_MAX_FLOW_DRIVER_H_ +#ifndef INCLUDE_PROCESS_MAXFLOW_PROCESS_H_ +#define INCLUDE_PROCESS_MAXFLOW_PROCESS_H_ #pragma once #ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#ifdef __cplusplus -} -#endif - -#include "cpp_common/undefPostgresDefine.hpp" - -#ifdef __cplusplus -# include -# include +#include +#include using Flow_t = struct Flow_t; +using ArrayType = struct ArrayType; #else -# include -# include +#include +#include +#include typedef struct Flow_t Flow_t; +typedef struct ArrayType ArrayType; #endif +#include "c_common/enums.h" + #ifdef __cplusplus extern "C" { #endif -void pgr_do_max_flow( - const char*, - const char*, +void pgr_process_maxFlow( + const char*, const char*, ArrayType*, ArrayType*, - int, bool, - - Flow_t**, size_t*, - char**, char**, char**); + enum Which, + Flow_t**, size_t*); #ifdef __cplusplus } #endif -#endif // INCLUDE_DRIVERS_MAX_FLOW_MAX_FLOW_DRIVER_H_ +#endif // INCLUDE_PROCESS_MAXFLOW_PROCESS_H_ diff --git a/src/max_flow/maxFlow_driver.cpp b/src/max_flow/maxFlow_driver.cpp index fd8446a01f..d063b9f1db 100644 --- a/src/max_flow/maxFlow_driver.cpp +++ b/src/max_flow/maxFlow_driver.cpp @@ -1,5 +1,5 @@ /*PGR-GNU***************************************************************** -File: max_flow_driver.cpp +File: maxFlow_driver.cpp Generated with Template by: Copyright (c) 2015-2026 pgRouting developers @@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -#include "drivers/max_flow/max_flow_driver.h" +#include "drivers/maxFlow_driver.hpp" #include #include @@ -36,51 +36,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "max_flow/maxflow.hpp" -#include "cpp_common/combinations.hpp" +#include "c_types/flow_t.h" #include "cpp_common/pgdata_getters.hpp" -#include "cpp_common/assert.hpp" -#include "cpp_common/alloc.hpp" +#include "cpp_common/utilities.hpp" +#include "cpp_common/to_postgres.hpp" +#include "cpp_common/combinations.hpp" -#include "c_types/ii_t_rt.h" +namespace pgrouting { +namespace drivers { void -pgr_do_max_flow( - const char *edges_sql, - const char *combinations_sql, +do_maxFlow( + const std::string &edges_sql, + const std::string &combinations_sql, ArrayType *starts, ArrayType *ends, - int algorithm, - bool only_flow, - - Flow_t **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; - using pgrouting::utilities::get_combinations; - - std::ostringstream log; - std::ostringstream notice; - std::ostringstream err; - const char *hint = nullptr; + Which which, + Flow_t* &return_tuples, size_t &return_count, + std::ostringstream &log, + std::ostringstream ¬ice, + std::ostringstream &err) { + std::string hint = ""; try { - pgassert(!(*log_msg)); - pgassert(!(*notice_msg)); - pgassert(!(*err_msg)); - pgassert(!(*return_tuples)); - pgassert(*return_count == 0); + if (edges_sql.empty()) { + err << "Empty edges SQL"; + return; + } + + using pgget::get_flow_edges; + using utilities::get_combinations; + using to_postgres::get_tuples; hint = combinations_sql; auto combinations = get_combinations(combinations_sql, starts, ends, true); - hint = nullptr; + hint = ""; - if (combinations.empty() && combinations_sql) { - *notice_msg = to_pg_msg("No (source, target) pairs found"); - *log_msg = to_pg_msg(combinations_sql); + if (combinations.empty() && !combinations_sql.empty()) { + notice << "No (source, target) pairs found"; + log << combinations_sql; return; } @@ -95,78 +90,57 @@ pgr_do_max_flow( vertices.insert(targets.begin(), targets.end()); if (vertices.size() != (sources.size() + targets.size())) { - *err_msg = to_pg_msg("A source found as sink"); + err << "A source found as sink"; return; } hint = edges_sql; - auto edges = pgrouting::pgget::get_flow_edges(std::string(edges_sql)); - hint = nullptr; + auto edges = get_flow_edges(edges_sql); + hint = ""; if (edges.empty()) { - *notice_msg = to_pg_msg("No edges found"); - *log_msg = to_pg_msg(edges_sql); + notice << "No edges found"; + log << edges_sql; return; } - pgrouting::graph::PgrFlowGraph digraph( - edges, sources, targets, algorithm); - // digraph.create_flow_graph(edges, sources, targets, algorithm); + pgrouting::graph::PgrFlowGraph digraph(edges, sources, targets, which); int64_t max_flow = 0; - if (algorithm == 1) { - max_flow = digraph.push_relabel(); - } else if (algorithm == 3) { - max_flow = digraph.edmonds_karp(); - } else if (algorithm == 2) { - max_flow = digraph.boykov_kolmogorov(); - } else { - log << "Unspecified algorithm!\n"; - *err_msg = to_pg_msg(log); - (*return_tuples) = NULL; - (*return_count) = 0; - return; + switch (which) { + case MAXFLOW: + case PUSHRELABEL: + max_flow = digraph.push_relabel(); + break; + case EDMONDSKARP: + max_flow = digraph.edmonds_karp(); + break; + case BOYKOV: + max_flow = digraph.boykov_kolmogorov(); + break; + default: + err << "Unknown flow function" << get_name(which); + return; } + auto flow_edges = which == MAXFLOW? only_maxFlow_result(max_flow) : digraph.get_flow_edges(); - std::vector flow_edges; - - if (only_flow) { - Flow_t edge = {-1, -1, -1, max_flow, -1, 0, 0}; - flow_edges.push_back(edge); - } else { - flow_edges = digraph.get_flow_edges(); - } - (*return_tuples) = pgr_alloc(flow_edges.size(), (*return_tuples)); - for (size_t i = 0; i < flow_edges.size(); ++i) { - (*return_tuples)[i] = flow_edges[i]; - } - *return_count = flow_edges.size(); - - - *log_msg = to_pg_msg(log); - *notice_msg = to_pg_msg(notice); + return_count = get_tuples(flow_edges, return_tuples); } 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::pair& ex) { + err << ex.first; + log << ex.second; + } catch (const std::string &ex) { + err << ex; + log << hint; } 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 (const std::string &ex) { - *err_msg = to_pg_msg(ex); - *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log); - } catch(...) { - (*return_tuples) = pgr_free(*return_tuples); - (*return_count) = 0; + } catch (...) { err << "Caught unknown exception!"; - *err_msg = to_pg_msg(err); - *log_msg = to_pg_msg(log); } } + +} // namespace drivers +} // namespace pgrouting From 4f1589d4a65eece467ac9e4b06d3491b893d1699 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Fri, 20 Feb 2026 20:58:26 -0600 Subject: [PATCH 04/10] (maxFlow) Preparing functions for the new process and driver --- include/c_common/enums.h | 4 +++- include/cpp_common/combinations.hpp | 3 +++ include/cpp_common/to_postgres.hpp | 6 ++++++ include/cpp_common/utilities.hpp | 2 ++ src/cpp_common/combinations.cpp | 8 ++++++++ src/cpp_common/to_postgres.cpp | 18 ++++++++++++++++++ src/cpp_common/utilities.cpp | 19 +++++++++++++++++++ 7 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/c_common/enums.h b/include/c_common/enums.h index 6ffad2994b..bea4c444b0 100644 --- a/include/c_common/enums.h +++ b/include/c_common/enums.h @@ -44,7 +44,9 @@ enum Which { PRIM = 510, PRIMDD, PRIMDFS, PRIMBFS, DFS = 520, BFS = 530, - DIJKSTRADD = 540 + DIJKSTRADD = 540, + MAXFLOW, PUSHRELABEL, BOYKOV, EDMONDSKARP + }; #endif // INCLUDE_C_COMMON_ENUMS_H_ diff --git a/include/cpp_common/combinations.hpp b/include/cpp_common/combinations.hpp index 467606c9a9..500fc7bae5 100644 --- a/include/cpp_common/combinations.hpp +++ b/include/cpp_common/combinations.hpp @@ -62,6 +62,9 @@ get_combinations(const std::vector&); std::map> get_combinations(const std::string&, ArrayType*, ArrayType*, bool, bool&); +std::map> +get_combinations(const std::string&, ArrayType*, ArrayType*, bool); + std::map> get_combinations(const char*, ArrayType*, ArrayType*, bool); diff --git a/include/cpp_common/to_postgres.hpp b/include/cpp_common/to_postgres.hpp index 026b59c6c2..e36a0c0aab 100644 --- a/include/cpp_common/to_postgres.hpp +++ b/include/cpp_common/to_postgres.hpp @@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_types/routes_t.h" #include "c_types/path_rt.h" #include "c_types/mst_rt.h" +#include "c_types/flow_t.h" #include "cpp_common/path.hpp" #include "cpp_common/base_graph.hpp" @@ -68,6 +69,11 @@ size_t get_tuples(const std::deque&, Path_rt*&); */ size_t get_tuples(const std::deque&, MST_rt*&); +/* + * @brief get tuples for Flow_t + */ +size_t get_tuples(const std::vector&, Flow_t*&); + /* * @brief get tuples for spanning tree driver */ diff --git a/include/cpp_common/utilities.hpp b/include/cpp_common/utilities.hpp index 6d59a2933d..e033e932cf 100644 --- a/include/cpp_common/utilities.hpp +++ b/include/cpp_common/utilities.hpp @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_common/enums.h" #include "c_types/mst_rt.h" +#include "c_types/flow_t.h" namespace pgrouting { @@ -42,6 +43,7 @@ std::string get_name(Which, bool, bool, bool); char estimate_drivingSide(char, Which); void get_new_queries(const std::string&, const std::string&, std::string&, std::string&); std::vector only_root_result(const std::set&); +std::vector only_maxFlow_result(int64_t); } // namespace pgrouting diff --git a/src/cpp_common/combinations.cpp b/src/cpp_common/combinations.cpp index 4e8c60a878..c8e4fa3057 100644 --- a/src/cpp_common/combinations.cpp +++ b/src/cpp_common/combinations.cpp @@ -182,5 +182,13 @@ get_combinations( return result; } +std::map> +get_combinations( + const std::string &combinations_sql, + ArrayType* startsArr, ArrayType* endsArr, bool normal) { + bool is_matrix = false; + return get_combinations(combinations_sql, startsArr, endsArr, normal, is_matrix); +} + } // namespace utilities } // namespace pgrouting diff --git a/src/cpp_common/to_postgres.cpp b/src/cpp_common/to_postgres.cpp index 4fa565d537..cdc6b853ba 100644 --- a/src/cpp_common/to_postgres.cpp +++ b/src/cpp_common/to_postgres.cpp @@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_types/routes_t.h" #include "c_types/path_rt.h" #include "c_types/mst_rt.h" +#include "c_types/flow_t.h" #include "cpp_common/path.hpp" #include "cpp_common/alloc.hpp" @@ -242,6 +243,23 @@ get_tuples( return count; } +size_t +get_tuples( + const std::vector &results, + Flow_t* &tuples) { + pgassert(!tuples); + + auto count = results.size(); + if (count == 0) return 0; + + tuples = pgr_alloc(count, tuples); + + for (size_t i = 0; i < count; i++) { + tuples[i] = results[i]; + } + return count; +} + size_t get_tuples( diff --git a/src/cpp_common/utilities.cpp b/src/cpp_common/utilities.cpp index 9735d37818..3a94081a9a 100644 --- a/src/cpp_common/utilities.cpp +++ b/src/cpp_common/utilities.cpp @@ -92,6 +92,18 @@ get_name(Which which) { case DIJKSTRADD: return "pgr_drivingDistance"; break; + case MAXFLOW: + return "pgr_maxFlow"; + break; + case PUSHRELABEL: + return "pgr_pushRelabel"; + break; + case BOYKOV: + return "pgr_boykovKolmogorov"; + break; + case EDMONDSKARP: + return "pgr_edmondsKarp"; + break; default: return "unknown"; break; @@ -213,4 +225,11 @@ only_root_result(const std::set &vids) { return results; } +std::vector +only_maxFlow_result(int64_t maxFlow) { + std::vector results; + results.push_back({-1, -1, -1, maxFlow, -1, 0, 0}); + return results; +} + } // namespace pgrouting From 0c8fbbe4052fabc87236acd20c356caefc3e3157 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sat, 21 Feb 2026 10:12:00 -0600 Subject: [PATCH 05/10] (maxFlow) using new process and driver --- include/max_flow/maxflow.hpp | 9 +-- src/max_flow/CMakeLists.txt | 4 +- src/max_flow/max_flow.c | 110 +++++++---------------------------- src/max_flow/maxflow.cpp | 18 ++++-- 4 files changed, 41 insertions(+), 100 deletions(-) diff --git a/include/max_flow/maxflow.hpp b/include/max_flow/maxflow.hpp index b0064fc652..0443ebd5f3 100644 --- a/include/max_flow/maxflow.hpp +++ b/include/max_flow/maxflow.hpp @@ -44,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_types/flow_t.h" #include "cpp_common/edge_t.hpp" +#include "c_common/enums.h" #include "c_types/path_rt.h" #include "cpp_common/interruption.hpp" @@ -107,10 +108,10 @@ class PgrFlowGraph { } PgrFlowGraph( - const std::vector &edges, - const std::set &source_vertices, - const std::set &sink_vertices, - int algorithm); + const std::vector&, + const std::set&, + const std::set&, + Which); PgrFlowGraph( const std::vector &edges, diff --git a/src/max_flow/CMakeLists.txt b/src/max_flow/CMakeLists.txt index 8c8d98cf47..47cd593645 100644 --- a/src/max_flow/CMakeLists.txt +++ b/src/max_flow/CMakeLists.txt @@ -7,7 +7,9 @@ ADD_LIBRARY(max_flow OBJECT maximum_cardinality_matching.c edge_disjoint_paths.c - max_flow_driver.cpp + maxFlow_driver.cpp + maxFlow_process.cpp + maximum_cardinality_matching_driver.cpp edge_disjoint_paths_driver.cpp minCostMaxFlow_driver.cpp diff --git a/src/max_flow/max_flow.c b/src/max_flow/max_flow.c index 8756b764ad..33d8068ce8 100644 --- a/src/max_flow/max_flow.c +++ b/src/max_flow/max_flow.c @@ -31,103 +31,37 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_common/postgres_connection.h" -#include "c_common/debug_macro.h" -#include "c_common/e_report.h" -#include "c_common/time_msg.h" -#include "drivers/max_flow/max_flow_driver.h" - #include "c_types/flow_t.h" -PGDLLEXPORT Datum -_pgr_maxflow(PG_FUNCTION_ARGS); - -static -void -process( - char *edges_sql, - char *combinations_sql, - ArrayType *starts, - ArrayType *ends, - int algorithm, - bool only_flow, - Flow_t **result_tuples, - size_t *result_count) { - if (algorithm < 1 || algorithm > 3) { - elog(ERROR, "Unknown algorithm"); - } - - pgr_SPI_connect(); - char* log_msg = NULL; - char* notice_msg = NULL; - char* err_msg = NULL; - - clock_t start_t = clock(); - pgr_do_max_flow( - edges_sql, - combinations_sql, - starts, ends, - - algorithm, - only_flow, - - result_tuples, result_count, - - &log_msg, - ¬ice_msg, - &err_msg); - - if (only_flow) { - time_msg("pgr_maxFlow(many to many)", start_t, clock()); - } else if (algorithm == 1) { - time_msg("pgr_maxFlowPushRelabel(many to many)", start_t, clock()); - } else if (algorithm == 3) { - time_msg("pgr_maxFlowEdmondsKarp(many to many)", start_t, clock()); - } else { - time_msg("pgr_maxFlowBoykovKolmogorov(many to many)", start_t, clock()); - } - - if (err_msg && (*result_tuples)) { - pfree(*result_tuples); - (*result_tuples) = NULL; - (*result_count) = 0; - } +#include "process/maxFlow_process.h" - pgr_global_report(&log_msg, ¬ice_msg, &err_msg); - - pgr_SPI_finish(); -} +PGDLLEXPORT Datum _pgr_maxflow(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_pgr_maxflow); -PG_FUNCTION_INFO_V1(_pgr_maxflow); -PGDLLEXPORT Datum -_pgr_maxflow(PG_FUNCTION_ARGS) { - FuncCallContext *funcctx; - TupleDesc tuple_desc; +PGDLLEXPORT Datum _pgr_maxflow(PG_FUNCTION_ARGS) { + FuncCallContext *funcctx; + TupleDesc tuple_desc; - /**************************************************************************/ - Flow_t *result_tuples = 0; + Flow_t *result_tuples = NULL; size_t result_count = 0; - /**************************************************************************/ if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; + MemoryContext oldcontext; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - - /**********************************************************************/ - if (PG_NARGS() == 5) { /* * many to many */ - process( + pgr_process_maxFlow( text_to_cstring(PG_GETARG_TEXT_P(0)), NULL, + PG_GETARG_ARRAYTYPE_P(1), PG_GETARG_ARRAYTYPE_P(2), - PG_GETARG_INT32(3), - PG_GETARG_BOOL(4), + PG_GETARG_BOOL(4)? MAXFLOW : MAXFLOW + PG_GETARG_INT32(3), &result_tuples, &result_count); @@ -135,20 +69,18 @@ _pgr_maxflow(PG_FUNCTION_ARGS) { /* * combinations */ - process( + pgr_process_maxFlow( text_to_cstring(PG_GETARG_TEXT_P(0)), text_to_cstring(PG_GETARG_TEXT_P(1)), + NULL, NULL, - PG_GETARG_INT32(2), - PG_GETARG_BOOL(3), + + PG_GETARG_BOOL(3)? MAXFLOW : MAXFLOW + PG_GETARG_INT32(2), &result_tuples, &result_count); } - /* */ - /**********************************************************************/ - funcctx->max_calls = result_count; funcctx->user_fctx = result_tuples; if (get_call_result_type(fcinfo, NULL, &tuple_desc) @@ -168,14 +100,13 @@ _pgr_maxflow(PG_FUNCTION_ARGS) { result_tuples = (Flow_t *) funcctx->user_fctx; if (funcctx->call_cntr < funcctx->max_calls) { - HeapTuple tuple; - Datum result; - Datum *values; - bool *nulls; + HeapTuple tuple; + Datum result; + Datum *values; + bool* nulls; + size_t call_cntr = funcctx->call_cntr; - /**********************************************************************/ - /* MODIFY AS NEEDED */ values = palloc(6 * sizeof(Datum)); nulls = palloc(6 * sizeof(bool)); @@ -190,7 +121,6 @@ _pgr_maxflow(PG_FUNCTION_ARGS) { values[3] = Int64GetDatum(result_tuples[call_cntr].target); values[4] = Int64GetDatum(result_tuples[call_cntr].flow); values[5] = Int64GetDatum(result_tuples[call_cntr].residual_capacity); - /**********************************************************************/ tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); diff --git a/src/max_flow/maxflow.cpp b/src/max_flow/maxflow.cpp index b466ba0ce2..68170bf1f6 100644 --- a/src/max_flow/maxflow.cpp +++ b/src/max_flow/maxflow.cpp @@ -40,17 +40,25 @@ PgrFlowGraph::PgrFlowGraph( const std::vector &edges, const std::set &source_vertices, const std::set &sink_vertices, - int algorithm) { + Which algorithm) { add_vertices(edges, source_vertices, sink_vertices); capacity = get(boost::edge_capacity, graph); rev = get(boost::edge_reverse, graph); residual_capacity = get(boost::edge_residual_capacity, graph); - if (algorithm == 1) { - insert_edges_push_relabel(edges); - } else { - insert_edges(edges); + switch (algorithm) { + case MAXFLOW: + case PUSHRELABEL: + insert_edges_push_relabel(edges); + break; + case BOYKOV: + case EDMONDSKARP: + insert_edges(edges); + break; + default: + ; + /* Maybe do a throw */ } } From fd0b13060eec984bf1070ebf35df34b0892f22ce Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sun, 1 Mar 2026 15:13:38 -0600 Subject: [PATCH 06/10] Updating release notes and news --- NEWS.md | 1 + doc/src/release_notes.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index bc2855eb35..591db40a52 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,7 @@ To see all issues & pull requests closed by this release see the * [#3060](https://github.com/pgRouting/pgrouting/issues/3060): dagShortestPath: use the shortest_path process and driver * [#3064](https://github.com/pgRouting/pgrouting/issues/3064): Astar: create and use a process and driver for Astar * [#3075](https://github.com/pgRouting/pgrouting/issues/3075): Spanning tree: create and use a process and driver +* [#3086](https://github.com/pgRouting/pgrouting/issues/3086): MaxFlow: create and use a process and driver ## pgRouting 4.0 diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 795aa5c0be..9104cc6b11 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -46,6 +46,7 @@ To see all issues & pull requests closed by this release see the * :issue:`3060`: dagShortestPath: use the shortest_path process and driver * :issue:`3064`: Astar: create and use a process and driver for Astar * :issue:`3075`: Spanning tree: create and use a process and driver +* :issue:`3086`: MaxFlow: create and use a process and driver pgRouting 4.0 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From 7106bb2203a4a37bb1cb41a6bbe14fec75939829 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:16:27 +0000 Subject: [PATCH 07/10] Update locale: commit fd0b13060e --- locale/en/LC_MESSAGES/pgrouting_doc_strings.po | 7 ++++++- locale/pot/pgrouting_doc_strings.pot | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index e3d55a1fc8..8edb97b173 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-21 01:08+0000\n" +"POT-Creation-Date: 2026-03-01 21:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3961,6 +3961,11 @@ msgid "" "tree: create and use a process and driver" msgstr "" +msgid "" +"`#3086 `__: MaxFlow: " +"create and use a 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 bf3e750913..e4721ccc0b 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-21 01:08+0000\n" +"POT-Creation-Date: 2026-03-01 21:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3550,6 +3550,9 @@ msgstr "" msgid "`#3075 `__: Spanning tree: create and use a process and driver" msgstr "" +msgid "`#3086 `__: MaxFlow: create and use a process and driver" +msgstr "" + msgid "All releases" msgstr "" From 8906c760c40fd977adede3a024d804f9fd7d5564 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sun, 1 Mar 2026 15:19:04 -0600 Subject: [PATCH 08/10] Fixing code checker --- include/c_common/enums.h | 1 - include/drivers/maxFlow_driver.hpp | 6 +++--- src/max_flow/maxFlow_driver.cpp | 1 + src/max_flow/maxflow.cpp | 2 +- tools/scripts/code_checker.sh | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/c_common/enums.h b/include/c_common/enums.h index bea4c444b0..b2b5fced59 100644 --- a/include/c_common/enums.h +++ b/include/c_common/enums.h @@ -46,7 +46,6 @@ enum Which { BFS = 530, DIJKSTRADD = 540, MAXFLOW, PUSHRELABEL, BOYKOV, EDMONDSKARP - }; #endif // INCLUDE_C_COMMON_ENUMS_H_ diff --git a/include/drivers/maxFlow_driver.hpp b/include/drivers/maxFlow_driver.hpp index ad857357b8..6e9b07d0c6 100644 --- a/include/drivers/maxFlow_driver.hpp +++ b/include/drivers/maxFlow_driver.hpp @@ -27,8 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -#ifndef INCLUDE_DRIVERS_MAXFLOW_DRIVER_H_ -#define INCLUDE_DRIVERS_MAXFLOW_DRIVER_H_ +#ifndef INCLUDE_DRIVERS_MAXFLOW_DRIVER_HPP_ +#define INCLUDE_DRIVERS_MAXFLOW_DRIVER_HPP_ #include #include @@ -54,4 +54,4 @@ void do_maxFlow( } // namespace drivers } // namespace pgrouting -#endif // INCLUDE_DRIVERS_MAXFLOW_DRIVER_H_ +#endif // INCLUDE_DRIVERS_MAXFLOW_DRIVER_HPP_ diff --git a/src/max_flow/maxFlow_driver.cpp b/src/max_flow/maxFlow_driver.cpp index d063b9f1db..ab0fcef7ba 100644 --- a/src/max_flow/maxFlow_driver.cpp +++ b/src/max_flow/maxFlow_driver.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include #include +#include #include "max_flow/maxflow.hpp" diff --git a/src/max_flow/maxflow.cpp b/src/max_flow/maxflow.cpp index 68170bf1f6..46f48ff458 100644 --- a/src/max_flow/maxflow.cpp +++ b/src/max_flow/maxflow.cpp @@ -57,7 +57,7 @@ PgrFlowGraph::PgrFlowGraph( insert_edges(edges); break; default: - ; + {}; /* Maybe do a throw */ } } diff --git a/tools/scripts/code_checker.sh b/tools/scripts/code_checker.sh index 3f52522119..2f699ef0f9 100755 --- a/tools/scripts/code_checker.sh +++ b/tools/scripts/code_checker.sh @@ -27,6 +27,7 @@ INCLUDE_ORDER=" -build/include_order:src/metrics/metrics_process.cpp, -build/include_order:src/ordering/ordering_process.cpp, -build/include_order:src/astar/astar_process.cpp, +-build/include_order:src/max_flow/maxFlow_process.cpp, -build/include_order:src/spanningTree/spanningTree_process.cpp, -build/include_order:src/allpairs/allpairs_process.cpp" From 02e9296c14bd56be533b36e6d7b31a1ca83dd603 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Sun, 1 Mar 2026 17:22:22 -0600 Subject: [PATCH 09/10] Removing warning --- src/max_flow/max_flow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/max_flow/max_flow.c b/src/max_flow/max_flow.c index 33d8068ce8..1f01e07092 100644 --- a/src/max_flow/max_flow.c +++ b/src/max_flow/max_flow.c @@ -61,7 +61,7 @@ PGDLLEXPORT Datum _pgr_maxflow(PG_FUNCTION_ARGS) { PG_GETARG_ARRAYTYPE_P(1), PG_GETARG_ARRAYTYPE_P(2), - PG_GETARG_BOOL(4)? MAXFLOW : MAXFLOW + PG_GETARG_INT32(3), + PG_GETARG_BOOL(4)? MAXFLOW : MAXFLOW + PG_GETARG_UINT32(3), &result_tuples, &result_count); @@ -76,7 +76,7 @@ PGDLLEXPORT Datum _pgr_maxflow(PG_FUNCTION_ARGS) { NULL, NULL, - PG_GETARG_BOOL(3)? MAXFLOW : MAXFLOW + PG_GETARG_INT32(2), + PG_GETARG_BOOL(3)? MAXFLOW : MAXFLOW + PG_GETARG_UINT32(2), &result_tuples, &result_count); } From 0cc9398e61945f44732a550bfaed6ed8df5358d9 Mon Sep 17 00:00:00 2001 From: cvvergara Date: Mon, 2 Mar 2026 19:10:17 -0600 Subject: [PATCH 10/10] Fixing license --- include/drivers/maxFlow_driver.hpp | 2 +- src/max_flow/maxFlow_process.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/drivers/maxFlow_driver.hpp b/include/drivers/maxFlow_driver.hpp index 6e9b07d0c6..5220fe7349 100644 --- a/include/drivers/maxFlow_driver.hpp +++ b/include/drivers/maxFlow_driver.hpp @@ -1,5 +1,5 @@ /*PGR-GNU***************************************************************** -File: maxFlow_driver.h +File: maxFlow_driver.hpp Generated with Template by: Copyright (c) 2007-2026 pgRouting developers diff --git a/src/max_flow/maxFlow_process.cpp b/src/max_flow/maxFlow_process.cpp index 3175b94c1c..1cf1de8444 100644 --- a/src/max_flow/maxFlow_process.cpp +++ b/src/max_flow/maxFlow_process.cpp @@ -1,8 +1,8 @@ /*PGR-GNU***************************************************************** -File: max_flow.c +File: maxFlow_process.cpp Generated with Template by: -Copyright (c) 2015-2026 pgRouting developers +Copyright (c) 2025-2026 pgRouting developers Mail: project@pgrouting.org Function's developer: