vrpRouting  0.3
orders_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: pd_orders_input.c
3 
4 Copyright (c) 2016 pgRouting developers
6 
7 Developer:
8 Copyright (c) 2016 Celia Virginia Vergara Castillo
9 
10 ------
11 
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26  ********************************************************************PGR-GNU*/
27 
28 #include "c_common/orders_input.h"
29 
31 #include "c_types/column_info_t.h"
32 
33 #include "c_common/debug_macro.h"
35 #ifdef PROFILE
36 #include "c_common/time_msg.h"
37 #endif
38 
39 
40 /*
41 .. pgr_pickDeliver start
42 
43 A ``SELECT`` statement that returns the following columns:
44 
45 ::
46 
47  id, amount
48  p_id, p_tw_open, p_tw_close, [p_service,]
49  d_id, d_tw_open, d_tw_close, [d_service]
50 
51 
52 ================ =================== =========== ================================================
53 Column Type Default Description
54 ================ =================== =========== ================================================
55 **id** |ANY-INTEGER| Identifier of the pick-delivery order pair.
56 **amount** |ANY-NUMERICAL| Number of units in the order
57 **p_id** |ANY-INTEGER| The identifier of the pickup node.
58 **p_tw_open** |ANY-NUMERICAL| The time, relative to 0, when the pickup location opens.
59 **p_tw_close** |ANY-NUMERICAL| The time, relative to 0, when the pickup location closes.
60 **p_service** |ANY-NUMERICAL| 0 The duration of the loading at the pickup location.
61 **d_id** |ANY-INTEGER| The identifier of the delivery node.
62 **d_tw_open** |ANY-NUMERICAL| The time, relative to 0, when the delivery location opens.
63 **d_tw_close** |ANY-NUMERICAL| The time, relative to 0, when the delivery location closes.
64 **d_service** |ANY-NUMERICAL| 0 The duration of the unloading at the delivery location.
65 ================ =================== =========== ================================================
66 
67 .. pgr_pickDeliver end
68 
69 .. pgr_pickDeliverEuclidean start
70 
71 A ``SELECT`` statement that returns the following columns:
72 
73 ::
74 
75  id, amount
76  p_x, p_y, p_tw_open, p_tw_close, [p_service,]
77  d_x, d_y, d_tw_open, d_tw_close, [d_service]
78 
79 
80 ================ =================== =========== ================================================
81 Column Type Default Description
82 ================ =================== =========== ================================================
83 **id** |ANY-INTEGER| Identifier of the pick-delivery order pair.
84 **amount** |ANY-INTEGER| Number of units in the order
85 **p_x** |ANY-NUMERICAL| :math:`x` value of the pick up location
86 **p_y** |ANY-NUMERICAL| :math:`y` value of the pick up location
87 **p_tw_open** |ANY-INTEGER| The time, relative to 0, when the pickup location opens.
88 **p_tw_close** |ANY-INTEGER| The time, relative to 0, when the pickup location closes.
89 **p_service** |ANY-INTEGER| 0 The duration of the loading at the pickup location.
90 **d_x** |ANY-NUMERICAL| :math:`x` value of the delivery location
91 **d_y** |ANY-NUMERICAL| :math:`y` value of the delivery location
92 **d_tw_open** |ANY-INTEGER| The time, relative to 0, when the delivery location opens.
93 **d_tw_close** |ANY-INTEGER| The time, relative to 0, when the delivery location closes.
94 **d_service** |ANY-INTEGER| 0 The duration of the loading at the delivery location.
95 ================ =================== =========== ================================================
96 
97 .. pgr_pickDeliverEuclidean end
98 
99 .. vrp_pickDeliver start
100 
101 A ``SELECT`` statement that returns the following columns:
102 
103 ::
104 
105  id, amount, requested_t
106  p_id, p_tw_open, p_tw_close, [p_service,]
107  d_id, d_tw_open, d_tw_close, [d_service]
108 
109 
110 ================ =================== =========== ================================================
111 Column Type Default Description
112 ================ =================== =========== ================================================
113 **id** |ANY-INTEGER| Identifier of the pick-delivery order pair.
114 **amount** |ANY-NUMERICAL| Number of units in the order
115 **requested_t** |ANY-NUMERICAL| TODO define if it is going to be used
116 **p_id** |ANY-INTEGER| The identifier of the pickup node.
117 **p_tw_open** |ANY-NUMERICAL| The time, relative to 0, when the pickup location opens.
118 **p_tw_close** |ANY-NUMERICAL| The time, relative to 0, when the pickup location closes.
119 **p_service** |ANY-NUMERICAL| 0 The duration of the loading at the pickup location.
120 **d_id** |ANY-INTEGER| The identifier of the delivery node.
121 **d_tw_open** |ANY-NUMERICAL| The time, relative to 0, when the delivery location opens.
122 **d_tw_close** |ANY-NUMERICAL| The time, relative to 0, when the delivery location closes.
123 **d_service** |ANY-NUMERICAL| 0 The duration of the unloading at the delivery location.
124 ================ =================== =========== ================================================
125 
126 .. vrp_pickDeliver end
127 */
128 
129 static
131  HeapTuple *tuple,
132  TupleDesc *tupdesc,
133  Column_info_t *info,
134  PickDeliveryOrders_t *pd_order) {
135  pd_order->id = get_Id(tuple, tupdesc, info[0], -1);
136  pd_order->demand = get_PositiveAmount(tuple, tupdesc, info[1], 0);
137 
138  /*
139  * the pickups
140  */
141  pd_order->pick_open_t = get_TTimestamp_plain(tuple, tupdesc, info[2], -1);
142  pd_order->pick_close_t = get_TTimestamp_plain(tuple, tupdesc, info[3], -1);
143  pd_order->pick_service_t = get_TInterval_plain(tuple, tupdesc, info[4], 0);
144 
145  /*
146  * the deliveries
147  */
148  pd_order->deliver_open_t = get_TTimestamp_plain(tuple, tupdesc, info[5], -1);
149  pd_order->deliver_close_t = get_TTimestamp_plain(tuple, tupdesc, info[6], -1);
150  pd_order->deliver_service_t = get_TInterval_plain(tuple, tupdesc, info[7], 0);
151 
152  pd_order->pick_x = spi_getCoordinate(tuple, tupdesc, info[8], 0);
153  pd_order->pick_y = spi_getCoordinate(tuple, tupdesc, info[9], 0);
154  pd_order->deliver_x = spi_getCoordinate(tuple, tupdesc, info[10], 0);
155  pd_order->deliver_y = spi_getCoordinate(tuple, tupdesc, info[11], 0);
156 
157  /*
158  * ignored information
159  */
160  pd_order->pick_node_id = 0;
161  pd_order->deliver_node_id = 0;
162 }
163 
164 
165 static
167  HeapTuple *tuple,
168  TupleDesc *tupdesc,
169  Column_info_t *info,
170  PickDeliveryOrders_t *pd_order) {
171  pd_order->id = get_Id(tuple, tupdesc, info[0], -1);
172  pd_order->demand = get_PositiveAmount(tuple, tupdesc, info[1], 0);
173 
174  /*
175  * the pickups
176  */
177  pd_order->pick_node_id = get_Id(tuple, tupdesc, info[8], -1);
178  pd_order->pick_open_t = get_TTimestamp_plain(tuple, tupdesc, info[2], -1);
179  pd_order->pick_close_t = get_TTimestamp_plain(tuple, tupdesc, info[3], -1);
180  pd_order->pick_service_t = get_TInterval_plain(tuple, tupdesc, info[4], 0);
181 
182  /*
183  * the deliveries
184  */
185  pd_order->deliver_node_id = get_Id(tuple, tupdesc, info[9], -1);
186  pd_order->deliver_open_t = get_TTimestamp_plain(tuple, tupdesc, info[5], -1);
187  pd_order->deliver_close_t = get_TTimestamp_plain(tuple, tupdesc, info[6], -1);
188  pd_order->deliver_service_t = get_TInterval_plain(tuple, tupdesc, info[7], 0);
189 
190 
191  /*
192  * Ignored information
193  */
194  pd_order->pick_x = 0;
195  pd_order->pick_y = 0;
196  pd_order->deliver_x = 0;
197  pd_order->deliver_y = 0;
198 }
199 
200 static
202  HeapTuple *tuple,
203  TupleDesc *tupdesc,
204  Column_info_t *info,
205  PickDeliveryOrders_t *pd_order) {
206  pd_order->id = get_Id(tuple, tupdesc, info[0], -1);
207  pd_order->demand = get_PositiveAmount(tuple, tupdesc, info[1], 0);
208 
209  /*
210  * the pickups
211  */
212  pd_order->pick_node_id = get_Id(tuple, tupdesc, info[2], -1);
213  pd_order->pick_open_t = get_TTimestamp(tuple, tupdesc, info[3], -1);
214  pd_order->pick_close_t = get_TTimestamp(tuple, tupdesc, info[4], -1);
215  pd_order->pick_service_t = get_TInterval(tuple, tupdesc, info[5], 0);
216 
217  /*
218  * the deliveries
219  */
220  pd_order->deliver_node_id = get_Id(tuple, tupdesc, info[6], -1);
221  pd_order->deliver_open_t = get_TTimestamp(tuple, tupdesc, info[7], -1);
222  pd_order->deliver_close_t = get_TTimestamp(tuple, tupdesc, info[8], -1);
223  pd_order->deliver_service_t = get_TInterval(tuple, tupdesc, info[9], 0);
224 
225  PGR_DBG("pick_service_t %ld deliver_service_t %ld", pd_order->pick_service_t, pd_order->deliver_service_t);
226 
227  /*
228  * Ignored information
229  */
230  pd_order->pick_x = 0;
231  pd_order->pick_y = 0;
232  pd_order->deliver_x = 0;
233  pd_order->deliver_y = 0;
234 }
235 
236 
237 
238 static
239 void
241  char *pd_orders_sql,
242  PickDeliveryOrders_t **pd_orders,
243  size_t *total_pd_orders,
244 
245  Column_info_t *info,
246  const int column_count,
247 
248  int kind) {
249 #ifdef PROFILE
250  clock_t start_t = clock();
251  PGR_DBG("%s", pd_orders_sql);
252 #endif
253 
254  const int tuple_limit = 1000000;
255 
256 
257  size_t total_tuples;
258 
259  void *SPIplan;
260  SPIplan = pgr_SPI_prepare(pd_orders_sql);
261  Portal SPIportal;
262  SPIportal = pgr_SPI_cursor_open(SPIplan);
263 
264  bool moredata = true;
265  (*total_pd_orders) = total_tuples = 0;
266 
267  /* on the first tuple get the column numbers */
268 
269  while (moredata == true) {
270  SPI_cursor_fetch(SPIportal, true, tuple_limit);
271  if (total_tuples == 0) {
272  pgr_fetch_column_info(info, column_count);
273  }
274  size_t ntuples = SPI_processed;
275  total_tuples += ntuples;
276  if (ntuples > 0) {
277  if ((*pd_orders) == NULL)
278  (*pd_orders) = (PickDeliveryOrders_t *)palloc0(
279  total_tuples * sizeof(PickDeliveryOrders_t));
280  else
281  (*pd_orders) = (PickDeliveryOrders_t *)repalloc(
282  (*pd_orders),
283  total_tuples * sizeof(PickDeliveryOrders_t));
284 
285  if ((*pd_orders) == NULL) {
286  elog(ERROR, "Out of memory");
287  }
288 
289  size_t t;
290  SPITupleTable *tuptable = SPI_tuptable;
291  TupleDesc tupdesc = SPI_tuptable->tupdesc;
292  for (t = 0; t < ntuples; t++) {
293  HeapTuple tuple = tuptable->vals[t];
294  switch (kind) {
295  case 0 : fetch_timestamps(&tuple, &tupdesc, info,
296  &(*pd_orders)[total_tuples - ntuples + t]);
297  break;
298  case 1 : fetch_raw(&tuple, &tupdesc, info,
299  &(*pd_orders)[total_tuples - ntuples + t]);
300  break;
301  case 2 : fetch_euclidean(&tuple, &tupdesc, info,
302  &(*pd_orders)[total_tuples - ntuples + t]);
303  break;
304  }
305  }
306  SPI_freetuptable(tuptable);
307  } else {
308  moredata = false;
309  }
310  }
311 
312  SPI_cursor_close(SPIportal);
313 
314  if (total_tuples == 0) {
315  (*total_pd_orders) = 0;
316  return;
317  }
318 
319  (*total_pd_orders) = total_tuples;
320 #ifdef PROFILE
321  time_msg("reading shipments", start_t, clock());
322 #endif
323 }
324 
330 void
332  char *sql,
333  PickDeliveryOrders_t **rows,
334  size_t *total_rows) {
335  const int column_count = 10;
336  Column_info_t info[10];
337 
338  for (int i = 0; i < column_count; ++i) {
339  info[i].colNumber = -1;
340  info[i].type = 0;
341  info[i].strict = true;
342  info[i].eType = ANY_INTEGER;
343  }
344 
345  info[0].name = "id";
346  info[1].name = "amount";
347  info[2].name = "p_id";
348  info[3].name = "p_tw_open";
349  info[4].name = "p_tw_close";
350  info[5].name = "p_t_service";
351  info[6].name = "d_id";
352  info[7].name = "d_tw_open";
353  info[8].name = "d_tw_close";
354  info[9].name = "d_t_service";
355 
356  info[3].eType = TIMESTAMP;
357  info[4].eType = TIMESTAMP;
358  info[7].eType = TIMESTAMP;
359  info[8].eType = TIMESTAMP;
360  info[5].eType = INTERVAL;
361  info[9].eType = INTERVAL;
362 
363  /* service is optional*/
364  info[5].strict = false;
365  info[9].strict = false;
366 
367  pgr_get_pd_orders_general(sql, rows, total_rows, info, column_count, 0);
368 }
369 
375 void
377  char *sql,
378  PickDeliveryOrders_t **rows,
379  size_t *total_rows) {
380  const int column_count = 10;
381  Column_info_t info[10];
382 
383  for (int i = 0; i < column_count; ++i) {
384  info[i].colNumber = -1;
385  info[i].type = 0;
386  info[i].strict = true;
387  info[i].eType = ANY_INTEGER;
388  }
389 
390  info[0].name = "id";
391  info[1].name = "amount";
392  info[2].name = "p_open";
393  info[3].name = "p_close";
394  info[4].name = "p_service";
395  info[5].name = "d_open";
396  info[6].name = "d_close";
397  info[7].name = "d_service";
398  info[8].name = "p_id";
399  info[9].name = "d_id";
400 
401  /* service is optional*/
402  info[4].strict = false;
403  info[7].strict = false;
404 
405  pgr_get_pd_orders_general(sql, rows, total_rows, info, column_count, 1);
406 }
407 
413 void
415  char *sql,
416  PickDeliveryOrders_t **rows,
417  size_t *total_rows) {
418  const int column_count = 12;
419  Column_info_t info[12];
420 
421  for (int i = 0; i < column_count; ++i) {
422  info[i].colNumber = -1;
423  info[i].type = 0;
424  info[i].strict = true;
425  info[i].eType = ANY_INTEGER;
426  }
427 
428  info[0].name = "id";
429  info[1].name = "amount";
430  info[2].name = "p_open";
431  info[3].name = "p_close";
432  info[4].name = "p_service";
433  info[5].name = "d_open";
434  info[6].name = "d_close";
435  info[7].name = "d_service";
436  info[8].name = "p_x";
437  info[9].name = "p_y";
438  info[10].name = "d_x";
439  info[11].name = "d_y";
440 
441  /* service is optional*/
442  info[4].strict = false;
443  info[7].strict = false;
444 
445  /* (x,y) are ignored*/
446  info[8].eType = ANY_NUMERICAL;
447  info[9].eType = ANY_NUMERICAL;
448  info[10].eType = ANY_NUMERICAL;
449  info[11].eType = ANY_NUMERICAL;
450 
451  pgr_get_pd_orders_general(sql, rows, total_rows, info, column_count, 2);
452 }
PickDeliveryOrders_t::deliver_node_id
Id deliver_node_id
Deliver y coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:72
Column_info_t::colNumber
int colNumber
Definition: column_info_t.h:54
PickDeliveryOrders_t::deliver_x
Coordinate deliver_x
Pickup service duration.
Definition: pickDeliveryOrders_t.h:70
PickDeliveryOrders_t::pick_x
Coordinate pick_x
Number of demand.
Definition: pickDeliveryOrders_t.h:62
time_msg.h
pickDeliveryOrders_t.h
Column_info_t::strict
bool strict
Definition: column_info_t.h:56
pgr_SPI_prepare
SPIPlanPtr pgr_SPI_prepare(char *sql)
Definition: postgres_connection.c:88
fetch_raw
static void fetch_raw(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t *info, PickDeliveryOrders_t *pd_order)
Definition: orders_input.c:166
PickDeliveryOrders_t
order's attributes
Definition: pickDeliveryOrders_t.h:56
get_TTimestamp
TTimestamp get_TTimestamp(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, TTimestamp opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:457
PickDeliveryOrders_t::deliver_close_t
TTimestamp deliver_close_t
Deliver open time.
Definition: pickDeliveryOrders_t.h:75
get_Id
Id get_Id(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, Id opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:562
orders_input.h
get_TInterval
TInterval get_TInterval(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, TInterval opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:492
pgr_fetch_column_info
void pgr_fetch_column_info(Column_info_t info[], int info_size)
Function tells expected type of each column and then check the correspondence type of each column.
Definition: get_check_data.c:905
debug_macro.h
get_shipments
void get_shipments(char *sql, PickDeliveryOrders_t **rows, size_t *total_rows)
Reads the pick-Deliver shipments for timestams and intervals.
Definition: orders_input.c:331
Column_info_t::name
char * name
Definition: column_info_t.h:57
PickDeliveryOrders_t::id
Id id
Definition: pickDeliveryOrders_t.h:59
PickDeliveryOrders_t::pick_node_id
Id pick_node_id
Pick y coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:64
PickDeliveryOrders_t::pick_open_t
TTimestamp pick_open_t
Pickup node identifier.
Definition: pickDeliveryOrders_t.h:66
pgr_SPI_cursor_open
Portal pgr_SPI_cursor_open(SPIPlanPtr SPIplan)
Definition: postgres_connection.c:98
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
INTERVAL
@ INTERVAL
Definition: column_info_t.h:48
Column_info_t::eType
expectType eType
Definition: column_info_t.h:58
PickDeliveryOrders_t
struct PickDeliveryOrders_t PickDeliveryOrders_t
Definition: orders_input.h:30
PickDeliveryOrders_t::pick_service_t
TInterval pick_service_t
Pickup close time.
Definition: pickDeliveryOrders_t.h:68
spi_getCoordinate
Coordinate spi_getCoordinate(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, Coordinate opt_value)
get a coordinate value
Definition: get_check_data.c:819
PickDeliveryOrders_t::deliver_open_t
TTimestamp deliver_open_t
Deliver node identifier.
Definition: pickDeliveryOrders_t.h:74
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
PickDeliveryOrders_t::deliver_service_t
TInterval deliver_service_t
Deliver close time.
Definition: pickDeliveryOrders_t.h:76
ANY_INTEGER
@ ANY_INTEGER
Definition: column_info_t.h:40
column_info_t.h
PickDeliveryOrders_t::pick_close_t
TTimestamp pick_close_t
Pickup open time.
Definition: pickDeliveryOrders_t.h:67
fetch_timestamps
static void fetch_timestamps(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t *info, PickDeliveryOrders_t *pd_order)
Definition: orders_input.c:201
get_TInterval_plain
TInterval get_TInterval_plain(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, TInterval opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:527
get_PositiveAmount
PAmount get_PositiveAmount(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, PAmount opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:638
PickDeliveryOrders_t::pick_y
Coordinate pick_y
Pick x coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:63
ANY_NUMERICAL
@ ANY_NUMERICAL
Definition: column_info_t.h:41
get_shipments_euclidean
void get_shipments_euclidean(char *sql, PickDeliveryOrders_t **rows, size_t *total_rows)
Reads the pick-Deliver shipments for euclidean information.
Definition: orders_input.c:414
fetch_euclidean
static void fetch_euclidean(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t *info, PickDeliveryOrders_t *pd_order)
Definition: orders_input.c:130
get_check_data.h
PickDeliveryOrders_t::deliver_y
Coordinate deliver_y
Deliver x coordinate: used in stand alone program for benchmarks.
Definition: pickDeliveryOrders_t.h:71
pgr_get_pd_orders_general
static void pgr_get_pd_orders_general(char *pd_orders_sql, PickDeliveryOrders_t **pd_orders, size_t *total_pd_orders, Column_info_t *info, const int column_count, int kind)
Definition: orders_input.c:240
Column_info_t::type
uint64_t type
Definition: column_info_t.h:55
TIMESTAMP
@ TIMESTAMP
Definition: column_info_t.h:47
Column_info_t
Definition: column_info_t.h:52
get_TTimestamp_plain
TTimestamp get_TTimestamp_plain(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, TTimestamp opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:422
get_shipments_raw
void get_shipments_raw(char *sql, PickDeliveryOrders_t **rows, size_t *total_rows)
Reads the pick-Deliver shipments for raw data.
Definition: orders_input.c:376
PickDeliveryOrders_t::demand
PAmount demand
Order's identifier.
Definition: pickDeliveryOrders_t.h:60