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
restrictions_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: restrictions_input.c
3 
4 Copyright (c) 2015 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 
25 
26 #include <postgres.h>
27 #include "executor/spi.h"
28 
29 #include "./debug_macro.h"
30 #include "./pgr_types.h"
31 #include "./time_msg.h"
32 #include "./postgres_connection.h"
33 #include "./get_check_data.h"
34 #include "./restrictions_input.h"
35 
36 
37 static
39  HeapTuple *tuple,
40  TupleDesc *tupdesc,
41  Column_info_t info[4],
42  Restrict_t *restriction) {
43  restriction->target_id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
44  restriction->to_cost = pgr_SPI_getFloat8(tuple, tupdesc, info[1]);
45  char *str = DatumGetCString(
46  SPI_getvalue(*tuple, *tupdesc, info[2].colNumber));
47 
48 // TODO(someone) because its text, no guarantee the text read is correct
49 // move this code to c++ to tokenize the integers.
50 
51  int i = 0;
52  for (i = 0; i < MAX_RULE_LENGTH; ++i) restriction->via[i] = -1;
53 
54  if (str != NULL) {
55  char *token = NULL;
56  int i = 0;
57 
58  token = (char *)strtok(str, " ,");
59 
60  while (token != NULL && i < MAX_RULE_LENGTH) {
61  restriction->via[i] = atoi(token);
62  i++;
63  token = (char *)strtok(NULL, " ,");
64  }
65  }
66 }
67 
68 
69 void
71  char *restrictions_sql,
72  Restrict_t **restrictions,
73  size_t *total_restrictions) {
74  const int tuple_limit = 1000000;
75  clock_t start_t = clock();
76 
77  PGR_DBG("pgr_get_restriction_data");
78  PGR_DBG("%s", restrictions_sql);
79 
80  Column_info_t info[3];
81 
82  int i;
83  for (i = 0; i < 3; ++i) {
84  info[i].colNumber = -1;
85  info[i].type = 0;
86  info[i].strict = true;
87  info[i].eType = ANY_INTEGER;
88  }
89  info[0].name = strdup("target_id");
90  info[1].name = strdup("to_cost");
91  info[2].name = strdup("via_path");
92 
93  info[1].eType = ANY_NUMERICAL;
94  info[2].eType = TEXT;
95 
96 
97  size_t ntuples;
98  size_t total_tuples;
99 
100  void *SPIplan;
101  SPIplan = pgr_SPI_prepare(restrictions_sql);
102  Portal SPIportal;
103  SPIportal = pgr_SPI_cursor_open(SPIplan);
104 
105  bool moredata = TRUE;
106  (*total_restrictions) = total_tuples = 0;
107 
108  /* on the first tuple get the column numbers */
109 
110  while (moredata == TRUE) {
111  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
112  if (total_tuples == 0) {
113  pgr_fetch_column_info(info, 3);
114  }
115  ntuples = SPI_processed;
116  total_tuples += ntuples;
117  PGR_DBG("SPI_processed %ld", ntuples);
118  if (ntuples > 0) {
119  if ((*restrictions) == NULL)
120  (*restrictions) = (Restrict_t *)palloc0(
121  total_tuples * sizeof(Restrict_t));
122  else
123  (*restrictions) = (Restrict_t *)repalloc(
124  (*restrictions),
125  total_tuples * sizeof(Restrict_t));
126 
127  if ((*restrictions) == NULL) {
128  elog(ERROR, "Out of memory");
129  }
130 
131  size_t t;
132  SPITupleTable *tuptable = SPI_tuptable;
133  TupleDesc tupdesc = SPI_tuptable->tupdesc;
134  PGR_DBG("processing %ld", ntuples);
135  for (t = 0; t < ntuples; t++) {
136  HeapTuple tuple = tuptable->vals[t];
137  fetch_restriction(&tuple, &tupdesc, info,
138  &(*restrictions)[total_tuples - ntuples + t]);
139  }
140  SPI_freetuptable(tuptable);
141  } else {
142  moredata = FALSE;
143  }
144  }
145 
146  if (total_tuples == 0) {
147  (*total_restrictions) = 0;
148  PGR_DBG("NO restrictions");
149  return;
150  }
151 
152  (*total_restrictions) = total_tuples;
153  PGR_DBG("Finish reading %ld data, %ld",
154  total_tuples,
155  (*total_restrictions));
156  clock_t end_t = clock();
157  time_msg(" reading Restrictions", start_t, end_t);
158 }
int64_t pgr_SPI_getBigInt(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
#define PGR_DBG(...)
Definition: debug_macro.h:33
uint64_t type
Definition: pgr_types.h:186
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:31
char * name
Definition: pgr_types.h:188
void pgr_fetch_column_info(Column_info_t info[], int info_size)
double to_cost
Definition: pgr_types.h:161
int64_t target_id
Definition: pgr_types.h:160
void pgr_get_restriction_data(char *restrictions_sql, Restrict_t **restrictions, size_t *total_restrictions)
int64_t via[5]
Definition: pgr_types.h:162
Portal pgr_SPI_cursor_open(SPIPlanPtr SPIplan)
double pgr_SPI_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
#define MAX_RULE_LENGTH
Definition: pgr_types.h:158
SPIPlanPtr pgr_SPI_prepare(char *sql)
expectType eType
Definition: pgr_types.h:189
static void fetch_restriction(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[4], Restrict_t *restriction)