pgRouting
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
contractGraph.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: contractGraph.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) 2016 Rohith Reddy
10 Mail:
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 
30 #include "postgres.h"
31 #include "executor/spi.h"
32 #include "funcapi.h"
33 #include "utils/array.h"
34 #include "catalog/pg_type.h"
35 #if PGSQL_VERSION > 92
36 #include "access/htup_details.h"
37 #endif
38 #include "utils/lsyscache.h"
39 #include "utils/builtins.h"
40 #include "fmgr.h"
41 
42 #ifndef INT8ARRAYOID
43 #define INT8ARRAYOID 1016
44 #endif
45 /*
46  Uncomment when needed
47 */
48 
49 // #define DEBUG
50 #include "./../../common/src/debug_macro.h"
51 #include "./../../common/src/pgr_types.h"
52 #include "./structs.h"
53 #include "./../../common/src/postgres_connection.h"
54 #include "./../../common/src/edges_input.h"
55 #include "./../../common/src/arrays_input.h"
56 #include "./contractGraph_driver.h"
57 
58 PGDLLEXPORT Datum contractGraph(PG_FUNCTION_ARGS);
59 
60 
61 /********************************************************************/
62 /* MODIFY AS NEEDED */
63 static
64 void
65 process(char* edges_sql,
66  int64_t *forbidden_vertices,
67  int64_t *contraction_order,
68  size_t size_forbidden_vertices,
69  size_t size_contraction_order,
70  int num_cycles,
71  bool directed,
72  pgr_contracted_blob **result_tuples,
73  size_t *result_count) {
75  PGR_DBG("num_cycles %d ", num_cycles);
76  PGR_DBG("directed %d ", directed);
77  PGR_DBG("edges_sql %s", edges_sql);
78  PGR_DBG("Load data");
79  pgr_edge_t *edges = NULL;
80  size_t total_tuples = 0;
81  // TODO (Rohith) decide if is a requirement (ERROR) or not
82  if (num_cycles < 1) {
83  // TODO (Rohith) if ERROR free edges_sql, and the arrays
84  PGR_DBG("Required: at least one cycle\n");
85  (*result_count) = 0;
86  (*result_tuples) = NULL;
88  return;
89  }
90  for (size_t i = 0; i < size_contraction_order; ++i) {
91  if (is_valid_contraction(contraction_order[i]) != 1) {
92  PGR_DBG("Error: Enter a valid Contraction Type\n");
93  (*result_count) = 0;
94  (*result_tuples) = NULL;
96  return;
97  }
98  }
99  pgr_get_edges(edges_sql, &edges, &total_tuples);
100  PGR_DBG("finished Loading");
101  if (total_tuples == 0) {
102  PGR_DBG("No edges found");
103  (*result_count) = 0;
104  (*result_tuples) = NULL;
105  pgr_SPI_finish();
106  return;
107  }
108  PGR_DBG("Total %ld tuples in query:", total_tuples);
109  PGR_DBG("Starting processing");
110  char *err_msg = NULL;
111 #if 1
113  edges,
114  total_tuples,
115  forbidden_vertices,
116  size_forbidden_vertices,
117  contraction_order,
118  size_contraction_order,
119  num_cycles,
120  directed,
121  result_tuples,
122  result_count,
123  &err_msg);
124 #endif
125  PGR_DBG("Returning %ld tuples\n", *result_count);
126  PGR_DBG("Returned message = %s\n", err_msg);
127  free(err_msg);
128  pfree(edges);
129  pgr_SPI_finish();
130 }
131 /* */
132 /******************************************************************************/
133 
135 PGDLLEXPORT Datum
136 contractGraph(PG_FUNCTION_ARGS) {
137  FuncCallContext *funcctx;
138  size_t call_cntr;
139  size_t max_calls;
140  TupleDesc tuple_desc;
141  pgr_contracted_blob *result_tuples = NULL;
142  size_t result_count = 0;
143  int64_t* contraction_order;
144  int64_t* forbidden_vertices;
145  size_t size_contraction_order;
146  size_t size_forbidden_vertices;
147  if (SRF_IS_FIRSTCALL()) {
148  MemoryContext oldcontext;
149  funcctx = SRF_FIRSTCALL_INIT();
150  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
151  /**********************************************************************/
152  /* MODIFY AS NEEDED */
153  /*
154  edges_sql TEXT,
155  contraction_order BIGINT[],
156  max_cycles integer DEFAULT 1,
157  forbidden_vertices BIGINT[] DEFAULT ARRAY[]::BIGINT[],
158  directed BOOLEAN DEFAULT true
159  **********************************************************************/
160 
161  forbidden_vertices = (int64_t*)
162  pgr_get_bigIntArray_allowEmpty(&size_forbidden_vertices , PG_GETARG_ARRAYTYPE_P(3));
163  PGR_DBG("size_forbidden_vertices %ld", size_forbidden_vertices);
164 
165  contraction_order = (int64_t*)
166  pgr_get_bigIntArray(&size_contraction_order, PG_GETARG_ARRAYTYPE_P(1));
167  PGR_DBG("size_contraction_order %ld ", size_contraction_order);
168 #if 1
169  PGR_DBG("Calling process");
170  process(
171  pgr_text2char(PG_GETARG_TEXT_P(0)),
172  forbidden_vertices,
173  contraction_order,
174  size_forbidden_vertices,
175  size_contraction_order,
176  PG_GETARG_INT32(2),
177  PG_GETARG_BOOL(4),
178  &result_tuples,
179  &result_count);
180 #endif
181  PGR_DBG("Cleaning arrays");
182  free(contraction_order);
183  free(forbidden_vertices);
184  PGR_DBG("Returned %d tuples\n", (int)result_count);
185  funcctx->max_calls = (uint32_t)result_count;
186  funcctx->user_fctx = result_tuples;
187  if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
188  ereport(ERROR,
189  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
190  errmsg("function returning record called in context "
191  "that cannot accept type record")));
192  funcctx->tuple_desc = tuple_desc;
193  MemoryContextSwitchTo(oldcontext);
194  }
195  funcctx = SRF_PERCALL_SETUP();
196  call_cntr = funcctx->call_cntr;
197  max_calls = funcctx->max_calls;
198  tuple_desc = funcctx->tuple_desc;
199  result_tuples = (pgr_contracted_blob*) funcctx->user_fctx;
200  if (call_cntr < max_calls) {
201  HeapTuple tuple;
202  Datum result;
203  Datum *values;
204  Datum *contracted_vertices_array;
205  char *nulls;
206  ArrayType * arrayType;
207  int16 typlen;
208  bool typbyval;
209  char typalign;
210  values =(Datum *)palloc(7 * sizeof(Datum));
211  nulls = palloc(7 * sizeof(bool));
212  size_t i;
213  for (i = 0; i < 7; ++i) {
214  nulls[i] = false;
215  }
216  int contracted_vertices_size =
217  (int)result_tuples[call_cntr].contracted_vertices_size;
218  contracted_vertices_array = (Datum *)palloc(sizeof(Datum) *
219  (size_t)contracted_vertices_size);
220  for (i = 0; i < contracted_vertices_size; ++i) {
221  PGR_DBG("Storing contracted vertex %ld", result_tuples[call_cntr].contracted_vertices[i]);
222  contracted_vertices_array[i] =
223  Int64GetDatum(result_tuples[call_cntr].contracted_vertices[i]);
224  }
225  get_typlenbyvalalign(INT8OID, &typlen, &typbyval, &typalign);
226  arrayType = construct_array(contracted_vertices_array,
227  contracted_vertices_size,
228  INT8OID, typlen, typbyval, typalign);
229  TupleDescInitEntry(tuple_desc, (AttrNumber) 4, "contracted_vertices",
230  INT8ARRAYOID, -1, 0);
231 
232 #if 1
233  PGR_DBG("%ld | %s | %ld | %ld | %f | %d",
234  result_tuples[call_cntr].id,
235  result_tuples[call_cntr].type,
236  result_tuples[call_cntr].source,
237  result_tuples[call_cntr].target,
238  result_tuples[call_cntr].cost,
239  result_tuples[call_cntr].contracted_vertices_size);
240 #endif
241  PGR_DBG("Storing complete\n");
242  // postgres starts counting from 1
243  values[0] = Int32GetDatum(call_cntr + 1);
244  values[1] = CStringGetTextDatum(result_tuples[call_cntr].type);
245  values[2] = Int64GetDatum(result_tuples[call_cntr].id);
246  values[3] = PointerGetDatum(arrayType);
247  values[4] = Int64GetDatum(result_tuples[call_cntr].source);
248  values[5] = Int64GetDatum(result_tuples[call_cntr].target);
249  values[6] = Float8GetDatum(result_tuples[call_cntr].cost);
250  // values[7] = Int32GetDatum(result_tuples[call_cntr].contracted_vertices_size);
251  /*********************************************************************/
252  tuple = heap_form_tuple(tuple_desc, values, nulls);
253  result = HeapTupleGetDatum(tuple);
254  // cleaning up the contracted vertices array
255  if (result_tuples[call_cntr].contracted_vertices) {
256  free(result_tuples[call_cntr].contracted_vertices);
257  }
258  SRF_RETURN_NEXT(funcctx, result);
259  } else {
260  // cleanup
261  PGR_DBG("Freeing values");
262  if (result_tuples) free(result_tuples);
263  SRF_RETURN_DONE(funcctx);
264  }
265  PGR_DBG("End of Function");
266 }
267 
PGDLLEXPORT Datum contractGraph(PG_FUNCTION_ARGS)
#define PGR_DBG(...)
Definition: debug_macro.h:33
int64_t * pgr_get_bigIntArray_allowEmpty(size_t *arrlen, ArrayType *input)
Definition: arrays_input.c:119
void pgr_get_edges(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
basic edge_sql
Definition: edges_input.c:535
int64_t * pgr_get_bigIntArray(size_t *arrlen, ArrayType *input)
Definition: arrays_input.c:38
static void process(char *edges_sql, int64_t *forbidden_vertices, int64_t *contraction_order, size_t size_forbidden_vertices, size_t size_contraction_order, int num_cycles, bool directed, pgr_contracted_blob **result_tuples, size_t *result_count)
Definition: contractGraph.c:65
PG_FUNCTION_INFO_V1(contractGraph)
void pgr_SPI_finish(void)
edge_astar_t * edges
Definition: BDATester.cpp:46
void pgr_SPI_connect(void)
int is_valid_contraction(int64_t number)
void do_pgr_contractGraph(pgr_edge_t *data_edges, size_t total_edges, int64_t *forbidden_vertices, size_t size_forbidden_vertices, int64_t *contraction_order, size_t size_contraction_order, int64_t max_cycles, bool directed, pgr_contracted_blob **return_tuples, size_t *return_count, char **err_msg)
#define INT8ARRAYOID
Definition: contractGraph.c:43
char * err_msg
Definition: BDATester.cpp:50
char * pgr_text2char(text *in)