diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 7dc98cdee..5fef661bf 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -836,7 +836,7 @@ WARN_FORMAT = "$file:$line: $text" # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = @CMAKE_CURRENT_BIN_DIR@/LOG +WARN_LOGFILE = @CMAKE_CURRENT_BINARY_DIR@/LOG #--------------------------------------------------------------------------- # Configuration options related to the input files diff --git a/src/compatibleVehicles/compatibleVehicles_driver.cpp b/src/compatibleVehicles/compatibleVehicles_driver.cpp index 10cb9a83c..19ec45729 100644 --- a/src/compatibleVehicles/compatibleVehicles_driver.cpp +++ b/src/compatibleVehicles/compatibleVehicles_driver.cpp @@ -24,24 +24,23 @@ 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 */ - #include "drivers/compatibleVehicles_driver.h" -#include +#include #include #include -#include +#include -#include "problem/pickDeliver.hpp" -#include "problem/matrix.hpp" -#include "cpp_common/orders_t.hpp" #include "c_types/compatibleVehicles_rt.h" -#include "cpp_common/vehicle_t.hpp" -#include "cpp_common/assert.hpp" #include "cpp_common/alloc.hpp" +#include "cpp_common/assert.hpp" + +#include "cpp_common/orders_t.hpp" +#include "cpp_common/vehicle_t.hpp" +#include "problem/pickDeliver.hpp" +#include "problem/matrix.hpp" /** * @@ -54,6 +53,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @param[in] multipliers_arr A C Array of the multipliers * @param[in] total_multipliers size of the multipliers_arr * @param[in] factor A global multiplier for the (time) matrix cells + * * @param[out] return_tuples C array of contents to be returned to postgres * @param[out] return_count number of tuples returned * @param[out] log_msg special log message pointer @@ -65,30 +65,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @pre The C array: return_tuples must be empty * @pre Only matrix cells (i, i) can be missing and are considered as 0 (time units) * - * @post The C arrays: customers_arr, vehicles_arr, matrix_cells_arr Do not change * @post The C array: return_tuples contains the result for the problem given * @post The return_tuples array size is return_count - * @post The return_tuples array size is return_count * @post err_msg is empty if no throw from the process is catched * @post log_msg contains some logging * @post notice_msg is empty * - * @dot digraph G { node[fontsize=11, nodesep=0.75,ranksep=0.75]; start [shape=Mdiamond]; n1 [label="Verify preconditions",shape=rect]; - n3 [label="Verify matrix cells preconditions",shape=rect]; + n3 [label="Verify matrix preconditions",shape=rect]; n4 [label="Construct problem",shape=cds,color=blue]; n7 [label="Prepare results",shape=rect]; end [shape=Mdiamond]; error [shape=Mdiamond,color=red] start -> n1 -> n3 -> n4 -> n7 -> end; - n1 -> error [ label="Caller error",color=red]; - n3 -> error [ label="User error",color=red]; - + n1 -> error [ label="throw",color=red]; + n3 -> error [ label="throw",color=red]; } @enddot @@ -96,17 +92,10 @@ digraph G { */ void vrp_do_compatibleVehicles( - Orders_t customers_arr[], - size_t total_customers, - - Vehicle_t *vehicles_arr, - size_t total_vehicles, - - Matrix_cell_t *matrix_cells_arr, - size_t total_cells, - - Time_multipliers_t *multipliers_arr, - size_t total_multipliers, + Orders_t customers_arr[], size_t total_customers, + Vehicle_t *vehicles_arr, size_t total_vehicles, + Matrix_cell_t *matrix_cells_arr, size_t total_cells, + Time_multipliers_t *multipliers_arr, size_t total_multipliers, double factor, @@ -117,8 +106,11 @@ vrp_do_compatibleVehicles( char **notice_msg, char **err_msg) { using vrprouting::alloc; + using vrprouting::free; using vrprouting::to_pg_msg; + char* hint = nullptr; + std::ostringstream log; std::ostringstream notice; std::ostringstream err; @@ -140,13 +132,15 @@ vrp_do_compatibleVehicles( Identifiers node_ids; for (size_t i = 0; i < total_customers; ++i) { - node_ids += customers_arr[i].pick_node_id; - node_ids += customers_arr[i].deliver_node_id; + auto o = customers_arr[i]; + node_ids += o.pick_node_id; + node_ids += o.deliver_node_id; } for (size_t i = 0; i < total_vehicles; ++i) { - node_ids += vehicles_arr[i].start_node_id; - node_ids += vehicles_arr[i].end_node_id; + auto v = vehicles_arr[i]; + node_ids += v.start_node_id; + node_ids += v.end_node_id; } /* @@ -156,7 +150,8 @@ vrp_do_compatibleVehicles( matrix_cells_arr, total_cells, multipliers_arr, total_multipliers, node_ids, static_cast(factor)); -#if 0 + +#ifdef TODO /* * Verify matrix triangle inequality */ @@ -169,6 +164,7 @@ vrp_do_compatibleVehicles( } } #endif + if (!cost_matrix.has_no_infinity()) { err << "An Infinity value was found on the Matrix"; *err_msg = to_pg_msg(err.str()); @@ -186,9 +182,8 @@ vrp_do_compatibleVehicles( err << pd_problem.msg.get_error(); if (!err.str().empty()) { - log << pd_problem.msg.get_log(); - *log_msg = to_pg_msg(log.str()); - *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(pd_problem.msg.get_log()); + *err_msg = to_pg_msg(pd_problem.msg.get_error()); return; } log << pd_problem.msg.get_log(); @@ -213,25 +208,34 @@ vrp_do_compatibleVehicles( } (*return_count) = solution.size(); - pgassert(*err_msg == nullptr); - *log_msg = log.str().empty()? - nullptr : - to_pg_msg(log.str()); - *notice_msg = notice.str().empty()? - nullptr : - to_pg_msg(notice.str()); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str()); + *err_msg = to_pg_msg(except.what()); *log_msg = to_pg_msg(log.str()); } catch (std::exception& except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); + } catch (const std::pair& ex) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); *log_msg = to_pg_msg(log.str()); } catch(...) { if (*return_tuples) free(*return_tuples); diff --git a/src/optimize/optimize_driver.cpp b/src/optimize/optimize_driver.cpp index 3686f8263..4b0b8de2a 100644 --- a/src/optimize/optimize_driver.cpp +++ b/src/optimize/optimize_driver.cpp @@ -25,30 +25,31 @@ 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 */ - #include "drivers/optimize_driver.h" -#include +#include #include #include -#include #include -#include +#include -#include "problem/pickDeliver.hpp" -#include "cpp_common/orders_t.hpp" #include "c_types/short_vehicle_rt.h" -#include "cpp_common/vehicle_t.hpp" -#include "problem/matrix.hpp" +#include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" + +#include "cpp_common/interruption.hpp" #include "cpp_common/messages.hpp" + +#include "cpp_common/orders_t.hpp" +#include "cpp_common/short_vehicle.hpp" +#include "cpp_common/vehicle_t.hpp" + #include "initialsol/tabu.hpp" #include "optimizers/tabu.hpp" -#include "cpp_common/alloc.hpp" -#include "cpp_common/interruption.hpp" +#include "problem/matrix.hpp" +#include "problem/pickDeliver.hpp" namespace { @@ -58,6 +59,7 @@ namespace { * @param[in] total_shipments size of the shipments_arr * @param[in] vehicles_arr A C Array of vehicles * @param[in] total_vehicles size of the vehicles_arr + * * @param[in] new_stops stops that override the original stops. * @param[in] time_matrix The unique time matrix * @param[in] max_cycles number of cycles to perform during the optimization phase @@ -120,15 +122,14 @@ one_processing( * @returns processing times */ Identifiers -processing_times_by_shipment( - Orders_t *shipments_arr, size_t total_shipments - ) { +processing_times_by_shipment(Orders_t *shipments_arr, size_t total_shipments) { Identifiers processing_times; for (size_t i = 0; i < total_shipments; ++i) { - processing_times += shipments_arr[i].pick_open_t; - processing_times += shipments_arr[i].pick_close_t; - processing_times += shipments_arr[i].deliver_open_t; - processing_times += shipments_arr[i].deliver_close_t; + auto o = shipments_arr[i]; + processing_times += o.pick_open_t; + processing_times += o.pick_close_t; + processing_times += o.deliver_open_t; + processing_times += o.deliver_close_t; } return processing_times; } @@ -141,15 +142,14 @@ processing_times_by_shipment( * @returns processing times */ Identifiers -processing_times_by_vehicle( - Vehicle_t *vehicles_arr, size_t total_vehicles - ) { +processing_times_by_vehicle(Vehicle_t *vehicles_arr, size_t total_vehicles) { Identifiers processing_times; for (size_t i = 0; i < total_vehicles; ++i) { - processing_times += vehicles_arr[i].start_open_t; - processing_times += vehicles_arr[i].start_close_t; - processing_times += vehicles_arr[i].end_open_t; - processing_times += vehicles_arr[i].end_close_t; + auto v = vehicles_arr[i]; + processing_times += v.start_open_t; + processing_times += v.start_close_t; + processing_times += v.end_open_t; + processing_times += v.end_close_t; } return processing_times; } @@ -162,9 +162,7 @@ processing_times_by_vehicle( * @returns (vehicle id, stops vector) pair which hold the stops structure */ std::vector -get_initial_stops( - Vehicle_t *vehicles_arr, size_t total_vehicles - ) { +get_initial_stops(Vehicle_t *vehicles_arr, size_t total_vehicles) { std::vector the_stops; for (size_t i = 0; i < total_vehicles; ++i) { std::vector stops; @@ -253,7 +251,7 @@ subdivide_processing( /* * Nothing to do: * - no shipments to process - * - last optimization had exavtly the same shipments + * - last optimization had exactly the same shipments */ if ((shipments_in_stops.size() == 0) || (prev_shipments_in_stops == shipments_in_stops)) continue; @@ -296,26 +294,24 @@ subdivide_processing( * @param[in] total_cells size of the matrix_cells_arr * @param[in] multipliers_arr A C Array of the multipliers * @param[in] total_multipliers size of the multipliers_arr + * * @param[in] factor A global multiplier for the (time) matrix cells * @param[in] max_cycles number of cycles to perform during the optimization phase * @param[in] check_triangle_inequality When true tirangle inequality will be checked * @param[in] subdivide @todo * @param[in] subdivide_by_vehicle @todo * @param[in] execution_date Value used for not moving shipments that are before this date + * * @param[out] return_tuples C array of contents to be returned to postgres * @param[out] return_count number of tuples returned * @param[out] log_msg special log message pointer * @param[out] notice_msg special message pointer to be returned as NOTICE * @param[out] err_msg special message pointer to be returned as ERROR - * @return void - * * * @pre The messages: log_msg, notice_msg, err_msg must be empty (=nullptr) - * @pre The C arrays: shipments_arr, vehicles_arr, matrix_cells_arr must not be empty * @pre The C array: return_tuples must be empty * @pre Only matrix cells (i, i) can be missing and are considered as 0 (time units) * - * @post The C arrays: shipments_arr, vehicles_arr, matrix_cells_arr Do not change * @post The C array: return_tuples contains the result for the problem given * @post The return_tuples array size is return_count * @post err_msg is empty if no throw from the process is catched @@ -342,8 +338,6 @@ subdivide_processing( } @enddot - - * */ void vrp_do_optimize( @@ -368,8 +362,11 @@ vrp_do_optimize( char **notice_msg, char **err_msg) { using vrprouting::alloc; + using vrprouting::free; using vrprouting::to_pg_msg; + char* hint = nullptr; + std::ostringstream log; std::ostringstream notice; std::ostringstream err; @@ -386,9 +383,6 @@ vrp_do_optimize( pgassert(*return_count == 0); pgassert(!(*return_tuples)); - *return_tuples = nullptr; - *return_count = 0; - Identifiers node_ids; Identifiers shipments_in_stops; @@ -522,27 +516,39 @@ vrp_do_optimize( (*return_count) = total_shipments * 2; pgassert(*err_msg == nullptr); - *log_msg = log.str().empty()? - nullptr : - to_pg_msg(log.str()); - *notice_msg = notice.str().empty()? - nullptr : - to_pg_msg(notice.str()); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { - err << except.what() << log.str(); - *err_msg = to_pg_msg(err.str()); + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); } catch (std::exception& except) { - err << except.what() << log.str(); - *err_msg = to_pg_msg(err.str()); + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); } catch (const std::pair& ex) { - err << ex.first; - log.str(""); - log.clear(); - log << ex.second; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); + *log_msg = to_pg_msg(log.str()); } catch(...) { - err << "Caught unknown exception!" << log.str(); + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + err << "Caught unknown exception!"; *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(log.str()); } } diff --git a/src/pgr_pickDeliver/pgr_pickDeliverEuclidean_driver.cpp b/src/pgr_pickDeliver/pgr_pickDeliverEuclidean_driver.cpp index 4a5546b49..f064173a7 100644 --- a/src/pgr_pickDeliver/pgr_pickDeliverEuclidean_driver.cpp +++ b/src/pgr_pickDeliver/pgr_pickDeliverEuclidean_driver.cpp @@ -25,27 +25,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ - #include "drivers/pgr_pickDeliverEuclidean_driver.h" +#include #include -#include #include -#include +#include #include -#include -#include "cpp_common/orders_t.hpp" #include "c_types/solution_rt.h" + #include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" -#include "problem/matrix.hpp" +#include "cpp_common/orders_t.hpp" +#include "cpp_common/vehicle_t.hpp" #include "initialsol/simple.hpp" #include "optimizers/simple.hpp" +#include "problem/matrix.hpp" #include "problem/pickDeliver.hpp" namespace { + vrprouting::problem::Solution get_initial_solution(vrprouting::problem::PickDeliver* problem_ptr, int m_initial_id) { using Solution = vrprouting::problem::Solution; @@ -82,33 +83,34 @@ are_shipments_ok( * - d_open <= d_close */ for (size_t i = 0; i < total_customers; ++i) { - if (customers_arr[i].demand == 0) { + auto o = customers_arr[i]; + if (o.demand == 0) { *err_string = "Unexpected zero value found on column 'demand' of shipments"; - *hint_string = "Check shipment id #:" + std::to_string(customers_arr[i].id); + *hint_string = "Check shipment id #:" + std::to_string(o.id); return false; } - if (customers_arr[i].pick_service_t < 0) { + if (o.pick_service_t < 0) { *err_string = "Unexpected negative value found on column 'p_service_t' of shipments"; - *hint_string = "Check shipment id #:" + std::to_string(customers_arr[i].id); + *hint_string = "Check shipment id #:" + std::to_string(o.id); return false; } - if (customers_arr[i].deliver_service_t < 0) { + if (o.deliver_service_t < 0) { *err_string = "Unexpected negative value found on column 'd_service_t' of shipments"; - *hint_string = "Check shipment id #:" + std::to_string(customers_arr[i].id); + *hint_string = "Check shipment id #:" + std::to_string(o.id); return false; } - if (customers_arr[i].pick_open_t > customers_arr[i].pick_close_t) { + if (o.pick_open_t > o.pick_close_t) { *err_string = "Unexpected pickup time windows found on shipments"; - *hint_string = "Check shipment id #:" + std::to_string(customers_arr[i].id); + *hint_string = "Check shipment id #:" + std::to_string(o.id); return false; } - if (customers_arr[i].deliver_open_t > customers_arr[i].deliver_close_t) { + if (o.deliver_open_t > o.deliver_close_t) { *err_string = "Unexpected delivery time windows found on shipments"; - *hint_string = "Check shipment id #:" + std::to_string(customers_arr[i].id); + *hint_string = "Check shipment id #:" + std::to_string(o.id); return false; } } @@ -119,11 +121,8 @@ are_shipments_ok( void vrp_do_pgr_pickDeliverEuclidean( - Orders_t *customers_arr, - size_t total_customers, - - Vehicle_t *vehicles_arr, - size_t total_vehicles, + Orders_t *customers_arr, size_t total_customers, + Vehicle_t *vehicles_arr, size_t total_vehicles, double factor, int max_cycles, @@ -136,19 +135,27 @@ vrp_do_pgr_pickDeliverEuclidean( char **notice_msg, char **err_msg) { using vrprouting::alloc; + using vrprouting::free; using vrprouting::to_pg_msg; + char* hint = nullptr; + std::ostringstream log; std::ostringstream notice; std::ostringstream err; try { - *return_tuples = nullptr; - *return_count = 0; + pgassert(!(*log_msg)); + pgassert(!(*notice_msg)); + pgassert(!(*err_msg)); + pgassert(*return_count == 0); + pgassert(!(*return_tuples)); + std::string err_string; std::string hint_string; + if (!are_shipments_ok(customers_arr, total_customers, &err_string, &hint_string)) { - *err_msg = to_pg_msg(err_string.c_str()); - *log_msg = to_pg_msg(hint_string.c_str()); + *err_msg = to_pg_msg(err_string); + *log_msg = to_pg_msg(hint_string); return; } @@ -189,54 +196,37 @@ vrp_do_pgr_pickDeliverEuclidean( } for (size_t i = 0; i < total_customers; ++i) { - customers_arr[i].pick_node_id = - matrix_data[std::pair(customers_arr[i].pick_x, customers_arr[i].pick_y)]; - - customers_arr[i].deliver_node_id = - matrix_data[std::pair(customers_arr[i].deliver_x, customers_arr[i].deliver_y)]; + auto &o = customers_arr[i]; + o.pick_node_id = matrix_data[std::pair(o.pick_x, o.pick_y)]; + o.deliver_node_id = matrix_data[std::pair(o.deliver_x, o.deliver_y)]; } + for (auto &v : vehicles) { v.start_node_id = matrix_data[std::pair(v.start_x, v.start_y)]; v.end_node_id = matrix_data[std::pair(v.end_x, v.end_y)]; } - vrprouting::problem::Matrix cost_matrix(matrix_data, static_cast(factor)); + vrprouting::problem::Matrix matrix(matrix_data, static_cast(factor)); log << "Initialize problem\n"; vrprouting::problem::PickDeliver pd_problem( customers_arr, total_customers, vehicles_arr, total_vehicles, - cost_matrix); + matrix); err << pd_problem.msg.get_error(); if (!err.str().empty()) { - log.str(""); - log.clear(); - log << pd_problem.msg.get_error(); - log << pd_problem.msg.get_log(); - *log_msg = to_pg_msg(log.str().c_str()); - *err_msg = to_pg_msg(err.str().c_str()); + *err_msg = to_pg_msg(pd_problem.msg.get_error()); + *log_msg = to_pg_msg(pd_problem.msg.get_log()); return; } log << pd_problem.msg.get_log(); log << "Finish Reading data\n"; -#if 0 - try { -#endif - auto sol = get_initial_solution(&pd_problem, initial_solution_id); - using Optimize = vrprouting::optimizers::simple::Optimize; - using Initials_code = vrprouting::initialsol::simple::Initials_code; - sol = Optimize(sol, static_cast(max_cycles), (Initials_code)initial_solution_id); -#if 0 - } catch (AssertFailedException &except) { - log << pd_problem.msg.get_log(); - throw; - } catch(...) { - log << "Caught unknown exception!"; - throw; - } -#endif + auto sol = get_initial_solution(&pd_problem, initial_solution_id); + using Optimize = vrprouting::optimizers::simple::Optimize; + using Initials_code = vrprouting::initialsol::simple::Initials_code; + sol = Optimize(sol, static_cast(max_cycles), (Initials_code)initial_solution_id); log << pd_problem.msg.get_log(); log << "Finish solve\n"; @@ -255,40 +245,40 @@ vrp_do_pgr_pickDeliverEuclidean( } (*return_count) = solution.size(); - log << pd_problem.msg.get_log(); - - pgassert(*err_msg == NULL); - *log_msg = log.str().empty()? - nullptr : - to_pg_msg(log.str().c_str()); - *notice_msg = notice.str().empty()? - nullptr : - to_pg_msg(notice.str().c_str()); + pgassert(*err_msg == nullptr); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); } catch (std::exception& except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); } catch (const std::pair& ex) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << ex.first; - log.str(""); - log.clear(); - log << ex.second; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); + *log_msg = to_pg_msg(log.str()); } catch(...) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(log.str()); } } diff --git a/src/pgr_pickDeliver/pgr_pickDeliver_driver.cpp b/src/pgr_pickDeliver/pgr_pickDeliver_driver.cpp index f81afe373..1a0248e13 100644 --- a/src/pgr_pickDeliver/pgr_pickDeliver_driver.cpp +++ b/src/pgr_pickDeliver/pgr_pickDeliver_driver.cpp @@ -25,62 +25,58 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ - #include "drivers/pgr_pickDeliver_driver.h" -#include +#include #include #include -#include #include #include -#include "cpp_common/orders_t.hpp" #include "c_types/solution_rt.h" + #include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" -#include "problem/solution.hpp" -#include "initialsol/simple.hpp" -#include "optimizers/simple.hpp" -#include "problem/pickDeliver.hpp" +#include "cpp_common/orders_t.hpp" #include "initialsol/initials_code.hpp" +#include "initialsol/simple.hpp" +#include "optimizers/simple.hpp" #include "problem/matrix.hpp" +#include "problem/pickDeliver.hpp" +#include "problem/solution.hpp" + +namespace { -namespace { vrprouting::problem::Solution - get_initial_solution(vrprouting::problem::PickDeliver* problem_ptr, int m_initial_id) { - using Solution = vrprouting::problem::Solution; - using Initial_solution = vrprouting::initialsol::simple::Initial_solution; - using Initials_code = vrprouting::initialsol::simple::Initials_code; - Solution m_solutions(problem_ptr); - if (m_initial_id == 0) { - for (int i = 1; i < 7; ++i) { - if (i == 1) { - m_solutions = Initial_solution((Initials_code)i, problem_ptr); - } else { - auto new_sol = Initial_solution((Initials_code)i, problem_ptr); - m_solutions = (new_sol < m_solutions)? new_sol : m_solutions; - } +get_initial_solution(vrprouting::problem::PickDeliver* problem_ptr, int m_initial_id) { + using Solution = vrprouting::problem::Solution; + using Initial_solution = vrprouting::initialsol::simple::Initial_solution; + using Initials_code = vrprouting::initialsol::simple::Initials_code; + Solution m_solutions(problem_ptr); + if (m_initial_id == 0) { + for (int i = 1; i < 7; ++i) { + if (i == 1) { + m_solutions = Initial_solution((Initials_code)i, problem_ptr); + } else { + auto new_sol = Initial_solution((Initials_code)i, problem_ptr); + m_solutions = (new_sol < m_solutions)? new_sol : m_solutions; } - } else { - m_solutions = Initial_solution((Initials_code)m_initial_id, problem_ptr); } - - return m_solutions; + } else { + m_solutions = Initial_solution((Initials_code)m_initial_id, problem_ptr); } + + return m_solutions; +} + } // namespace void vrp_do_pgr_pickDeliver( - struct Orders_t customers_arr[], - size_t total_customers, - - Vehicle_t *vehicles_arr, - size_t total_vehicles, - - Matrix_cell_t *matrix_cells_arr, - size_t total_cells, + struct Orders_t customers_arr[], size_t total_customers, + Vehicle_t *vehicles_arr, size_t total_vehicles, + Matrix_cell_t *matrix_cells_arr, size_t total_cells, double factor, int max_cycles, @@ -93,8 +89,11 @@ vrp_do_pgr_pickDeliver( char **notice_msg, char **err_msg) { using vrprouting::alloc; + using vrprouting::free; using vrprouting::to_pg_msg; + char* hint = nullptr; + std::ostringstream log; std::ostringstream notice; std::ostringstream err; @@ -107,25 +106,22 @@ vrp_do_pgr_pickDeliver( pgassert(total_vehicles); pgassert(*return_count == 0); pgassert(!(*return_tuples)); - log << "do_pgr_pickDeliver\n"; - - *return_tuples = nullptr; - *return_count = 0; Identifiers node_ids; Identifiers order_ids; for (size_t i = 0; i < total_customers; ++i) { - node_ids += customers_arr[i].pick_node_id; - node_ids += customers_arr[i].deliver_node_id; - order_ids += customers_arr[i].id; + auto o = customers_arr[i]; + node_ids += o.pick_node_id; + node_ids += o.deliver_node_id; + order_ids += o.id; } for (size_t i = 0; i < total_vehicles; ++i) { - auto vehicle = vehicles_arr[i]; - node_ids += vehicle.start_node_id; - node_ids += vehicle.end_node_id; + auto v = vehicles_arr[i]; + node_ids += v.start_node_id; + node_ids += v.end_node_id; } log << node_ids; @@ -136,13 +132,9 @@ vrp_do_pgr_pickDeliver( std::vector vehicles( vehicles_arr, vehicles_arr + total_vehicles); - vrprouting::problem::Matrix time_matrix( - matrix_cells_arr, - total_cells, - node_ids, - static_cast(factor)); + vrprouting::problem::Matrix matrix(matrix_cells_arr, total_cells, node_ids, static_cast(factor)); -#if 0 +#ifdef TODO auto depot_node = vehicles[0].start_node_id; /* @@ -155,7 +147,7 @@ vrp_do_pgr_pickDeliver( for (const auto &v : vehicles) { if (v.start_node_id != depot_node && v.end_node_id != depot_node) { err << "All vehicles must depart & arrive to same node"; - *err_msg = to_pg_msg(err.str().c_str()); + *err_msg = to_pg_msg(err.str()); return; } } @@ -166,55 +158,39 @@ vrp_do_pgr_pickDeliver( for (size_t i = 0; i < total_customers; ++i) { if (customers_arr[i].pick_node_id != depot_node) { err << "All orders must be picked at depot"; - *err_msg = to_pg_msg(err.str().c_str()); + *err_msg = to_pg_msg(err.str()); return; } } } #endif - if (!time_matrix.has_no_infinity()) { + if (!matrix.has_no_infinity()) { err << "An Infinity value was found on the Matrix. Might be missing information of a node"; - *err_msg = to_pg_msg(err.str().c_str()); + *err_msg = to_pg_msg(err.str()); return; } - // TODO(vicky) wrap with a try and make a throw??? - // tried it is already wrapped log << "Initialize problem\n"; vrprouting::problem::PickDeliver pd_problem( customers_arr, total_customers, vehicles_arr, total_vehicles, - time_matrix); + matrix); err << pd_problem.msg.get_error(); if (!err.str().empty()) { - log << pd_problem.msg.get_log(); - *log_msg = to_pg_msg(log.str().c_str()); - *err_msg = to_pg_msg(err.str().c_str()); + *err_msg = to_pg_msg(pd_problem.msg.get_error()); + *log_msg = to_pg_msg(pd_problem.msg.get_log()); return; } log << pd_problem.msg.get_log(); log << "Finish Reading data\n"; pd_problem.msg.clear(); -#if 0 - try { -#endif - using Initials_code = vrprouting::initialsol::simple::Initials_code; - auto sol = get_initial_solution(&pd_problem, initial_solution_id); - using Optimize = vrprouting::optimizers::simple::Optimize; - sol = Optimize(sol, static_cast(max_cycles), (Initials_code)initial_solution_id); -#if 0 - } catch (AssertFailedException &except) { - log << pd_problem.msg.get_log(); - pd_problem.msg.clear(); - throw; - } catch(...) { - log << "Caught unknown exception!"; - throw; - } -#endif + using Initials_code = vrprouting::initialsol::simple::Initials_code; + auto sol = get_initial_solution(&pd_problem, initial_solution_id); + using Optimize = vrprouting::optimizers::simple::Optimize; + sol = Optimize(sol, static_cast(max_cycles), (Initials_code)initial_solution_id); log << pd_problem.msg.get_log(); log << "Finish solve\n"; @@ -236,42 +212,40 @@ vrp_do_pgr_pickDeliver( } (*return_count) = solution.size(); - pgassert(*err_msg == NULL); - *log_msg = log.str().empty()? - nullptr : - to_pg_msg(log.str().c_str()); - *notice_msg = notice.str().empty()? - nullptr : - to_pg_msg(notice.str().c_str()); + pgassert(*err_msg == nullptr); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); } catch (std::exception& except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); } catch (const std::pair& ex) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << ex.first; - log << ex.second; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); - } catch (const std::pair& ex) { + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << ex.first; - log << "FOOOO missing on matrix: id = " << ex.second; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); + *log_msg = to_pg_msg(log.str()); } catch(...) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(log.str()); } } diff --git a/src/pickDeliver/pickDeliver_driver.cpp b/src/pickDeliver/pickDeliver_driver.cpp index 8ae3a95c7..e183fc635 100644 --- a/src/pickDeliver/pickDeliver_driver.cpp +++ b/src/pickDeliver/pickDeliver_driver.cpp @@ -30,21 +30,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "drivers/pickDeliver_driver.h" -#include +#include #include #include -#include -#include "problem/pickDeliver.hpp" -#include "cpp_common/orders_t.hpp" #include "c_types/solution_rt.h" -#include "cpp_common/vehicle_t.hpp" -#include "problem/matrix.hpp" +#include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" + +#include "cpp_common/orders_t.hpp" +#include "cpp_common/vehicle_t.hpp" #include "initialsol/tabu.hpp" #include "optimizers/tabu.hpp" -#include "cpp_common/alloc.hpp" +#include "problem/matrix.hpp" +#include "problem/pickDeliver.hpp" + /** * @@ -66,8 +67,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @param[out] log_msg special log message pointer * @param[out] notice_msg special message pointer to be returned as NOTICE * @param[out] err_msg special message pointer to be returned as ERROR - * @return void - * * * @pre The messages: log_msg, notice_msg, err_msg must be empty (=nullptr) * @pre The C arrays: customers_arr, vehicles_arr, matrix_cells_arr must not be empty @@ -81,7 +80,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @post log_msg contains some logging * @post notice_msg is empty * - * @dot digraph G { node[fontsize=11, nodesep=0.75,ranksep=0.75]; @@ -101,8 +99,6 @@ digraph G { } @enddot - - * */ void vrp_do_pickDeliver( @@ -125,8 +121,11 @@ vrp_do_pickDeliver( char **notice_msg, char **err_msg) { using vrprouting::alloc; + using vrprouting::free; using vrprouting::to_pg_msg; + char* hint = nullptr; + std::ostringstream log; std::ostringstream notice; std::ostringstream err; @@ -144,28 +143,27 @@ vrp_do_pickDeliver( pgassert(!(*return_tuples)); log << "do_pickDeliver\n"; - *return_tuples = nullptr; - *return_count = 0; - Identifiers node_ids; Identifiers order_ids; for (size_t i = 0; i < total_customers; ++i) { - node_ids += customers_arr[i].pick_node_id; - node_ids += customers_arr[i].deliver_node_id; - order_ids += customers_arr[i].id; + auto o = customers_arr[i]; + node_ids += o.pick_node_id; + node_ids += o.deliver_node_id; + order_ids += o.id; } bool missing = false; for (size_t i = 0; i < total_vehicles; ++i) { - auto vehicle = vehicles_arr[i]; - node_ids += vehicle.start_node_id; - node_ids += vehicle.end_node_id; - for (size_t j = 0; j < vehicle.stops_size; ++j) { - if (!order_ids.has(vehicle.stops[j])) { + auto v = vehicles_arr[i]; + node_ids += v.start_node_id; + node_ids += v.end_node_id; + for (size_t j = 0; j < v.stops_size; ++j) { + auto s = v.stops[j]; + if (!order_ids.has(s)) { if (!missing) err << "Order in 'stops' information missing"; missing = true; - err << "Missing information of order " << vehicle.stops[j] << "\n"; + err << "Missing information of order " << s << "\n"; } } if (missing) { @@ -178,7 +176,7 @@ vrp_do_pickDeliver( matrix_cells_arr, total_cells, multipliers_arr, total_multipliers, node_ids, static_cast(factor)); -#if 1 + /* * Verify matrix triangle inequality */ @@ -190,7 +188,7 @@ vrp_do_pickDeliver( log << "[pickDeliver] Matrix Still does not obey triangle inequality "; } } -#endif + /* * Verify matrix cells preconditions */ @@ -225,29 +223,18 @@ vrp_do_pickDeliver( log << "Finish Initialize problem\n"; -#if 0 - try { -#endif - /* - * get initial solutions - */ - using Initial_solution = vrprouting::initialsol::tabu::Initial_solution; - using Solution = vrprouting::problem::Solution; - auto sol = static_cast(Initial_solution(execution_date, optimize, &pd_problem)); - /* - * Solve (optimize) - */ - using Optimize = vrprouting::optimizers::tabu::Optimize; - sol = Optimize(sol, static_cast(max_cycles), stop_on_all_served, optimize); -#if 0 - } catch (AssertFailedException &except) { - log << pd_problem.msg.get_log(); - throw; - } catch(...) { - log << "Caught unknown exception!"; - throw; - } -#endif + /* + * get initial solutions + */ + using Initial_solution = vrprouting::initialsol::tabu::Initial_solution; + using Solution = vrprouting::problem::Solution; + auto sol = static_cast(Initial_solution(execution_date, optimize, &pd_problem)); + + /* + * Solve (optimize) + */ + using Optimize = vrprouting::optimizers::tabu::Optimize; + sol = Optimize(sol, static_cast(max_cycles), stop_on_all_served, optimize); log << pd_problem.msg.get_log(); pd_problem.msg.clear(); @@ -272,29 +259,40 @@ vrp_do_pickDeliver( } (*return_count) = solution.size(); - log << pd_problem.msg.get_log(); - pgassert(*err_msg == nullptr); - *log_msg = log.str().empty()? - nullptr : - to_pg_msg(log.str()); - *notice_msg = notice.str().empty()? - nullptr : - to_pg_msg(notice.str()); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what() << log.str(); - *err_msg = to_pg_msg(err.str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); } catch (std::exception& except) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what() << log.str(); - *err_msg = to_pg_msg(err.str()); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); + } catch (const std::pair& ex) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); + *log_msg = to_pg_msg(log.str()); } catch(...) { if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << "Caught unknown exception!" << log.str(); + err << "Caught unknown exception!"; *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(log.str()); } } diff --git a/src/vroom/vroom_driver.cpp b/src/vroom/vroom_driver.cpp index e90e60782..529d77281 100644 --- a/src/vroom/vroom_driver.cpp +++ b/src/vroom/vroom_driver.cpp @@ -27,27 +27,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "drivers/vroom_driver.h" -#include -#include #include -#include -#include #include - -#include "vroom/vroom.hpp" +#include +#include +#include +#include #include "c_types/vroom_rt.h" + #include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" + #include "cpp_common/identifiers.hpp" +#include "cpp_common/vroom_job_t.hpp" #include "cpp_common/vroom_matrix.hpp" #include "cpp_common/vroom_vehicle_t.hpp" #include "cpp_common/vroom_shipment_t.hpp" -#include "cpp_common/vroom_job_t.hpp" +#include "vroom/vroom.hpp" /** @file vroom_driver.cpp * @brief Handles actual calling of function in the `vrp_vroom.hpp` file. - * */ /** @brief Performs exception handling and converts the results to postgres. @@ -78,9 +78,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @param[in] total_breaks_tws The total number of total breaks timewindows * @param[in] matrix_rows Pointer to the array of matrix rows * @param[in] total_matrix_rows The total number of matrix rows + * * @param[in] exploration_level Exploration level to use while solving. * @param[in] timeout Timeout value to stop the solving process (seconds). * @param[in] loading_time Additional time spent in loading the data from SQL Query (seconds). + * * @param[out] return_tuples The rows in the result * @param[out] return_count The count of rows in the result * @param[out] log_msg Stores the log message @@ -105,12 +107,14 @@ vrp_do_vroom( Vroom_rt **return_tuples, size_t *return_count, - char ** log_msg, - char ** notice_msg, - char ** err_msg) { + char **log_msg, + char **notice_msg, + char **err_msg) { using vrprouting::alloc; - using vrprouting::to_pg_msg; using vrprouting::free; + using vrprouting::to_pg_msg; + + char* hint = nullptr; std::ostringstream log; std::ostringstream err; @@ -139,21 +143,23 @@ vrp_do_vroom( } for (size_t i = 0; i < total_shipments; ++i) { - location_ids += shipments[i].p_location_id; - location_ids += shipments[i].d_location_id; + auto s = shipments[i]; + location_ids += s.p_location_id; + location_ids += s.d_location_id; } double min_speed_factor, max_speed_factor; min_speed_factor = max_speed_factor = vehicles[0].speed_factor; for (size_t i = 0; i < total_vehicles; ++i) { - min_speed_factor = std::min(min_speed_factor, vehicles[i].speed_factor); - max_speed_factor = std::max(max_speed_factor, vehicles[i].speed_factor); - if (vehicles[i].start_id != -1) { - location_ids += vehicles[i].start_id; + auto v = vehicles[i]; + min_speed_factor = std::min(min_speed_factor, v.speed_factor); + max_speed_factor = std::max(max_speed_factor, v.speed_factor); + if (v.start_id != -1) { + location_ids += v.start_id; } - if (vehicles[i].end_id != -1) { - location_ids += vehicles[i].end_id; + if (v.end_id != -1) { + location_ids += v.end_id; } } @@ -195,13 +201,9 @@ vrp_do_vroom( vrprouting::problem::Vroom problem; problem.add_matrix(matrix); - problem.add_vehicles(vehicles, total_vehicles, - breaks, total_breaks, - breaks_tws, total_breaks_tws); - problem.add_jobs(jobs, total_jobs, - jobs_tws, total_jobs_tws); - problem.add_shipments(shipments, total_shipments, - shipments_tws, total_shipments_tws); + problem.add_vehicles(vehicles, total_vehicles, breaks, total_breaks, breaks_tws, total_breaks_tws); + problem.add_jobs(jobs, total_jobs, jobs_tws, total_jobs_tws); + problem.add_shipments(shipments, total_shipments, shipments_tws, total_shipments_tws); auto end_time = std::chrono::high_resolution_clock::now(); loading_time += static_cast( @@ -217,7 +219,7 @@ vrp_do_vroom( notice << "No results found"; *notice_msg = notice.str().empty()? *notice_msg : - to_pg_msg(notice.str().c_str()); + to_pg_msg(notice.str()); return; } @@ -228,41 +230,40 @@ vrp_do_vroom( (*return_count) = count; - pgassert(*err_msg == NULL); - *log_msg = log.str().empty()? - *log_msg : - to_pg_msg(log.str().c_str()); - *notice_msg = notice.str().empty()? - *notice_msg : - to_pg_msg(notice.str().c_str()); + pgassert(*err_msg == nullptr); + *log_msg = log.str().empty()? nullptr : to_pg_msg(log.str()); + *notice_msg = notice.str().empty()? nullptr : to_pg_msg(notice.str()); } catch (AssertFailedException &except) { - (*return_tuples) = free(*return_tuples); + if (*return_tuples) free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (std::exception& except) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); - } catch (const vroom::Exception &except) { - (*return_tuples) = free(*return_tuples); + *err_msg = to_pg_msg(except.what()); + *log_msg = to_pg_msg(log.str()); + } catch (const std::string &except) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.message; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); - } catch (std::string &except) { - (*return_tuples) = free(*return_tuples); + *err_msg = to_pg_msg(except); + *log_msg = hint? to_pg_msg(hint) : to_pg_msg(log.str()); + } catch (const std::pair& ex) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - *err_msg = to_pg_msg(except.c_str()); - *log_msg = to_pg_msg(log.str().c_str()); - } catch (std::exception &except) { - (*return_tuples) = free(*return_tuples); + *err_msg = to_pg_msg(ex.first); + *log_msg = to_pg_msg(ex.second); + } catch (const std::pair& except) { + if (*return_tuples) free(*return_tuples); (*return_count) = 0; - err << except.what(); - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + log << "id = " << except.second; + *err_msg = to_pg_msg(except.first); + *log_msg = to_pg_msg(log.str()); } catch(...) { - (*return_tuples) = free(*return_tuples); + if (*return_tuples) free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; - *err_msg = to_pg_msg(err.str().c_str()); - *log_msg = to_pg_msg(log.str().c_str()); + *err_msg = to_pg_msg(err.str()); + *log_msg = to_pg_msg(log.str()); } }