vrpRouting  0.3
vroom/vehicles_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: vehicles_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, start_id, end_id
39  [, capacity, skills, tw_open, tw_close, speed_factor, max_tasks, data]
40 
41 
42 ====================== ======================== =================== ================================================
43 Column Type Default Description
44 ====================== ======================== =================== ================================================
45 **id** ``ANY-INTEGER`` Positive unique identifier of the vehicle.
46 
47 **start_id** ``ANY-INTEGER`` Positive identifier of the vehicle start location.
48 
49 **end_id** ``ANY-INTEGER`` Positive identifier of the vehicle end location.
50 
51 **capacity** ``ARRAY[ANY-INTEGER]`` Empty Array Array of non-negative integers describing
52  multidimensional quantities such as
53  number of items, weight, volume etc.
54 
55  - All vehicles must have the same value of
56  :code:`array_length(capacity, 1)`
57 
58 **skills** ``ARRAY[INTEGER]`` Empty Array Array of non-negative integers defining
59  mandatory skills.
60 
61 **tw_open** |timestamp| |tw_open_default| Time window opening time.
62 
63 **tw_close** |timestamp| |tw_close_default| Time window closing time.
64 
65 **speed_factor** ``ANY-NUMERICAL`` :math:`1.0` Vehicle travel time multiplier.
66 
67  - Max value of speed factor for a vehicle shall not be
68  greater than 5 times the speed factor of any other vehicle.
69 
70 **max_tasks** ``INTEGER`` :math:`2147483647` Maximum number of tasks in a route for the vehicle.
71 
72  - A job, pickup, or delivery is counted as a single task.
73 
74 **data** ``JSONB`` '{}'::JSONB Any metadata information of the vehicle.
75 ====================== ======================== =================== ================================================
76 
77 **Note**:
78 
79 - At least one of the ``start_id`` or ``end_id`` shall be present.
80 - If ``end_id`` is omitted, the resulting route will stop at the last visited task, whose choice is determined by the optimization process.
81 - If ``start_id`` is omitted, the resulting route will start at the first visited task, whose choice is determined by the optimization process.
82 - To request a round trip, specify both ``start_id`` and ``end_id`` as the same index.
83 - A vehicle is only allowed to serve a set of tasks if the resulting load at each route step is lower than the matching value in capacity for each metric. When using multiple components for amounts, it is recommended to put the most important/limiting metrics first.
84 - It is assumed that all delivery-related amounts for jobs are loaded at vehicle start, while all pickup-related amounts for jobs are brought back at vehicle end.
85 - :code:`tw_open ≤ tw_close`
86 
87 .. vrp_vroom end
88 */
89 
90 static
92  HeapTuple *tuple,
93  TupleDesc *tupdesc,
94  Column_info_t *info,
95  Vroom_vehicle_t *vehicle,
96  bool is_plain) {
97  vehicle->id = get_Idx(tuple, tupdesc, info[0], 0);
98  vehicle->start_id = get_MatrixIndex(tuple, tupdesc, info[1], -1);
99  vehicle->end_id = get_MatrixIndex(tuple, tupdesc, info[2], -1);
100 
101  vehicle->capacity_size = 0;
102  vehicle->capacity = column_found(info[3].colNumber) ?
103  spi_getPositiveBigIntArr_allowEmpty(tuple, tupdesc, info[3], &vehicle->capacity_size)
104  : NULL;
105 
106  vehicle->skills_size = 0;
107  vehicle->skills = column_found(info[4].colNumber) ?
108  spi_getPositiveIntArr_allowEmpty(tuple, tupdesc, info[4], &vehicle->skills_size)
109  : NULL;
110 
111  if (is_plain) {
112  vehicle->tw_open = get_Duration(tuple, tupdesc, info[5], 0);
113  vehicle->tw_close = get_Duration(tuple, tupdesc, info[6], UINT_MAX);
114  } else {
115  vehicle->tw_open =
116  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[5], 0);
117  vehicle->tw_close =
118  (Duration)get_PositiveTTimestamp(tuple, tupdesc, info[6], UINT_MAX);
119  }
120 
121  if (vehicle->tw_open > vehicle->tw_close) {
122  ereport(ERROR,
123  (errmsg("Invalid time window (%d, %d)",
124  vehicle->tw_open, vehicle->tw_close),
125  errhint("Time window start time %d must be "
126  "less than or equal to time window end time %d",
127  vehicle->tw_open, vehicle->tw_close)));
128  }
129 
130  vehicle->speed_factor = column_found(info[7].colNumber) ?
131  spi_getFloat8(tuple, tupdesc, info[7])
132  : 1.0;
133 
134  if (vehicle->speed_factor <= 0.0) {
135  ereport(ERROR, (errmsg("Invalid speed_factor %lf", vehicle->speed_factor),
136  errhint("Speed factor must be greater than 0")));
137  }
138 
139  vehicle->max_tasks = column_found(info[8].colNumber)
140  ? spi_getMaxTasks(tuple, tupdesc, info[8])
141  : INT_MAX; // 2147483647
142 
143  vehicle->data = column_found(info[9].colNumber)
144  ? spi_getText(tuple, tupdesc, info[9])
145  : strdup("{}");
146 }
147 
148 
149 static
151  char *vehicles_sql,
152  Vroom_vehicle_t **vehicles,
153  size_t *total_vehicles,
154 
155  Column_info_t *info,
156  const int column_count,
157  bool is_plain) {
158 #ifdef PROFILE
159  clock_t start_t = clock();
160  PGR_DBG("%s", vehicles_sql);
161 #endif
162 
163  const int tuple_limit = 1000000;
164 
165  size_t total_tuples;
166 
167  void *SPIplan;
168  SPIplan = pgr_SPI_prepare(vehicles_sql);
169  Portal SPIportal;
170  SPIportal = pgr_SPI_cursor_open(SPIplan);
171 
172  bool moredata = true;
173  (*total_vehicles) = total_tuples = 0;
174 
175  /* on the first tuple get the column numbers */
176 
177  while (moredata == true) {
178  SPI_cursor_fetch(SPIportal, true, tuple_limit);
179  if (total_tuples == 0) {
180  /* Atleast one out of start_id or end_id must be present */
181  info[1].colNumber = SPI_fnumber(SPI_tuptable->tupdesc, "start_id");
182  info[2].colNumber = SPI_fnumber(SPI_tuptable->tupdesc, "end_id");
183  if (!column_found(info[1].colNumber) && !column_found(info[2].colNumber)) {
184  elog(ERROR, "At least one out of start_id or end_id must be present");
185  }
186  pgr_fetch_column_info(info, column_count);
187  }
188  size_t ntuples = SPI_processed;
189  total_tuples += ntuples;
190  if (ntuples > 0) {
191  if ((*vehicles) == NULL)
192  (*vehicles) = (Vroom_vehicle_t *)palloc0(
193  total_tuples * sizeof(Vroom_vehicle_t));
194  else
195  (*vehicles) = (Vroom_vehicle_t *)repalloc(
196  (*vehicles),
197  total_tuples * sizeof(Vroom_vehicle_t));
198 
199  if ((*vehicles) == NULL) {
200  elog(ERROR, "Out of memory");
201  }
202 
203  size_t t;
204  SPITupleTable *tuptable = SPI_tuptable;
205  TupleDesc tupdesc = SPI_tuptable->tupdesc;
206  for (t = 0; t < ntuples; t++) {
207  HeapTuple tuple = tuptable->vals[t];
208  fetch_vehicles(&tuple, &tupdesc, info,
209  &(*vehicles)[total_tuples - ntuples + t], is_plain);
210  }
211  SPI_freetuptable(tuptable);
212  } else {
213  moredata = false;
214  }
215  }
216 
217  SPI_cursor_close(SPIportal);
218 
219  if (total_tuples == 0) {
220  (*total_vehicles) = 0;
221  return;
222  }
223 
224  (*total_vehicles) = total_tuples;
225 #ifdef PROFILE
226  time_msg("reading vehicles", start_t, clock());
227 #endif
228 }
229 
230 
236 void
238  char *sql,
239  Vroom_vehicle_t **rows,
240  size_t *total_rows,
241  bool is_plain) {
242  int kColumnCount = 10;
243  Column_info_t info[kColumnCount];
244 
245  for (int i = 0; i < kColumnCount; ++i) {
246  info[i].colNumber = -1;
247  info[i].type = 0;
248  info[i].strict = false;
249  info[i].eType = ANY_INTEGER;
250  }
251 
252  info[0].name = "id";
253  info[1].name = "start_id";
254  info[2].name = "end_id";
255  info[3].name = "capacity";
256  info[4].name = "skills";
257  info[5].name = "tw_open";
258  info[6].name = "tw_close";
259  info[7].name = "speed_factor";
260  info[8].name = "max_tasks";
261  info[9].name = "data";
262 
263  info[3].eType = ANY_INTEGER_ARRAY; // capacity
264  info[4].eType = INTEGER_ARRAY; // skills
265  info[5].eType = INTEGER; // tw_open
266  info[6].eType = INTEGER; // tw_close
267  info[7].eType = ANY_NUMERICAL; // speed_factor
268  info[8].eType = INTEGER; // max_tasks
269  info[9].eType = JSONB; // data
270 
271  if (!is_plain) {
272  info[5].eType = TIMESTAMP; // tw_open
273  info[6].eType = TIMESTAMP; // tw_close
274  }
275 
280  info[0].strict = true;
281 
282  db_get_vehicles(sql, rows, total_rows, info, kColumnCount, is_plain);
283 }
Column_info_t::colNumber
int colNumber
Definition: column_info_t.h:54
get_vroom_vehicles
void get_vroom_vehicles(char *sql, Vroom_vehicle_t **rows, size_t *total_rows, bool is_plain)
Reads the VROOM vehicles.
Definition: vroom/vehicles_input.c:237
Vroom_vehicle_t::end_id
MatrixIndex end_id
Start location index in matrix.
Definition: vroom_vehicle_t.h:57
Vroom_vehicle_t::tw_open
Duration tw_open
Number of vehicle's skills.
Definition: vroom_vehicle_t.h:65
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
spi_getText
char * spi_getText(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
under development
Definition: get_check_data.c:832
get_MatrixIndex
MatrixIndex get_MatrixIndex(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, MatrixIndex opt_value)
@params [in] tuple @params [in] tupdesc @params [in] info about the column been fetched @params [in] ...
Definition: get_check_data.c:658
Vroom_vehicle_t::capacity_size
size_t capacity_size
Vehicle's capacity array.
Definition: vroom_vehicle_t.h:60
Vroom_vehicle_t::speed_factor
double speed_factor
Time window end time.
Definition: vroom_vehicle_t.h:68
Vroom_vehicle_t::skills
Skill * skills
Vehicle's capacity array size.
Definition: vroom_vehicle_t.h:62
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
Vroom_vehicle_t
struct Vroom_vehicle_t Vroom_vehicle_t
Definition: typedefs.h:95
vehicles_input.h
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
Vroom_vehicle_t::max_tasks
int32_t max_tasks
Vehicle travel time multiplier.
Definition: vroom_vehicle_t.h:70
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
fetch_vehicles
static void fetch_vehicles(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t *info, Vroom_vehicle_t *vehicle, bool is_plain)
Definition: vroom/vehicles_input.c:91
JSONB
@ JSONB
Definition: column_info_t.h:43
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
ANY_INTEGER_ARRAY
@ ANY_INTEGER_ARRAY
Definition: column_info_t.h:46
INTEGER_ARRAY
@ INTEGER_ARRAY
Definition: column_info_t.h:45
Column_info_t::eType
expectType eType
Definition: column_info_t.h:58
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
spi_getMaxTasks
int32_t spi_getMaxTasks(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
gets the vehicle max tasks value
Definition: get_check_data.c:320
db_get_vehicles
static void db_get_vehicles(char *vehicles_sql, Vroom_vehicle_t **vehicles, size_t *total_vehicles, Column_info_t *info, const int column_count, bool is_plain)
Definition: vroom/vehicles_input.c:150
Vroom_vehicle_t::data
char * data
Max number of tasks in a route for the vehicle.
Definition: vroom_vehicle_t.h:72
Vroom_vehicle_t::id
Idx id
Definition: vroom_vehicle_t.h:55
spi_getPositiveBigIntArr_allowEmpty
int64_t * spi_getPositiveBigIntArr_allowEmpty(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, size_t *the_size)
Function returns the values of specified columns in array.
Definition: get_check_data.c:377
spi_getPositiveIntArr_allowEmpty
uint32_t * spi_getPositiveIntArr_allowEmpty(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, size_t *the_size)
Function returns the values of specified columns in array.
Definition: get_check_data.c:393
Vroom_vehicle_t::tw_close
Duration tw_close
Time window start time.
Definition: vroom_vehicle_t.h:66
Vroom_vehicle_t::skills_size
size_t skills_size
Vehicle's skills.
Definition: vroom_vehicle_t.h:63
Vroom_vehicle_t
Vehicles's attributes.
Definition: vroom_vehicle_t.h:54
ANY_NUMERICAL
@ ANY_NUMERICAL
Definition: column_info_t.h:41
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_found
bool column_found(int colNumber)
Check whether the colNumber represent any specific column or NULL (SPI_ERROR_NOATTRIBUTE).
Definition: get_check_data.c:900
Vroom_vehicle_t::start_id
MatrixIndex start_id
The vehicle's identifier.
Definition: vroom_vehicle_t.h:56
Vroom_vehicle_t::capacity
Amount * capacity
End location index in matrix.
Definition: vroom_vehicle_t.h:59
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
INTEGER
@ INTEGER
Definition: column_info_t.h:39
spi_getFloat8
double spi_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
gets value of specified column in double type.
Definition: get_check_data.c:782