PGROUTING  3.2
bdDijkstra.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: bdDijkstra.c
3 
4 Generated with Template by:
5 Copyright (c) 2016 pgRouting developers
7 
8 Function's developer:
9 Copyright (c) 2016 Celia Virginia Vergara Castillo
11 
12 
13 ------
14 
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19 
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24 
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 
29  ********************************************************************PGR-GNU*/
30 
31 #include <stdbool.h>
33 #include "utils/array.h"
34 
35 #include "c_common/debug_macro.h"
36 #include "c_common/e_report.h"
37 #include "c_common/time_msg.h"
38 
39 #include "c_common/edges_input.h"
40 #include "c_common/arrays_input.h"
42 
44 
45 PGDLLEXPORT Datum _pgr_bddijkstra(PG_FUNCTION_ARGS);
47 
48 
49 /******************************************************************************/
50 /* MODIFY AS NEEDED */
51 static
52 void
54  char* edges_sql,
55  char* combinations_sql,
56  ArrayType *starts,
57  ArrayType *ends,
58  bool directed,
59  bool only_cost,
60  General_path_element_t **result_tuples,
61  size_t *result_count) {
63 
64  int64_t* start_vidsArr = NULL;
65  size_t size_start_vidsArr = 0;
66 
67  int64_t* end_vidsArr = NULL;
68  size_t size_end_vidsArr = 0;
69 
70  pgr_edge_t *edges = NULL;
71  size_t total_edges = 0;
72 
73  pgr_combination_t *combinations = NULL;
74  size_t total_combinations = 0;
75 
76  if (starts && ends) {
77  start_vidsArr = (int64_t*)
78  pgr_get_bigIntArray(&size_start_vidsArr, starts);
79  end_vidsArr = (int64_t*)
80  pgr_get_bigIntArray(&size_end_vidsArr, ends);
81  } else if (combinations_sql) {
82  pgr_get_combinations(combinations_sql, &combinations, &total_combinations);
83  }
84 
85  pgr_get_edges(edges_sql, &edges, &total_edges);
86  PGR_DBG("Total %ld edges in query:", total_edges);
87 
88  if (total_edges == 0) {
89  PGR_DBG("No edges found");
91  return;
92  }
93 
94  PGR_DBG("Starting processing");
95  clock_t start_t = clock();
96  char *log_msg = NULL;
97  char *notice_msg = NULL;
98  char *err_msg = NULL;
100  edges, total_edges,
101  combinations, total_combinations,
102  start_vidsArr, size_start_vidsArr,
103  end_vidsArr, size_end_vidsArr,
104 
105  directed,
106  only_cost,
107 
108  result_tuples,
109  result_count,
110  &log_msg,
111  &notice_msg,
112  &err_msg);
113 
114  time_msg(" processing pgr_bdDijkstra", start_t, clock());
115 
116 
117  if (err_msg && (*result_tuples)) {
118  pfree(*result_tuples);
119  (*result_tuples) = NULL;
120  (*result_count) = 0;
121  }
122 
123  pgr_global_report(log_msg, notice_msg, err_msg);
124 
125  if (log_msg) pfree(log_msg);
126  if (notice_msg) pfree(notice_msg);
127  if (err_msg) pfree(err_msg);
128  if (edges) pfree(edges);
129 
130  pgr_SPI_finish();
131 }
132 /* */
133 /******************************************************************************/
134 
135 PGDLLEXPORT Datum _pgr_bddijkstra(PG_FUNCTION_ARGS) {
136  FuncCallContext *funcctx;
137  TupleDesc tuple_desc;
138 
139  /**************************************************************************/
140  /* MODIFY AS NEEDED */
141  /* */
142  General_path_element_t *result_tuples = NULL;
143  size_t result_count = 0;
144  /* */
145  /**************************************************************************/
146 
147  if (SRF_IS_FIRSTCALL()) {
148  MemoryContext oldcontext;
149  funcctx = SRF_FIRSTCALL_INIT();
150  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
151 
152 
153  if (PG_NARGS() == 5) {
154  /*
155  * many to many
156  */
157  process(
158  text_to_cstring(PG_GETARG_TEXT_P(0)),
159  NULL,
160  PG_GETARG_ARRAYTYPE_P(1),
161  PG_GETARG_ARRAYTYPE_P(2),
162  PG_GETARG_BOOL(3),
163  PG_GETARG_BOOL(4),
164  &result_tuples,
165  &result_count);
166 
167  } else if (PG_NARGS() == 4) {
168  /*
169  * combinations
170  */
171  process(
172  text_to_cstring(PG_GETARG_TEXT_P(0)),
173  text_to_cstring(PG_GETARG_TEXT_P(1)),
174  NULL,
175  NULL,
176  PG_GETARG_BOOL(2),
177  PG_GETARG_BOOL(3),
178  &result_tuples,
179  &result_count);
180  }
181 
182  /* */
183  /**********************************************************************/
184 
185 #if PGSQL_VERSION > 95
186  funcctx->max_calls = result_count;
187 #else
188  funcctx->max_calls = (uint32_t)result_count;
189 #endif
190  funcctx->user_fctx = result_tuples;
191  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
192  != TYPEFUNC_COMPOSITE) {
193  ereport(ERROR,
194  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
195  errmsg("function returning record called in context "
196  "that cannot accept type record")));
197  }
198 
199  funcctx->tuple_desc = tuple_desc;
200  MemoryContextSwitchTo(oldcontext);
201  }
202 
203  funcctx = SRF_PERCALL_SETUP();
204  tuple_desc = funcctx->tuple_desc;
205 
206  result_tuples = (General_path_element_t*) funcctx->user_fctx;
207 
208  if (funcctx->call_cntr < funcctx->max_calls) {
209  HeapTuple tuple;
210  Datum result;
211  Datum *values;
212  bool* nulls;
213  size_t call_cntr = funcctx->call_cntr;
214 
215 
216  /**********************************************************************/
217  /* MODIFY AS NEEDED */
218  /*
219  OUT seq INTEGER,
220  OUT path_seq INTEGER,
221  OUT node BIGINT,
222  OUT edge BIGINT,
223  OUT cost FLOAT,
224  OUT agg_cost FLOAT
225  ***********************************************************************/
226 
227  size_t numb = 8;
228  values = palloc(numb * sizeof(Datum));
229  nulls = palloc(numb * sizeof(bool));
230 
231 
232  size_t i;
233  for (i = 0; i < numb; ++i) {
234  nulls[i] = false;
235  }
236 
237  values[0] = Int32GetDatum(call_cntr + 1);
238  values[1] = Int32GetDatum(result_tuples[call_cntr].seq);
239  values[2] = Int64GetDatum(result_tuples[call_cntr].start_id);
240  values[3] = Int64GetDatum(result_tuples[call_cntr].end_id);
241  values[4] = Int64GetDatum(result_tuples[call_cntr].node);
242  values[5] = Int64GetDatum(result_tuples[call_cntr].edge);
243  values[6] = Float8GetDatum(result_tuples[call_cntr].cost);
244  values[7] = Float8GetDatum(result_tuples[call_cntr].agg_cost);
245 
246  /**********************************************************************/
247 
248  tuple = heap_form_tuple(tuple_desc, values, nulls);
249  result = HeapTupleGetDatum(tuple);
250  SRF_RETURN_NEXT(funcctx, result);
251  } else {
252  SRF_RETURN_DONE(funcctx);
253  }
254 }
do_pgr_bdDijkstra
void do_pgr_bdDijkstra(pgr_edge_t *data_edges, size_t total_edges, pgr_combination_t *combinations, 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, General_path_element_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: bdDijkstra_driver.cpp:129
combinations_input.h
time_msg.h
postgres_connection.h
pgr_edge_t
Definition: pgr_edge_t.h:37
pgr_SPI_connect
void pgr_SPI_connect(void)
Definition: postgres_connection.c:82
pgr_SPI_finish
void pgr_SPI_finish(void)
Definition: postgres_connection.c:71
e_report.h
arrays_input.h
edge
Definition: trsp.h:41
debug_macro.h
pgr_get_bigIntArray
int64_t * pgr_get_bigIntArray(size_t *arrlen, ArrayType *input)
Enforces the input array to be NOT empty.
Definition: arrays_input.c:146
_pgr_bddijkstra
PGDLLEXPORT Datum _pgr_bddijkstra(PG_FUNCTION_ARGS)
Definition: bdDijkstra.c:135
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
pgr_combination_t
Definition: pgr_combination_t.h:43
bdDijkstra_driver.h
pgr_get_combinations
void pgr_get_combinations(char *combinations_sql, pgr_combination_t **combinations, size_t *total_combinations)
combinations_sql
Definition: combinations_input.c:147
pgr_get_edges
void pgr_get_edges(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
basic edge_sql
Definition: edges_input.c:711
General_path_element_t
Definition: general_path_element_t.h:37
PG_FUNCTION_INFO_V1
PG_FUNCTION_INFO_V1(_pgr_bddijkstra)
if
if(DOXYGEN_FOUND) configure_file($
Definition: doxygen/CMakeLists.txt:13
process
static void process(char *edges_sql, char *combinations_sql, ArrayType *starts, ArrayType *ends, bool directed, bool only_cost, General_path_element_t **result_tuples, size_t *result_count)
Definition: bdDijkstra.c:53
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
edges_input.h
pgr_global_report
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:93