Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/relationsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 496 - (hide 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 amb 496 /***************************************
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     }