PGROUTING  2.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vehicles_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: vehicles_input.c
3 
4 Copyright (c) 2016 Celia Virginia Vergara Castillo
5 vicky_vergara@hotmail.com
6 
7 ------
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23  ********************************************************************PGR-GNU*/
24 
26 
27 #include <limits.h>
28 #if PGSQL_VERSION > 96
29 #include <float.h>
30 #endif
31 
32 #if PGSQL_VERSION == 100
33 #include <float.h>
34 #endif
35 
36 
37 #include "c_types/column_info_t.h"
38 
39 #include "c_common/debug_macro.h"
41 #include "c_common/time_msg.h"
42 
43 
44 static
46  HeapTuple *tuple,
47  TupleDesc *tupdesc,
48  Column_info_t info[16],
49  Vehicle_t *vehicle,
50  bool with_id) {
51 
52  vehicle->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
53  vehicle->capacity = pgr_SPI_getFloat8(tuple, tupdesc, info[1]);
54 
55  vehicle->start_x = with_id ?
56  0 :
57  pgr_SPI_getFloat8(tuple, tupdesc, info[2]);
58  vehicle->start_y = with_id ?
59  0 :
60  pgr_SPI_getFloat8(tuple, tupdesc, info[3]);
61 
62  vehicle->speed = column_found(info[13].colNumber) ?
63  pgr_SPI_getFloat8(tuple, tupdesc, info[13]) :
64  1;
65  vehicle->cant_v = column_found(info[4].colNumber) ?
66  pgr_SPI_getBigInt(tuple, tupdesc, info[4]) :
67  1;
68  vehicle->start_open_t = column_found(info[5].colNumber) ?
69  pgr_SPI_getFloat8(tuple, tupdesc, info[5]) :
70  0;
71  vehicle->start_close_t = column_found(info[6].colNumber) ?
72  pgr_SPI_getFloat8(tuple, tupdesc, info[6]) :
73  DBL_MAX;
74  vehicle->start_service_t = column_found(info[7].colNumber) ?
75  pgr_SPI_getFloat8(tuple, tupdesc, info[7]) :
76  0;
77 
78 
79  if (!(column_found(info[8].colNumber)) && column_found(info[9].colNumber)) {
80  ereport(ERROR,
81  (errmsg("Column \'%s\' not Found", info[8].name),
82  errhint("%s was found, also column is expected %s ", info[9].name, info[8].name)));
83  }
84  if (column_found(info[8].colNumber) && !(column_found(info[9].colNumber))) {
85  ereport(ERROR,
86  (errmsg("Column \'%s\' not Found", info[9].name),
87  errhint("%s was found, also column is expected %s ", info[8].name, info[9].name)));
88  }
89 
90  vehicle->end_x = column_found(info[8].colNumber) ?
91  pgr_SPI_getFloat8(tuple, tupdesc, info[8]) :
92  vehicle->start_x;
93  vehicle->end_y = column_found(info[9].colNumber) ?
94  pgr_SPI_getFloat8(tuple, tupdesc, info[9]) :
95  vehicle->start_y;
96 
97  if (!(column_found(info[10].colNumber)) && column_found(info[11].colNumber)) {
98  ereport(ERROR,
99  (errmsg("Column \'%s\' not Found", info[10].name),
100  errhint("%s was found, also column is expected %s ", info[10].name, info[11].name)));
101  }
102 
103  if (column_found(info[10].colNumber) && !(column_found(info[11].colNumber))) {
104  ereport(ERROR,
105  (errmsg("Column \'%s\' not Found", info[11].name),
106  errhint("%s was found, also column is expected %s ", info[11].name, info[10].name)));
107  }
108  vehicle->end_open_t = column_found(info[10].colNumber) ?
109  pgr_SPI_getFloat8(tuple, tupdesc, info[10]) :
110  vehicle->start_open_t;
111  vehicle->end_close_t = column_found(info[11].colNumber) ?
112  pgr_SPI_getFloat8(tuple, tupdesc, info[11]) :
113  vehicle->start_close_t;
114  vehicle->end_service_t = column_found(info[12].colNumber) ?
115  pgr_SPI_getFloat8(tuple, tupdesc, info[12]) :
116  vehicle->start_service_t;
117 
118  vehicle->speed = column_found(info[13].colNumber) ?
119  pgr_SPI_getFloat8(tuple, tupdesc, info[13]) :
120  1;
121  vehicle->start_node_id = with_id ?
122  pgr_SPI_getBigInt(tuple, tupdesc, info[14]) :
123  0;
124  vehicle->end_node_id = with_id ?
125  (column_found(info[12].colNumber) ?
126  pgr_SPI_getBigInt(tuple, tupdesc, info[15]) :
127  vehicle->start_node_id) :
128  0;
129 }
130 
131 
132 
133 static
135  char *vehicles_sql,
136  Vehicle_t **vehicles,
137  size_t *total_vehicles,
138  bool with_id) {
139  clock_t start_t = clock();
140 
141  const int tuple_limit = 1000000;
142 
143  PGR_DBG("pgr_get_vehicles");
144  PGR_DBG("%s", vehicles_sql);
145 
146  Column_info_t info[16];
147 
148  int i;
149  for (i = 0; i < 16; ++i) {
150  info[i].colNumber = -1;
151  info[i].type = 0;
152  info[i].strict = true;
153  info[i].eType = ANY_NUMERICAL;
154  }
155 
156  info[0].name = strdup("id");
157  info[1].name = strdup("capacity");
158  info[2].name = strdup("start_x");
159  info[3].name = strdup("start_y");
160  info[4].name = strdup("number");
161  info[5].name = strdup("start_open");
162  info[6].name = strdup("start_close");
163  info[7].name = strdup("start_service");
164  info[8].name = strdup("end_x");
165  info[9].name = strdup("end_y");
166  info[10].name = strdup("end_open");
167  info[11].name = strdup("end_close");
168  info[12].name = strdup("end_service");
169  info[13].name = strdup("speed");
170  info[14].name = strdup("start_node_id");
171  info[15].name = strdup("end_node_id");
172 
173  info[0].eType = ANY_INTEGER;
174  info[4].eType = ANY_INTEGER;
175  info[14].eType = ANY_INTEGER;
176  info[15].eType = ANY_INTEGER;
177 
178  for (i = 4; i < 16; ++i) {
179  info[i].strict = false;
180  }
181 
182  if (with_id) {
183  /*
184  * with id, then start_x and start_y are optional
185  * start_node_id is compulsory
186  */
187  info[2].strict = false;
188  info[3].strict = false;
189  info[14].strict = true;
190 
191  }
192 
193  size_t ntuples;
194  size_t total_tuples;
195 
196  void *SPIplan;
197  SPIplan = pgr_SPI_prepare(vehicles_sql);
198  Portal SPIportal;
199  SPIportal = pgr_SPI_cursor_open(SPIplan);
200 
201  bool moredata = TRUE;
202  (*total_vehicles) = total_tuples = 0;
203 
204  /* on the first tuple get the column numbers */
205 
206  while (moredata == TRUE) {
207  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
208  if (total_tuples == 0) {
209  pgr_fetch_column_info(info, 16);
210  }
211  ntuples = SPI_processed;
212  total_tuples += ntuples;
213  PGR_DBG("SPI_processed %ld", ntuples);
214  if (ntuples > 0) {
215  if ((*vehicles) == NULL)
216  (*vehicles) = (Vehicle_t *)palloc0(
217  total_tuples * sizeof(Vehicle_t));
218  else
219  (*vehicles) = (Vehicle_t *)repalloc(
220  (*vehicles),
221  total_tuples * sizeof(Vehicle_t));
222 
223  if ((*vehicles) == NULL) {
224  elog(ERROR, "Out of memory");
225  }
226 
227  size_t t;
228  SPITupleTable *tuptable = SPI_tuptable;
229  TupleDesc tupdesc = SPI_tuptable->tupdesc;
230  PGR_DBG("processing %ld", ntuples);
231  for (t = 0; t < ntuples; t++) {
232  HeapTuple tuple = tuptable->vals[t];
233  fetch_vehicles(&tuple, &tupdesc, info,
234  &(*vehicles)[total_tuples - ntuples + t], with_id);
235  }
236  SPI_freetuptable(tuptable);
237  } else {
238  moredata = FALSE;
239  }
240  }
241 
242  SPI_cursor_close(SPIportal);
243 
244  if (total_tuples == 0) {
245  (*total_vehicles) = 0;
246  PGR_DBG("NO orders");
247  return;
248  }
249 
250  (*total_vehicles) = total_tuples;
251  if (with_id) {
252  PGR_DBG("Finish reading %ld vehicles for matrix", (*total_vehicles));
253  } else {
254  PGR_DBG("Finish reading %ld vehicles for eucledian", (*total_vehicles));
255  }
256  time_msg("reading edges", start_t, clock());
257 
258 }
259 
260 void
262  char *vehicles_sql,
263  Vehicle_t **vehicles,
264  size_t *total_vehicles) {
265  pgr_get_vehicles_general( vehicles_sql, vehicles, total_vehicles, false);
266 }
267 
268 void
270  char *vehicles_sql,
271  Vehicle_t **vehicles,
272  size_t *total_vehicles) {
273  pgr_get_vehicles_general(vehicles_sql, vehicles, total_vehicles, true);
274 }
275 
int64_t pgr_SPI_getBigInt(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
void pgr_get_vehicles_with_id(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles)
Reads the vehicles orders.
static void fetch_vehicles(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[16], Vehicle_t *vehicle, bool with_id)
double capacity
Definition: vehicle_t.h:62
double end_service_t
Definition: vehicle_t.h:81
static void pgr_get_vehicles_general(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles, bool with_id)
double start_open_t
Definition: vehicle_t.h:71
#define PGR_DBG(...)
Definition: debug_macro.h:34
double end_close_t
Definition: vehicle_t.h:80
double end_open_t
Definition: vehicle_t.h:79
uint64_t type
Definition: column_info_t.h:73
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
double start_y
Definition: vehicle_t.h:66
double start_close_t
Definition: vehicle_t.h:72
int64_t cant_v
Definition: vehicle_t.h:69
void pgr_fetch_column_info(Column_info_t info[], int info_size)
double start_service_t
Definition: vehicle_t.h:73
double end_x
Definition: vehicle_t.h:75
double end_y
Definition: vehicle_t.h:76
int64_t end_node_id
Definition: vehicle_t.h:77
double start_x
Definition: vehicle_t.h:65
double speed
Definition: vehicle_t.h:63
int64_t start_node_id
Definition: vehicle_t.h:67
bool column_found(int colNumber)
Portal pgr_SPI_cursor_open(SPIPlanPtr SPIplan)
double pgr_SPI_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
int64_t id
Definition: vehicle_t.h:61
void pgr_get_vehicles(char *vehicles_sql, Vehicle_t **vehicles, size_t *total_vehicles)
Reads the vehicles orders.
SPIPlanPtr pgr_SPI_prepare(char *sql)
expectType eType
Definition: column_info_t.h:76