vrpRouting  0.3
time_windows_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: time_windows_input.c
3 
4 Copyright (c) 2021 pgRouting developers
6 
7 Function's developer:
8 Copyright (c) 2021 Ashish Kumar
10 
11 ------
12 
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17 
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 
27  ********************************************************************PGR-GNU*/
28 
30 
31 /*
32 .. vrp_vroom start
33 
34 A ``SELECT`` statement that returns the following columns:
35 
36 ::
37 
38  id [, kind], tw_open, tw_close
39 
40 ==================== ====================================== =====================================================
41 Column Type Description
42 ==================== ====================================== =====================================================
43 **id** ``ANY-INTEGER`` Positive unique identifier of the job,
44  pickup/delivery shipment, or break.
45 
46 **kind** ``CHAR`` **Only required for shipments time windows**.
47  Value in ['p', 'd'] indicating whether
48  the time window is for:
49 
50  - Pickup shipment, or
51  - Delivery shipment.
52 
53 **tw_open** |timestamp| Time window opening time.
54 
55 **tw_close** |timestamp| Time window closing time.
56 ==================== ====================================== =====================================================
57 
58 **Note**:
59 
60 - All timings are in **seconds** when represented as an ``INTEGER``.
61 - Every row must satisfy the condition: :code:`tw_open ≤ tw_close`.
62 - It is up to users to decide how to describe time windows:
63 
64  - **Relative values**, e.g. [0, 14400] for a 4 hours time window starting at the beginning of the planning horizon. In that case all times reported in output with the arrival column are relative to the start of the planning horizon.
65  - **Absolute values**, "real" timestamps. In that case all times reported in output with the arrival column can be interpreted as timestamps.
66 
67 .. vrp_vroom end
68 */
69 
70 static
72  HeapTuple *tuple,
73  TupleDesc *tupdesc,
74  Column_info_t *info,
75  Vroom_time_window_t *time_window,
76  bool is_shipment,
77  bool is_plain) {
78 
79  time_window->id = get_Idx(tuple, tupdesc, info[0], 0);
80 
81  if (is_shipment) {
82  char kind = get_Kind(tuple, tupdesc, info[1], ' ');
83  if (kind != 'p' && kind != 'd') {
84  ereport(ERROR, (errmsg("Invalid kind %c", kind),
85  errhint("Kind must be either 'p' or 'd'")));
86  }
87  time_window->kind = kind;
88  if (is_plain) {
89  time_window->tw_open = get_Duration(tuple, tupdesc, info[2], 0);
90  time_window->tw_close = get_Duration(tuple, tupdesc, info[3], 0);
91  } else {
92  time_window->tw_open =
93  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[2], 0);
94  time_window->tw_close =
95  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[3], 0);
96  }
97  } else {
98  if (is_plain) {
99  time_window->tw_open = get_Duration(tuple, tupdesc, info[1], 0);
100  time_window->tw_close = get_Duration(tuple, tupdesc, info[2], 0);
101  } else {
102  time_window->tw_open =
103  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[1], 0);
104  time_window->tw_close =
105  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[2], 0);
106  }
107  }
108 
109  if (time_window->tw_open > time_window->tw_close) {
110  ereport(ERROR,
111  (errmsg("Invalid time window (%d, %d)",
112  time_window->tw_open, time_window->tw_close),
113  errhint("Time window start time %d must be "
114  "less than or equal to time window end time %d",
115  time_window->tw_open, time_window->tw_close)));
116  }
117 }
118 
119 
120 static
122  char *time_windows_sql,
123  Vroom_time_window_t **time_windows,
124  size_t *total_time_windows,
125 
126  Column_info_t *info,
127  const int column_count,
128  bool is_shipment,
129  bool is_plain) {
130 #ifdef PROFILE
131  clock_t start_t = clock();
132  PGR_DBG("%s", time_windows_sql);
133 #endif
134 
135  const int tuple_limit = 1000000;
136 
137  size_t total_tuples;
138 
139  void *SPIplan;
140  SPIplan = pgr_SPI_prepare(time_windows_sql);
141  Portal SPIportal;
142  SPIportal = pgr_SPI_cursor_open(SPIplan);
143 
144  bool moredata = true;
145  (*total_time_windows) = total_tuples = 0;
146 
147  /* on the first tuple get the column numbers */
148 
149  while (moredata == true) {
150  SPI_cursor_fetch(SPIportal, true, tuple_limit);
151  if (total_tuples == 0) {
152  pgr_fetch_column_info(info, column_count);
153  }
154  size_t ntuples = SPI_processed;
155  total_tuples += ntuples;
156  if (ntuples > 0) {
157  if ((*time_windows) == NULL)
158  (*time_windows) = (Vroom_time_window_t *)palloc0(
159  total_tuples * sizeof(Vroom_time_window_t));
160  else
161  (*time_windows) = (Vroom_time_window_t *)repalloc(
162  (*time_windows),
163  total_tuples * sizeof(Vroom_time_window_t));
164 
165  if ((*time_windows) == NULL) {
166  elog(ERROR, "Out of memory");
167  }
168 
169  size_t t;
170  SPITupleTable *tuptable = SPI_tuptable;
171  TupleDesc tupdesc = SPI_tuptable->tupdesc;
172  for (t = 0; t < ntuples; t++) {
173  HeapTuple tuple = tuptable->vals[t];
174  fetch_time_windows(&tuple, &tupdesc, info,
175  &(*time_windows)[total_tuples - ntuples + t],
176  is_shipment, is_plain);
177  }
178  SPI_freetuptable(tuptable);
179  } else {
180  moredata = false;
181  }
182  }
183 
184  SPI_cursor_close(SPIportal);
185 
186  if (total_tuples == 0) {
187  (*total_time_windows) = 0;
188  return;
189  }
190 
191  (*total_time_windows) = total_tuples;
192 #ifdef PROFILE
193  time_msg("reading time windows", start_t, clock());
194 #endif
195 }
196 
197 
203 void
205  char *sql,
206  Vroom_time_window_t **rows,
207  size_t *total_rows,
208  bool is_plain) {
209  int kColumnCount = 3;
210  Column_info_t info[kColumnCount];
211 
212  for (int i = 0; i < kColumnCount; ++i) {
213  info[i].colNumber = -1;
214  info[i].type = 0;
215  info[i].strict = true;
216  info[i].eType = INTEGER;
217  }
218 
219  info[0].name = "id";
220  info[1].name = "tw_open";
221  info[2].name = "tw_close";
222 
223  info[0].eType = ANY_INTEGER; // id
224 
225  if (!is_plain) {
226  info[1].eType = TIMESTAMP; // tw_open
227  info[2].eType = TIMESTAMP; // tw_close
228  }
229 
230  db_get_time_windows(sql, rows, total_rows, info, kColumnCount, 0, is_plain);
231 }
232 
238 void
240  char *sql,
241  Vroom_time_window_t **rows,
242  size_t *total_rows,
243  bool is_plain) {
244  int kColumnCount = 4;
245  Column_info_t info[kColumnCount];
246 
247  for (int i = 0; i < kColumnCount; ++i) {
248  info[i].colNumber = -1;
249  info[i].type = 0;
250  info[i].strict = true;
251  info[i].eType = INTEGER;
252  }
253 
254  info[0].name = "id";
255  info[1].name = "kind";
256  info[2].name = "tw_open";
257  info[3].name = "tw_close";
258 
259  info[0].eType = ANY_INTEGER; // id
260  info[1].eType = CHAR1; // kind
261 
262  if (!is_plain) {
263  info[2].eType = TIMESTAMP; // tw_open
264  info[3].eType = TIMESTAMP; // tw_close
265  }
266 
267  db_get_time_windows(sql, rows, total_rows, info, kColumnCount, 1, is_plain);
268 }
Column_info_t::colNumber
int colNumber
Definition: column_info_t.h:54
time_windows_input.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
Vroom_time_window_t
Time window's attributes.
Definition: vroom_time_window_t.h:46
Vroom_time_window_t::id
Idx id
Definition: vroom_time_window_t.h:47
Vroom_time_window_t::kind
char kind
Definition: vroom_time_window_t.h:48
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
get_PositiveTTimestamp
TTimestamp get_PositiveTTimestamp(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:476
Column_info_t::name
char * name
Definition: column_info_t.h:57
pgr_SPI_cursor_open
Portal pgr_SPI_cursor_open(SPIPlanPtr SPIplan)
Definition: postgres_connection.c:98
get_vroom_shipments_time_windows
void get_vroom_shipments_time_windows(char *sql, Vroom_time_window_t **rows, size_t *total_rows, bool is_plain)
Reads the VROOM shipments time windows.
Definition: time_windows_input.c:239
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
get_Duration
Duration get_Duration(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, Duration opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:681
Vroom_time_window_t::tw_close
Duration tw_close
Definition: vroom_time_window_t.h:50
Column_info_t::eType
expectType eType
Definition: column_info_t.h:58
Vroom_time_window_t::tw_open
Duration tw_open
Definition: vroom_time_window_t.h:49
get_Kind
char get_Kind(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, char opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:725
get_vroom_time_windows
void get_vroom_time_windows(char *sql, Vroom_time_window_t **rows, size_t *total_rows, bool is_plain)
Reads the VROOM time windows.
Definition: time_windows_input.c:204
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
ANY_INTEGER
@ ANY_INTEGER
Definition: column_info_t.h:40
Duration
uint32_t Duration
Definition: typedefs.h:81
get_Idx
Idx get_Idx(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, Idx opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:581
Column_info_t::type
uint64_t type
Definition: column_info_t.h:55
TIMESTAMP
@ TIMESTAMP
Definition: column_info_t.h:47
CHAR1
@ CHAR1
Definition: column_info_t.h:44
Column_info_t
Definition: column_info_t.h:52
INTEGER
@ INTEGER
Definition: column_info_t.h:39
Vroom_time_window_t
struct Vroom_time_window_t Vroom_time_window_t
Definition: typedefs.h:98
fetch_time_windows
static void fetch_time_windows(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t *info, Vroom_time_window_t *time_window, bool is_shipment, bool is_plain)
Definition: time_windows_input.c:71
db_get_time_windows
static void db_get_time_windows(char *time_windows_sql, Vroom_time_window_t **time_windows, size_t *total_time_windows, Column_info_t *info, const int column_count, bool is_shipment, bool is_plain)
Definition: time_windows_input.c:121