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/waysx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 461 - (hide annotations) (download) (as text)
Sat Jul 24 16:51:41 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 12979 byte(s)
Some tidying up of the writing of the file headers.

1 amb 110 /***************************************
2 amb 461 $Header: /home/amb/CVS/routino/src/waysx.c,v 1.44 2010-07-24 16:51:41 amb Exp $
3 amb 110
4     Extended Way data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 326 This file Copyright 2008-2010 Andrew M. Bishop
9 amb 110
10 amb 151 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 amb 110 ***************************************/
23    
24    
25     #include <assert.h>
26     #include <stdlib.h>
27 amb 449 #include <stdio.h>
28 amb 110 #include <string.h>
29 amb 326 #include <sys/stat.h>
30 amb 110
31 amb 228 #include "ways.h"
32 amb 110
33 amb 449 #include "waysx.h"
34 amb 110
35 amb 449 #include "files.h"
36     #include "functions.h"
37    
38    
39 amb 262 /* Variables */
40 amb 110
41 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
42 amb 284 extern char *option_tmpdirname;
43 amb 110
44 amb 284 /*+ A temporary file-local variable for use by the sort functions. +*/
45     static WaysX *sortwaysx;
46    
47 amb 110 /* Functions */
48    
49 amb 310 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
50     static int deduplicate_by_id(WayX *wayx,index_t index);
51    
52 amb 272 static int sort_by_id(WayX *a,WayX *b);
53     static int index_by_id(WayX *wayx,index_t index);
54    
55 amb 110
56     /*++++++++++++++++++++++++++++++++++++++
57 amb 326 Allocate a new way list (create a new file or open an existing one).
58 amb 110
59     WaysX *NewWayList Returns the way list.
60 amb 326
61     int append Set to 1 if the file is to be opened for appending (now or later).
62 amb 110 ++++++++++++++++++++++++++++++++++++++*/
63    
64 amb 326 WaysX *NewWayList(int append)
65 amb 110 {
66     WaysX *waysx;
67    
68 amb 213 waysx=(WaysX*)calloc(1,sizeof(WaysX));
69 amb 110
70 amb 243 assert(waysx); /* Check calloc() worked */
71    
72 amb 284 waysx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
73 amb 216
74 amb 326 if(append)
75 amb 447 sprintf(waysx->filename,"%s/waysx.input.tmp",option_tmpdirname);
76 amb 326 else
77 amb 447 sprintf(waysx->filename,"%s/waysx.%p.tmp",option_tmpdirname,waysx);
78 amb 262
79 amb 326 if(append)
80     {
81 amb 331 off_t size,position=0;
82 amb 326
83     waysx->fd=AppendFile(waysx->filename);
84    
85 amb 331 size=SizeFile(waysx->filename);
86 amb 326
87 amb 331 while(position<size)
88 amb 326 {
89 amb 331 FILESORT_VARINT waysize;
90 amb 326
91     SeekFile(waysx->fd,position);
92 amb 331 ReadFile(waysx->fd,&waysize,FILESORT_VARSIZE);
93 amb 326
94     waysx->xnumber++;
95 amb 331 position+=waysize+FILESORT_VARSIZE;
96 amb 326 }
97    
98 amb 331 SeekFile(waysx->fd,size);
99 amb 326 }
100     else
101     waysx->fd=OpenFile(waysx->filename);
102    
103 amb 284 waysx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32);
104     sprintf(waysx->nfilename,"%s/waynames.%p.tmp",option_tmpdirname,waysx);
105 amb 262
106 amb 110 return(waysx);
107     }
108    
109    
110     /*++++++++++++++++++++++++++++++++++++++
111 amb 226 Free a way list.
112    
113     WaysX *waysx The list to be freed.
114 amb 326
115     int keep Set to 1 if the file is to be kept.
116 amb 226 ++++++++++++++++++++++++++++++++++++++*/
117    
118 amb 326 void FreeWayList(WaysX *waysx,int keep)
119 amb 226 {
120 amb 326 if(!keep)
121     DeleteFile(waysx->filename);
122    
123 amb 283 free(waysx->filename);
124 amb 262
125 amb 226 if(waysx->idata)
126     free(waysx->idata);
127    
128 amb 262 DeleteFile(waysx->nfilename);
129 amb 326
130 amb 283 free(waysx->nfilename);
131 amb 226
132     free(waysx);
133     }
134    
135    
136     /*++++++++++++++++++++++++++++++++++++++
137 amb 262 Append a way to a way list.
138 amb 203
139 amb 262 void AppendWay Returns the newly appended way.
140 amb 243
141 amb 262 WaysX* waysx The set of ways to process.
142 amb 110
143 amb 262 way_t id The ID of the way.
144 amb 110
145 amb 262 Way *way The way data itself.
146 amb 110
147 amb 262 const char *name The name or reference of the way.
148     ++++++++++++++++++++++++++++++++++++++*/
149 amb 110
150 amb 262 void AppendWay(WaysX* waysx,way_t id,Way *way,const char *name)
151     {
152     WayX wayx;
153 amb 311 FILESORT_VARINT size;
154 amb 110
155 amb 262 assert(!waysx->idata); /* Must not have idata filled in => unsorted */
156    
157     wayx.id=id;
158 amb 310 wayx.prop=0;
159 amb 262 wayx.way=*way;
160    
161 amb 310 size=sizeof(WayX)+strlen(name)+1;
162    
163 amb 311 WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
164 amb 262 WriteFile(waysx->fd,&wayx,sizeof(WayX));
165 amb 310 WriteFile(waysx->fd,name,strlen(name)+1);
166 amb 262
167     waysx->xnumber++;
168 amb 110 }
169    
170    
171     /*++++++++++++++++++++++++++++++++++++++
172 amb 224 Sort the list of ways.
173 amb 110
174     WaysX* waysx The set of ways to process.
175     ++++++++++++++++++++++++++++++++++++++*/
176    
177     void SortWayList(WaysX* waysx)
178     {
179 amb 310 index_t i;
180     int fd,nfd;
181     char *names[2]={NULL,NULL};
182     int namelen[2]={0,0};
183     int nnames=0,nprops=0;
184     uint32_t lastlength=0;
185     Way lastway;
186 amb 110
187 amb 266 /* Check the start conditions */
188    
189 amb 243 assert(!waysx->idata); /* Must not have idata filled in => unsorted */
190 amb 110
191 amb 266 /* Print the start message */
192    
193 amb 227 printf("Sorting Ways");
194     fflush(stdout);
195 amb 110
196 amb 310 /* Close the file and re-open it (finished appending) */
197 amb 203
198 amb 262 CloseFile(waysx->fd);
199     waysx->fd=ReOpenFile(waysx->filename);
200 amb 216
201 amb 310 DeleteFile(waysx->filename);
202 amb 262
203 amb 310 fd=OpenFile(waysx->filename);
204    
205     /* Sort the ways to allow compacting them and remove duplicates */
206    
207     sortwaysx=waysx;
208    
209 amb 311 filesort_vary(waysx->fd,fd,(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,(int (*)(void*,index_t))deduplicate_by_id);
210 amb 310
211     /* Close the files */
212    
213     CloseFile(waysx->fd);
214     CloseFile(fd);
215    
216     /* Print the final message */
217    
218     printf("\rSorted Ways: Ways=%d Duplicates=%d\n",waysx->xnumber,waysx->xnumber-waysx->number);
219     fflush(stdout);
220    
221    
222     /* Print the start message */
223    
224     printf("Compacting Ways: Ways=0 Names=0 Properties=0");
225     fflush(stdout);
226    
227     /* Open the files */
228    
229     waysx->fd=ReOpenFile(waysx->filename);
230    
231 amb 272 DeleteFile(waysx->filename);
232 amb 262
233 amb 272 fd=OpenFile(waysx->filename);
234 amb 310 nfd=OpenFile(waysx->nfilename);
235 amb 272
236 amb 310 /* Copy from the single file into two files and index as we go. */
237    
238     for(i=0;i<waysx->number;i++)
239     {
240     WayX wayx;
241 amb 311 FILESORT_VARINT size;
242 amb 310
243 amb 311 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
244 amb 310
245     if(namelen[nnames%2]<size)
246     names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
247    
248     ReadFile(waysx->fd,&wayx,sizeof(WayX));
249     ReadFile(waysx->fd,names[nnames%2],size-sizeof(WayX));
250    
251     if(nnames==0 || strcmp(names[0],names[1]))
252     {
253     WriteFile(nfd,names[nnames%2],size-sizeof(WayX));
254    
255     lastlength=waysx->nlength;
256     waysx->nlength+=size-sizeof(WayX);
257    
258     nnames++;
259     }
260    
261     wayx.way.name=lastlength;
262    
263     if(nprops==0 || wayx.way.name!=lastway.name || WaysCompare(&lastway,&wayx.way))
264     {
265     lastway=wayx.way;
266    
267     waysx->cnumber++;
268    
269     nprops++;
270     }
271    
272     wayx.prop=nprops-1;
273    
274     WriteFile(fd,&wayx,sizeof(WayX));
275    
276     if(!((i+1)%10000))
277     {
278     printf("\rCompacting Ways: Ways=%d Names=%d Properties=%d",i+1,nnames,nprops);
279     fflush(stdout);
280     }
281     }
282    
283     if(names[0]) free(names[0]);
284     if(names[1]) free(names[1]);
285    
286     /* Close the files */
287    
288     CloseFile(waysx->fd);
289     CloseFile(fd);
290    
291     waysx->fd=ReOpenFile(waysx->filename);
292    
293     CloseFile(nfd);
294    
295     /* Print the final message */
296    
297     printf("\rCompacted Ways: Ways=%d Names=%d Properties=%d \n",waysx->number,nnames,nprops);
298     fflush(stdout);
299    
300    
301     /* Print the start message */
302    
303     printf("Sorting Ways");
304     fflush(stdout);
305    
306     /* Open the files */
307    
308     waysx->fd=ReOpenFile(waysx->filename);
309    
310     DeleteFile(waysx->filename);
311    
312     fd=OpenFile(waysx->filename);
313    
314 amb 272 /* Allocate the array of indexes */
315    
316 amb 310 waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
317 amb 262
318 amb 243 assert(waysx->idata); /* Check malloc() worked */
319    
320 amb 310 /* Sort the ways by index and index them */
321 amb 203
322 amb 272 sortwaysx=waysx;
323 amb 215
324 amb 311 filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))index_by_id);
325 amb 215
326 amb 262 /* Close the files and re-open them */
327    
328     CloseFile(waysx->fd);
329     CloseFile(fd);
330    
331     waysx->fd=ReOpenFile(waysx->filename);
332    
333 amb 266 /* Print the final message */
334    
335 amb 310 printf("\rSorted Ways: Ways=%d\n",waysx->number);
336 amb 227 fflush(stdout);
337 amb 224 }
338    
339    
340     /*++++++++++++++++++++++++++++++++++++++
341 amb 262 Sort the ways into id order.
342 amb 224
343 amb 262 int sort_by_id Returns the comparison of the id fields.
344    
345 amb 272 WayX *a The first extended way.
346 amb 262
347 amb 272 WayX *b The second extended way.
348 amb 262 ++++++++++++++++++++++++++++++++++++++*/
349    
350 amb 272 static int sort_by_id(WayX *a,WayX *b)
351 amb 262 {
352 amb 272 way_t a_id=a->id;
353     way_t b_id=b->id;
354 amb 262
355     if(a_id<b_id)
356     return(-1);
357     else if(a_id>b_id)
358     return(1);
359     else
360     return(0);
361     }
362    
363    
364     /*++++++++++++++++++++++++++++++++++++++
365 amb 310 Sort the ways into name, properties and id order.
366 amb 272
367 amb 310 int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
368 amb 272
369 amb 310 WayX *a The first extended Way.
370    
371     WayX *b The second extended Way.
372     ++++++++++++++++++++++++++++++++++++++*/
373    
374     static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
375     {
376     int compare;
377     char *a_name=(char*)a+sizeof(WayX);
378     char *b_name=(char*)b+sizeof(WayX);
379    
380     compare=strcmp(a_name,b_name);
381    
382     if(compare)
383     return(compare);
384    
385     compare=WaysCompare(&a->way,&b->way);
386    
387     if(compare)
388     return(compare);
389    
390     return(sort_by_id(a,b));
391     }
392    
393    
394     /*++++++++++++++++++++++++++++++++++++++
395     Deduplicate the extended ways using the id after sorting.
396    
397     int deduplicate_by_id Return 1 if the value is to be kept, otherwise zero.
398    
399 amb 272 WayX *wayx The extended way.
400    
401     index_t index The index of this way in the total.
402     ++++++++++++++++++++++++++++++++++++++*/
403    
404 amb 310 static int deduplicate_by_id(WayX *wayx,index_t index)
405 amb 272 {
406 amb 310 static way_t previd;
407    
408     if(index==0 || wayx->id!=previd)
409 amb 272 {
410 amb 310 previd=wayx->id;
411 amb 272
412     sortwaysx->number++;
413    
414     return(1);
415     }
416    
417     return(0);
418     }
419    
420    
421     /*++++++++++++++++++++++++++++++++++++++
422 amb 310 Index the ways after sorting.
423    
424     int index_by_id Return 1 if the value is to be kept, otherwise zero.
425    
426     WayX *wayx The extended way.
427    
428     index_t index The index of this way in the total.
429     ++++++++++++++++++++++++++++++++++++++*/
430    
431     static int index_by_id(WayX *wayx,index_t index)
432     {
433     sortwaysx->idata[index]=wayx->id;
434    
435     return(1);
436     }
437    
438    
439     /*++++++++++++++++++++++++++++++++++++++
440 amb 285 Find a particular way index.
441    
442     index_t IndexWayX Returns the index of the extended way with the specified id.
443    
444     WaysX* waysx The set of ways to process.
445    
446     way_t id The way id to look for.
447     ++++++++++++++++++++++++++++++++++++++*/
448    
449     index_t IndexWayX(WaysX* waysx,way_t id)
450     {
451     int start=0;
452     int end=waysx->number-1;
453     int mid;
454    
455     assert(waysx->idata); /* Must have idata filled in => sorted */
456    
457     /* Binary search - search key exact match only is required.
458     *
459     * # <- start | Check mid and move start or end if it doesn't match
460     * # |
461     * # | Since an exact match is wanted we can set end=mid-1
462     * # <- mid | or start=mid+1 because we know that mid doesn't match.
463     * # |
464     * # | Eventually either end=start or end=start+1 and one of
465     * # <- end | start or end is the wanted one.
466     */
467    
468     if(end<start) /* There are no ways */
469     return(NO_WAY);
470     else if(id<waysx->idata[start]) /* Check key is not before start */
471     return(NO_WAY);
472     else if(id>waysx->idata[end]) /* Check key is not after end */
473     return(NO_WAY);
474     else
475     {
476     do
477     {
478     mid=(start+end)/2; /* Choose mid point */
479    
480     if(waysx->idata[mid]<id) /* Mid point is too low */
481     start=mid+1;
482     else if(waysx->idata[mid]>id) /* Mid point is too high */
483     end=mid-1;
484     else /* Mid point is correct */
485     return(mid);
486     }
487     while((end-start)>1);
488    
489     if(waysx->idata[start]==id) /* Start is correct */
490     return(start);
491    
492     if(waysx->idata[end]==id) /* End is correct */
493     return(end);
494     }
495    
496     return(NO_WAY);
497     }
498    
499    
500     /*++++++++++++++++++++++++++++++++++++++
501     Save the way list to a file.
502    
503     WaysX* waysx The set of ways to save.
504    
505     const char *filename The name of the file to save.
506     ++++++++++++++++++++++++++++++++++++++*/
507    
508 amb 398 void SaveWayList(WaysX* waysx,const char *filename)
509 amb 285 {
510     index_t i;
511 amb 310 int fd,nfd;
512     int position=0;
513 amb 461 WaysFile waysfile;
514     wayallow_t allow=0;
515     wayprop_t props=0;
516 amb 285
517 amb 461 /* Print the start message */
518    
519 amb 285 printf("Writing Ways: Ways=0");
520     fflush(stdout);
521    
522 amb 461 /* Map into memory */
523    
524 amb 452 #if !SLIM
525     waysx->xdata=MapFile(waysx->filename);
526     #endif
527 amb 285
528 amb 461 /* Write out the ways data */
529 amb 285
530 amb 461 fd=OpenFile(filename);
531 amb 285
532 amb 461 SeekFile(fd,sizeof(WaysFile));
533 amb 285
534     for(i=0;i<waysx->number;i++)
535     {
536 amb 309 WayX *wayx=LookupWayX(waysx,i,1);
537 amb 285
538 amb 461 allow|=wayx->way.allow;
539     props|=wayx->way.props;
540 amb 398
541 amb 460 SeekFile(fd,sizeof(WaysFile)+wayx->prop*sizeof(Way));
542 amb 309 WriteFile(fd,&wayx->way,sizeof(Way));
543    
544 amb 285 if(!((i+1)%10000))
545     {
546     printf("\rWriting Ways: Ways=%d",i+1);
547     fflush(stdout);
548     }
549     }
550    
551 amb 461 /* Unmap from memory */
552 amb 398
553 amb 452 #if !SLIM
554     waysx->xdata=UnmapFile(waysx->filename);
555     #endif
556 amb 285
557 amb 461 /* Write out the ways names */
558 amb 285
559 amb 461 SeekFile(fd,sizeof(WaysFile)+waysx->cnumber*sizeof(Way));
560    
561 amb 310 nfd=ReOpenFile(waysx->nfilename);
562 amb 285
563 amb 309 while(position<waysx->nlength)
564     {
565     int len=1024;
566     char temp[1024];
567    
568     if((waysx->nlength-position)<1024)
569     len=waysx->nlength-position;
570    
571 amb 310 ReadFile(nfd,temp,len);
572 amb 309 WriteFile(fd,temp,len);
573    
574     position+=len;
575     }
576    
577 amb 310 CloseFile(nfd);
578 amb 309
579 amb 461 /* Write out the header structure */
580    
581     waysfile.number=waysx->cnumber;
582     waysfile.onumber=waysx->number;
583    
584     waysfile.allow=allow;
585     waysfile.props=props;
586    
587     SeekFile(fd,0);
588     WriteFile(fd,&waysfile,sizeof(WaysFile));
589    
590 amb 285 CloseFile(fd);
591    
592 amb 461 /* Print the final message */
593    
594 amb 285 printf("\rWrote Ways: Ways=%d \n",waysx->number);
595     fflush(stdout);
596     }

Properties

Name Value
cvs:description Extended ways functions.