Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/relationsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 496 - (show annotations) (download) (as text)
Fri Sep 17 17:42:45 2010 UTC (14 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 8395 byte(s)
Initial revision

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/relationsx.c,v 1.1 2010-09-17 17:42:45 amb Exp $
3
4 Extended Relation data type functions.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2010 Andrew M. Bishop
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
23
24
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <sys/stat.h>
30
31 #include "waysx.h"
32 #include "relationsx.h"
33
34 #include "files.h"
35 #include "functions.h"
36
37
38 /* Variables */
39
40 /*+ The command line '--tmpdir' option or its default value. +*/
41 extern char *option_tmpdirname;
42
43 /*+ A temporary file-local variable for use by the sort functions. +*/
44 static RelationsX *sortrelationsx;
45
46 /* Functions */
47
48 static int sort_by_id(RouteRelX *a,RouteRelX *b);
49 static int deduplicate_by_id(RouteRelX *relationx,index_t index);
50
51
52 /*++++++++++++++++++++++++++++++++++++++
53 Allocate a new relation list (create a new file or open an existing one).
54
55 RelationsX *NewRelationList Returns the relation list.
56
57 int append Set to 1 if the file is to be opened for appending (now or later).
58 ++++++++++++++++++++++++++++++++++++++*/
59
60 RelationsX *NewRelationList(int append)
61 {
62 RelationsX *relationsx;
63
64 relationsx=(RelationsX*)calloc(1,sizeof(RelationsX));
65
66 assert(relationsx); /* Check calloc() worked */
67
68 relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32);
69
70 if(append)
71 sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname);
72 else
73 sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx);
74
75 if(append)
76 {
77 off_t size,position=0;
78
79 relationsx->rfd=AppendFile(relationsx->rfilename);
80
81 size=SizeFile(relationsx->rfilename);
82
83 while(position<size)
84 {
85 FILESORT_VARINT relationsize;
86
87 SeekFile(relationsx->rfd,position);
88 ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE);
89
90 relationsx->rxnumber++;
91 position+=relationsize+FILESORT_VARSIZE;
92 }
93
94 SeekFile(relationsx->rfd,size);
95 }
96 else
97 relationsx->rfd=OpenFile(relationsx->rfilename);
98
99 return(relationsx);
100 }
101
102
103 /*++++++++++++++++++++++++++++++++++++++
104 Free a relation list.
105
106 RelationsX *relationsx The list to be freed.
107
108 int keep Set to 1 if the file is to be kept.
109 ++++++++++++++++++++++++++++++++++++++*/
110
111 void FreeRelationList(RelationsX *relationsx,int keep)
112 {
113 if(!keep)
114 DeleteFile(relationsx->rfilename);
115
116 free(relationsx->rfilename);
117
118 free(relationsx);
119 }
120
121
122 /*++++++++++++++++++++++++++++++++++++++
123 Append a single relation to an unsorted route relation list.
124
125 RelationsX* relationsx The set of relations to process.
126
127 relation_t id The ID of the relation.
128
129 allow_t routes The types of routes that this relation is for.
130
131 way_t *ways The array of ways that are members of the relation.
132
133 int nways The number of ways that are members of the relation.
134
135 relation_t *relations The array of relations that are members of the relation.
136
137 int nrelations The number of relations that are members of the relation.
138 ++++++++++++++++++++++++++++++++++++++*/
139
140 void AppendRouteRelation(RelationsX* relationsx,relation_t id,allow_t routes,
141 way_t *ways,int nways,
142 relation_t *relations,int nrelations)
143 {
144 RouteRelX relationx;
145 FILESORT_VARINT size,padsize;
146 way_t zeroway=0;
147 relation_t zerorelation=0;
148 void *zeropointer=NULL;
149
150 relationx.id=id;
151 relationx.routes=routes;
152
153 size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t);
154 padsize=sizeof(RouteRelX*)*((size+sizeof(RouteRelX*)-1)/sizeof(RouteRelX*));
155
156 WriteFile(relationsx->rfd,&padsize,FILESORT_VARSIZE);
157 WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
158
159 WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t));
160 WriteFile(relationsx->rfd,&zeroway, sizeof(way_t));
161
162 WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t));
163 WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t));
164
165 WriteFile(relationsx->rfd,&zeropointer,padsize-size);
166
167 relationsx->rxnumber++;
168
169 assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */
170 }
171
172
173 /*++++++++++++++++++++++++++++++++++++++
174 Sort the list of relations.
175
176 RelationsX* relationsx The set of relations to process.
177 ++++++++++++++++++++++++++++++++++++++*/
178
179 void SortRelationList(RelationsX* relationsx)
180 {
181 int rfd;
182
183 /* Print the start message */
184
185 printf("Sorting Relations");
186 fflush(stdout);
187
188 /* Close the file and re-open it (finished appending) */
189
190 CloseFile(relationsx->rfd);
191 relationsx->rfd=ReOpenFile(relationsx->rfilename);
192
193 DeleteFile(relationsx->rfilename);
194
195 rfd=OpenFile(relationsx->rfilename);
196
197 /* Sort the relations to allow removing duplicates */
198
199 sortrelationsx=relationsx;
200
201 filesort_vary(relationsx->rfd,rfd,(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))deduplicate_by_id);
202
203 /* Close the files */
204
205 CloseFile(relationsx->rfd);
206 CloseFile(rfd);
207
208 /* Print the final message */
209
210 printf("\rSorted Relations: Relations=%d Duplicates=%d\n",relationsx->rxnumber,relationsx->rxnumber-relationsx->rnumber);
211 fflush(stdout);
212 }
213
214
215 /*++++++++++++++++++++++++++++++++++++++
216 Sort the relations into id order.
217
218 int sort_by_id Returns the comparison of the id fields.
219
220 RouteRelX *a The first extended relation.
221
222 RouteRelX *b The second extended relation.
223 ++++++++++++++++++++++++++++++++++++++*/
224
225 static int sort_by_id(RouteRelX *a,RouteRelX *b)
226 {
227 relation_t a_id=a->id;
228 relation_t b_id=b->id;
229
230 if(a_id<b_id)
231 return(-1);
232 else if(a_id>b_id)
233 return(1);
234 else
235 return(0);
236 }
237
238
239 /*++++++++++++++++++++++++++++++++++++++
240 Deduplicate the extended relations using the id after sorting.
241
242 int deduplicate_by_id Return 1 if the value is to be kept, otherwise zero.
243
244 RouteRelX *relationx The extended relation.
245
246 index_t index The index of this relation in the total.
247 ++++++++++++++++++++++++++++++++++++++*/
248
249 static int deduplicate_by_id(RouteRelX *relationx,index_t index)
250 {
251 static relation_t previd;
252
253 if(index==0 || relationx->id!=previd)
254 {
255 previd=relationx->id;
256
257 sortrelationsx->rnumber++;
258
259 return(1);
260 }
261
262 return(0);
263 }
264
265
266 /*++++++++++++++++++++++++++++++++++++++
267 Process the route relations and apply the information to the ways.
268
269 RelationsX *relationsx The set of relations to process.
270
271 WaysX *waysx The set of ways to update.
272 ++++++++++++++++++++++++++++++++++++++*/
273
274 void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx)
275 {
276 int i;
277
278 /* Print the start message */
279
280 printf("Processing Route Relations: Relations=0");
281 fflush(stdout);
282
283 /* Open the file and read through it */
284
285 relationsx->rfd=ReOpenFile(relationsx->rfilename);
286
287 for(i=0;i<relationsx->rnumber;i++)
288 {
289 FILESORT_VARINT padsize,size;
290 RouteRelX relationx;
291 way_t way;
292 relation_t relation;
293 void *pointer;
294
295 ReadFile(relationsx->rfd,&padsize,FILESORT_VARSIZE);
296 ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
297
298 size=FILESORT_VARSIZE+sizeof(RouteRelX);
299
300 do
301 {
302 ReadFile(relationsx->rfd,&way,sizeof(way_t));
303
304 // if(way)
305 // printf("Relation %d includes way %d\n",relationx.id,way);
306
307 size+=sizeof(way_t);
308 }
309 while(way);
310
311 do
312 {
313 ReadFile(relationsx->rfd,&relation,sizeof(relation_t));
314
315 // if(relation)
316 // printf("Relation %d includes relation %d\n",relationx.id,relation);
317
318 size+=sizeof(relation_t);
319 }
320 while(relation);
321
322 ReadFile(relationsx->rfd,&pointer,padsize-size);
323 }
324
325 CloseFile(relationsx->rfd);
326
327 /* Print the final message */
328
329 printf("\rProcessed Route Relations: Relations=%d \n",relationsx->rnumber);
330 fflush(stdout);
331 }