PGROUTING  2.6-dev
dijkstraTRSP.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: dijkstraTRSP.c
3 
4 Generated with Template by:
5 Copyright (c) 2015 pgRouting developers
6 Mail: project@pgrouting.org
7 
8 Function's developer:
9 Copyright (c) 2017 Vidhan Jain
10 Mail: vidhanj1307@gmail.com
11 
12 ------
13 
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18 
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 
28 ********************************************************************PGR-GNU*/
29 
46 
47 
48 /* for macro PGR_DBG */
49 #include "c_common/debug_macro.h"
50 /* for pgr_global_report */
51 #include "c_common/e_report.h"
52 /* for time_msg & clock */
53 #include "c_common/time_msg.h"
54 /* for functions to get edges information */
55 #include "c_common/edges_input.h"
56 #include "c_common/restrict_input.h"
57 
58 #include "drivers/dijkstraTRSP/dijkstraTRSP_driver.h" // the link to the C++ code of the function
59 
60 PGDLLEXPORT Datum dijkstraTRSP(PG_FUNCTION_ARGS);
62 
63 
64 /******************************************************************************/
65 /* MODIFY AS NEEDED */
66 static
67 void
69  char* edges_sql,
70  char *restrictions_sql,
71  int64_t start_vid,
72  int64_t end_vid,
73  bool directed,
74  bool only_cost,
75  bool strict,
76  General_path_element_t **result_tuples,
77  size_t *result_count) {
79  /*
80  * https://www.postgresql.org/docs/current/static/spi-spi-connect.html
81  */
82  (*result_tuples) = NULL;
83  (*result_count) = 0;
84  PGR_DBG("\n\n\n\n\n\nEdge query: %s\n", edges_sql);
85  PGR_DBG("Restrictions query: %s\n", restrictions_sql);
86  PGR_DBG("source: %lu | destination: %lu\n\n", start_vid, end_vid);
87 
88  PGR_DBG("Load data");
89  pgr_edge_t *edges = NULL;
90  size_t total_edges = 0;
91 
92  if (start_vid == end_vid) {
93  /*
94  * https://www.postgresql.org/docs/current/static/spi-spi-finish.html
95  */
97  return;
98  }
99 
100  pgr_get_edges(edges_sql, &edges, &total_edges);
101  PGR_DBG("Total %ld edges in query:", total_edges);
102 
103  PGR_DBG("Load restrictions");
104  Restrict_t *restrictions = NULL;
105  size_t total_restrictions = 0;
106 
107  pgr_get_restriction_data(restrictions_sql, &restrictions,
108  &total_restrictions);
109 
110 #if 1
111  size_t i = 0;
112  while (i < total_restrictions) {
113  PGR_DBG("id: %ld cost: %lf", restrictions[i].id, restrictions[i].cost);
114  int j = 0;
115  while (restrictions[i].restricted_edges[j] != -1) {
116  PGR_DBG("%ld ", restrictions[i].restricted_edges[j]);
117  j++;
118  }
119  PGR_DBG("\n");
120  i++;
121  }
122 #endif
123 
124  if (total_edges == 0) {
125  PGR_DBG("No edges found");
126  pgr_SPI_finish();
127  return;
128  }
129 
130  PGR_DBG("Starting processing");
131  clock_t start_t = clock();
132  char *log_msg = NULL;
133  char *notice_msg = NULL;
134  char *err_msg = NULL;
136  edges,
137  total_edges,
138  restrictions,
139  total_restrictions,
140  start_vid,
141  end_vid,
142  directed,
143  only_cost,
144  strict,
145  result_tuples,
146  result_count,
147  &log_msg,
148  &notice_msg,
149  &err_msg);
150 
151  time_msg(" processing pgr_dijkstraTRSP", start_t, clock());
152  PGR_DBG("Returning %ld tuples", *result_count);
153 
154  if (err_msg) {
155  if (*result_tuples) pfree(*result_tuples);
156  }
157  pgr_global_report(log_msg, notice_msg, err_msg);
158  if (edges) pfree(edges);
159  if (log_msg) pfree(log_msg);
160  if (notice_msg) pfree(notice_msg);
161  if (err_msg) pfree(err_msg);
162  if (restrictions) pfree(restrictions);
163  pgr_SPI_finish();
164 }
165 /* */
166 /******************************************************************************/
167 
168 PGDLLEXPORT Datum dijkstraTRSP(PG_FUNCTION_ARGS) {
169  FuncCallContext *funcctx;
170  TupleDesc tuple_desc;
171 
172  /**************************************************************************/
173  /* MODIFY AS NEEDED */
174  /* */
175  General_path_element_t *result_tuples = NULL;
176  size_t result_count = 0;
177  /* */
178  /**************************************************************************/
179 
180  if (SRF_IS_FIRSTCALL()) {
181  MemoryContext oldcontext;
182  funcctx = SRF_FIRSTCALL_INIT();
183  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
184 
185 
186  /**********************************************************************/
187  /* MODIFY AS NEEDED */
188  /*
189  TEXT,
190  TEXT,
191  BIGINT,
192  BIGINT,
193  directed BOOLEAN DEFAULT true,
194  only_cost BOOLEAN DEFAULT false,
195  strict BOOLEAN DEFAULT false
196  **********************************************************************/
197 
198 
199  PGR_DBG("Calling process");
200  process(
201  text_to_cstring(PG_GETARG_TEXT_P(0)),
202  text_to_cstring(PG_GETARG_TEXT_P(1)),
203  PG_GETARG_INT64(2),
204  PG_GETARG_INT64(3),
205  PG_GETARG_BOOL(4),
206  PG_GETARG_BOOL(5),
207  PG_GETARG_BOOL(6),
208  &result_tuples,
209  &result_count);
210 
211 
212  /* */
213  /**********************************************************************/
214 
215 #if PGSQL_VERSION > 94
216  funcctx->max_calls = result_count;
217 #else
218  funcctx->max_calls = (uint32_t)result_count;
219 #endif
220  funcctx->user_fctx = result_tuples;
221  if (get_call_result_type(fcinfo, NULL, &tuple_desc)
222  != TYPEFUNC_COMPOSITE) {
223  ereport(ERROR,
224  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
225  errmsg("function returning record called in context "
226  "that cannot accept type record")));
227  }
228 
229  funcctx->tuple_desc = tuple_desc;
230  MemoryContextSwitchTo(oldcontext);
231  }
232 
233  funcctx = SRF_PERCALL_SETUP();
234  tuple_desc = funcctx->tuple_desc;
235  result_tuples = (General_path_element_t*) funcctx->user_fctx;
236 
237  if (funcctx->call_cntr < funcctx->max_calls) {
238  HeapTuple tuple;
239  Datum result;
240  Datum *values;
241  bool* nulls;
242 
243  /**********************************************************************/
244  /* MODIFY AS NEEDED */
245  /*
246  OUT seq INTEGER,
247  OUT path_seq INTEGER,
248  OUT node BIGINT,
249  OUT edge BIGINT,
250  OUT cost FLOAT,
251  OUT agg_cost FLOAT
252  ***********************************************************************/
253 
254  values = palloc(6 * sizeof(Datum));
255  nulls = palloc(6 * sizeof(bool));
256 
257 
258  size_t i;
259  for (i = 0; i < 6; ++i) {
260  nulls[i] = false;
261  }
262 
263  // postgres starts counting from 1
264  values[0] = Int32GetDatum(funcctx->call_cntr + 1);
265  values[1] = Int32GetDatum(result_tuples[funcctx->call_cntr].seq);
266  values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].node);
267  values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].edge);
268  values[4] = Float8GetDatum(result_tuples[funcctx->call_cntr].cost);
269  values[5] = Float8GetDatum(result_tuples[funcctx->call_cntr].agg_cost);
270  /**********************************************************************/
271 
272  tuple = heap_form_tuple(tuple_desc, values, nulls);
273  result = HeapTupleGetDatum(tuple);
274  SRF_RETURN_NEXT(funcctx, result);
275  } else {
276  /**********************************************************************/
277  /* MODIFY AS NEEDED */
278 
279  PGR_DBG("Clean up code");
280 
281  /**********************************************************************/
282 
283  SRF_RETURN_DONE(funcctx);
284  }
285 }
void do_pgr_dijkstraTRSP(pgr_edge_t *data_edges, size_t total_edges, Restrict_t *restrictions, size_t total_restrictions, int64_t start_vid, int64_t end_vid, bool directed, bool only_cost, bool strict, General_path_element_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
#define PGR_DBG(...)
Definition: debug_macro.h:34
void pgr_get_edges(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
basic edge_sql
Definition: edges_input.c:545
PG_FUNCTION_INFO_V1(dijkstraTRSP)
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
void pgr_global_report(char *log, char *notice, char *err)
notice & error
Definition: e_report.c:93
void pgr_SPI_finish(void)
if(DOXYGEN_FOUND) configure_file($
Definition: CMakeLists.txt:13
PGDLLEXPORT Datum dijkstraTRSP(PG_FUNCTION_ARGS)
postgres_connection.h
Definition: dijkstraTRSP.c:168
void pgr_SPI_connect(void)
static void process(char *edges_sql, char *restrictions_sql, int64_t start_vid, int64_t end_vid, bool directed, bool only_cost, bool strict, General_path_element_t **result_tuples, size_t *result_count)
Definition: dijkstraTRSP.c:68