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 680 - (hide annotations) (download) (as text)
Sun Apr 24 15:14:53 2011 UTC (13 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 15198 byte(s)
Update comments throughout the source code.

1 amb 110 /***************************************
2     Extended Way data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 110 ******************/ /******************
6 amb 612 This file Copyright 2008-2011 Andrew M. Bishop
7 amb 110
8 amb 151 This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU Affero General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU Affero General Public License for more details.
17    
18     You should have received a copy of the GNU Affero General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 amb 110 ***************************************/
21    
22    
23     #include <assert.h>
24     #include <stdlib.h>
25 amb 449 #include <stdio.h>
26 amb 110 #include <string.h>
27 amb 326 #include <sys/stat.h>
28 amb 110
29 amb 228 #include "ways.h"
30 amb 110
31 amb 449 #include "waysx.h"
32 amb 110
33 amb 449 #include "files.h"
34 amb 519 #include "logging.h"
35 amb 532 #include "sorting.h"
36 amb 449
37    
38 amb 680 /* Global variables */
39 amb 110
40 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
41 amb 284 extern char *option_tmpdirname;
42 amb 110
43 amb 680
44     /* Local variables */
45    
46 amb 284 /*+ A temporary file-local variable for use by the sort functions. +*/
47     static WaysX *sortwaysx;
48    
49 amb 680
50 amb 110 /* Functions */
51    
52 amb 499 static int sort_by_id(WayX *a,WayX *b);
53     static int sort_by_name_and_id(WayX *a,WayX *b);
54 amb 310 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
55    
56 amb 499 static int deduplicate_and_index_by_id(WayX *wayx,index_t index);
57 amb 272
58 amb 110
59     /*++++++++++++++++++++++++++++++++++++++
60 amb 326 Allocate a new way list (create a new file or open an existing one).
61 amb 110
62     WaysX *NewWayList Returns the way list.
63 amb 326
64     int append Set to 1 if the file is to be opened for appending (now or later).
65 amb 110 ++++++++++++++++++++++++++++++++++++++*/
66    
67 amb 326 WaysX *NewWayList(int append)
68 amb 110 {
69     WaysX *waysx;
70    
71 amb 213 waysx=(WaysX*)calloc(1,sizeof(WaysX));
72 amb 110
73 amb 243 assert(waysx); /* Check calloc() worked */
74    
75 amb 284 waysx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
76 amb 216
77 amb 326 if(append)
78 amb 447 sprintf(waysx->filename,"%s/waysx.input.tmp",option_tmpdirname);
79 amb 326 else
80 amb 447 sprintf(waysx->filename,"%s/waysx.%p.tmp",option_tmpdirname,waysx);
81 amb 262
82 amb 326 if(append)
83     {
84 amb 331 off_t size,position=0;
85 amb 326
86 amb 502 waysx->fd=OpenFileAppend(waysx->filename);
87 amb 326
88 amb 331 size=SizeFile(waysx->filename);
89 amb 326
90 amb 331 while(position<size)
91 amb 326 {
92 amb 331 FILESORT_VARINT waysize;
93 amb 326
94     SeekFile(waysx->fd,position);
95 amb 331 ReadFile(waysx->fd,&waysize,FILESORT_VARSIZE);
96 amb 326
97 amb 650 waysx->number++;
98 amb 331 position+=waysize+FILESORT_VARSIZE;
99 amb 326 }
100    
101 amb 331 SeekFile(waysx->fd,size);
102 amb 326 }
103     else
104 amb 502 waysx->fd=OpenFileNew(waysx->filename);
105 amb 326
106 amb 284 waysx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32);
107     sprintf(waysx->nfilename,"%s/waynames.%p.tmp",option_tmpdirname,waysx);
108 amb 262
109 amb 110 return(waysx);
110     }
111    
112    
113     /*++++++++++++++++++++++++++++++++++++++
114 amb 226 Free a way list.
115    
116     WaysX *waysx The list to be freed.
117 amb 326
118 amb 680 int keep Set to 1 if the file is to be kept (for appending later).
119 amb 226 ++++++++++++++++++++++++++++++++++++++*/
120    
121 amb 326 void FreeWayList(WaysX *waysx,int keep)
122 amb 226 {
123 amb 326 if(!keep)
124     DeleteFile(waysx->filename);
125    
126 amb 283 free(waysx->filename);
127 amb 262
128 amb 226 if(waysx->idata)
129     free(waysx->idata);
130    
131 amb 262 DeleteFile(waysx->nfilename);
132 amb 326
133 amb 283 free(waysx->nfilename);
134 amb 226
135     free(waysx);
136     }
137    
138    
139     /*++++++++++++++++++++++++++++++++++++++
140 amb 493 Append a single way to an unsorted way list.
141 amb 203
142 amb 262 WaysX* waysx The set of ways to process.
143 amb 110
144 amb 262 way_t id The ID of the way.
145 amb 110
146 amb 262 Way *way The way data itself.
147 amb 110
148 amb 262 const char *name The name or reference of the way.
149     ++++++++++++++++++++++++++++++++++++++*/
150 amb 110
151 amb 262 void AppendWay(WaysX* waysx,way_t id,Way *way,const char *name)
152     {
153     WayX wayx;
154 amb 311 FILESORT_VARINT size;
155 amb 110
156 amb 262 wayx.id=id;
157 amb 310 wayx.prop=0;
158 amb 262 wayx.way=*way;
159    
160 amb 310 size=sizeof(WayX)+strlen(name)+1;
161    
162 amb 311 WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
163 amb 262 WriteFile(waysx->fd,&wayx,sizeof(WayX));
164 amb 310 WriteFile(waysx->fd,name,strlen(name)+1);
165 amb 262
166 amb 650 waysx->number++;
167 amb 466
168 amb 650 assert(!(waysx->number==0)); /* Zero marks the high-water mark for ways. */
169 amb 110 }
170    
171    
172     /*++++++++++++++++++++++++++++++++++++++
173 amb 224 Sort the list of ways.
174 amb 110
175     WaysX* waysx The set of ways to process.
176     ++++++++++++++++++++++++++++++++++++++*/
177    
178     void SortWayList(WaysX* waysx)
179     {
180 amb 650 index_t i,xnumber;
181 amb 555 int fd;
182 amb 310 char *names[2]={NULL,NULL};
183     int namelen[2]={0,0};
184 amb 499 int nnames=0;
185 amb 310 uint32_t lastlength=0;
186 amb 110
187 amb 266 /* Print the start message */
188    
189 amb 519 printf_first("Sorting Ways by Name");
190 amb 110
191 amb 555 /* Close the file (finished appending) */
192 amb 203
193 amb 612 waysx->fd=CloseFile(waysx->fd);
194 amb 555
195     /* Re-open the file read-only and a new file writeable */
196    
197 amb 262 waysx->fd=ReOpenFile(waysx->filename);
198 amb 216
199 amb 310 DeleteFile(waysx->filename);
200 amb 262
201 amb 502 fd=OpenFileNew(waysx->filename);
202 amb 310
203 amb 499 /* Sort the ways to allow separating the names */
204 amb 310
205 amb 499 filesort_vary(waysx->fd,fd,(int (*)(const void*,const void*))sort_by_name_and_id,NULL);
206 amb 310
207     /* Close the files */
208    
209 amb 612 waysx->fd=CloseFile(waysx->fd);
210 amb 310 CloseFile(fd);
211    
212     /* Print the final message */
213    
214 amb 650 printf_last("Sorted Ways by Name: Ways=%d",waysx->number);
215 amb 310
216    
217     /* Print the start message */
218    
219 amb 519 printf_first("Separating Way Names: Ways=0 Names=0");
220 amb 310
221 amb 555 /* Re-open the file read-only and new files writeable */
222 amb 310
223     waysx->fd=ReOpenFile(waysx->filename);
224    
225 amb 272 DeleteFile(waysx->filename);
226 amb 262
227 amb 502 fd=OpenFileNew(waysx->filename);
228 amb 272
229 amb 555 waysx->nfd=OpenFileNew(waysx->nfilename);
230    
231 amb 499 /* Copy from the single file into two files */
232 amb 310
233 amb 650 for(i=0;i<waysx->number;i++)
234 amb 310 {
235     WayX wayx;
236 amb 311 FILESORT_VARINT size;
237 amb 310
238 amb 311 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
239 amb 310
240     if(namelen[nnames%2]<size)
241     names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
242    
243     ReadFile(waysx->fd,&wayx,sizeof(WayX));
244     ReadFile(waysx->fd,names[nnames%2],size-sizeof(WayX));
245    
246     if(nnames==0 || strcmp(names[0],names[1]))
247     {
248 amb 555 WriteFile(waysx->nfd,names[nnames%2],size-sizeof(WayX));
249 amb 310
250     lastlength=waysx->nlength;
251     waysx->nlength+=size-sizeof(WayX);
252    
253     nnames++;
254     }
255    
256     wayx.way.name=lastlength;
257    
258     WriteFile(fd,&wayx,sizeof(WayX));
259    
260     if(!((i+1)%10000))
261 amb 519 printf_middle("Separating Way Names: Ways=%d Names=%d",i+1,nnames);
262 amb 310 }
263    
264     if(names[0]) free(names[0]);
265     if(names[1]) free(names[1]);
266    
267     /* Close the files */
268    
269 amb 612 waysx->fd=CloseFile(waysx->fd);
270 amb 310 CloseFile(fd);
271    
272 amb 612 waysx->nfd=CloseFile(waysx->nfd);
273 amb 310
274     /* Print the final message */
275    
276 amb 650 printf_last("Separated Way Names: Ways=%d Names=%d ",waysx->number,nnames);
277 amb 310
278    
279     /* Print the start message */
280    
281 amb 519 printf_first("Sorting Ways");
282 amb 310
283 amb 555 /* Re-open the file read-only and a new file writeable */
284 amb 310
285     waysx->fd=ReOpenFile(waysx->filename);
286    
287     DeleteFile(waysx->filename);
288    
289 amb 502 fd=OpenFileNew(waysx->filename);
290 amb 310
291 amb 272 /* Allocate the array of indexes */
292    
293 amb 650 waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
294 amb 262
295 amb 243 assert(waysx->idata); /* Check malloc() worked */
296    
297 amb 310 /* Sort the ways by index and index them */
298 amb 203
299 amb 650 xnumber=waysx->number;
300 amb 499 waysx->number=0;
301    
302 amb 272 sortwaysx=waysx;
303 amb 215
304 amb 499 filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))deduplicate_and_index_by_id);
305 amb 215
306 amb 555 /* Close the files */
307 amb 262
308 amb 612 waysx->fd=CloseFile(waysx->fd);
309 amb 262 CloseFile(fd);
310    
311 amb 266 /* Print the final message */
312    
313 amb 650 printf_last("Sorted Ways: Ways=%d Duplicates=%d",xnumber,xnumber-waysx->number);
314 amb 499 }
315    
316    
317     /*++++++++++++++++++++++++++++++++++++++
318     Compact the list of ways.
319    
320     WaysX* waysx The set of ways to process.
321     ++++++++++++++++++++++++++++++++++++++*/
322    
323     void CompactWayList(WaysX* waysx)
324     {
325     index_t i;
326     int fd;
327     Way lastway;
328    
329     /* Print the start message */
330    
331 amb 519 printf_first("Sorting Ways by Properties");
332 amb 499
333 amb 555 /* Re-open the file read-only and a new file writeable */
334 amb 499
335     waysx->fd=ReOpenFile(waysx->filename);
336    
337     DeleteFile(waysx->filename);
338    
339 amb 502 fd=OpenFileNew(waysx->filename);
340 amb 499
341     /* Sort the ways to allow compacting according to he properties */
342    
343     filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,NULL);
344    
345     /* Close the files */
346    
347 amb 612 waysx->fd=CloseFile(waysx->fd);
348 amb 499 CloseFile(fd);
349    
350     /* Print the final message */
351    
352 amb 519 printf_last("Sorted Ways by Properties: Ways=%d",waysx->number);
353 amb 499
354    
355     /* Print the start message */
356    
357 amb 519 printf_first("Compacting Ways: Ways=0 Properties=0");
358 amb 499
359 amb 555 /* Re-open the file read-only and a new file writeable */
360 amb 499
361     waysx->fd=ReOpenFile(waysx->filename);
362    
363     DeleteFile(waysx->filename);
364    
365 amb 502 fd=OpenFileNew(waysx->filename);
366 amb 499
367     /* Update the way as we go using the sorted index */
368    
369     waysx->cnumber=0;
370    
371     for(i=0;i<waysx->number;i++)
372     {
373     WayX wayx;
374    
375     ReadFile(waysx->fd,&wayx,sizeof(WayX));
376    
377     if(waysx->cnumber==0 || wayx.way.name!=lastway.name || WaysCompare(&lastway,&wayx.way))
378     {
379     lastway=wayx.way;
380    
381     waysx->cnumber++;
382     }
383    
384     wayx.prop=waysx->cnumber-1;
385    
386     WriteFile(fd,&wayx,sizeof(WayX));
387    
388     if(!((i+1)%10000))
389 amb 519 printf_middle("Compacting Ways: Ways=%d Properties=%d",i+1,waysx->cnumber);
390 amb 499 }
391    
392     /* Close the files */
393    
394 amb 612 waysx->fd=CloseFile(waysx->fd);
395 amb 499 CloseFile(fd);
396    
397     /* Print the final message */
398    
399 amb 519 printf_last("Compacted Ways: Ways=%d Properties=%d ",waysx->number,waysx->cnumber);
400 amb 499
401    
402     /* Print the start message */
403    
404 amb 519 printf_first("Sorting Ways");
405 amb 499
406 amb 555 /* Re-open the file read-only and a new file writeable */
407 amb 499
408     waysx->fd=ReOpenFile(waysx->filename);
409    
410     DeleteFile(waysx->filename);
411    
412 amb 502 fd=OpenFileNew(waysx->filename);
413 amb 499
414     /* Sort the ways by index */
415    
416     filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,NULL);
417    
418 amb 555 /* Close the files */
419 amb 499
420 amb 612 waysx->fd=CloseFile(waysx->fd);
421 amb 499 CloseFile(fd);
422    
423     /* Print the final message */
424    
425 amb 519 printf_last("Sorted Ways: Ways=%d",waysx->number);
426 amb 224 }
427    
428    
429     /*++++++++++++++++++++++++++++++++++++++
430 amb 262 Sort the ways into id order.
431 amb 224
432 amb 262 int sort_by_id Returns the comparison of the id fields.
433    
434 amb 272 WayX *a The first extended way.
435 amb 262
436 amb 272 WayX *b The second extended way.
437 amb 262 ++++++++++++++++++++++++++++++++++++++*/
438    
439 amb 272 static int sort_by_id(WayX *a,WayX *b)
440 amb 262 {
441 amb 272 way_t a_id=a->id;
442     way_t b_id=b->id;
443 amb 262
444     if(a_id<b_id)
445     return(-1);
446     else if(a_id>b_id)
447     return(1);
448     else
449     return(0);
450     }
451    
452    
453     /*++++++++++++++++++++++++++++++++++++++
454 amb 680 Sort the ways into name order and then id order.
455 amb 272
456 amb 499 int sort_by_name_and_id Returns the comparison of the name and id fields.
457 amb 272
458 amb 310 WayX *a The first extended Way.
459    
460     WayX *b The second extended Way.
461     ++++++++++++++++++++++++++++++++++++++*/
462    
463 amb 499 static int sort_by_name_and_id(WayX *a,WayX *b)
464 amb 310 {
465     int compare;
466     char *a_name=(char*)a+sizeof(WayX);
467     char *b_name=(char*)b+sizeof(WayX);
468    
469     compare=strcmp(a_name,b_name);
470    
471     if(compare)
472     return(compare);
473    
474 amb 499 return(sort_by_id(a,b));
475     }
476    
477    
478     /*++++++++++++++++++++++++++++++++++++++
479     Sort the ways into name, properties and id order.
480    
481     int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
482    
483     WayX *a The first extended Way.
484    
485     WayX *b The second extended Way.
486     ++++++++++++++++++++++++++++++++++++++*/
487    
488     static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
489     {
490     int compare;
491     index_t a_name=a->way.name;
492     index_t b_name=b->way.name;
493    
494     if(a_name<b_name)
495     return(-1);
496     else if(a_name>b_name)
497     return(1);
498    
499 amb 310 compare=WaysCompare(&a->way,&b->way);
500    
501     if(compare)
502     return(compare);
503    
504     return(sort_by_id(a,b));
505     }
506    
507    
508     /*++++++++++++++++++++++++++++++++++++++
509 amb 680 Create the index of identifiers and discard duplicate ways.
510 amb 310
511 amb 680 int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise 0.
512 amb 310
513 amb 272 WayX *wayx The extended way.
514    
515     index_t index The index of this way in the total.
516     ++++++++++++++++++++++++++++++++++++++*/
517    
518 amb 499 static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
519 amb 272 {
520 amb 310 static way_t previd;
521    
522     if(index==0 || wayx->id!=previd)
523 amb 272 {
524 amb 310 previd=wayx->id;
525 amb 272
526     sortwaysx->number++;
527    
528 amb 499 sortwaysx->idata[index]=wayx->id;
529    
530 amb 272 return(1);
531     }
532    
533     return(0);
534     }
535    
536    
537     /*++++++++++++++++++++++++++++++++++++++
538 amb 285 Find a particular way index.
539    
540     index_t IndexWayX Returns the index of the extended way with the specified id.
541    
542     WaysX* waysx The set of ways to process.
543    
544     way_t id The way id to look for.
545     ++++++++++++++++++++++++++++++++++++++*/
546    
547     index_t IndexWayX(WaysX* waysx,way_t id)
548     {
549     int start=0;
550     int end=waysx->number-1;
551     int mid;
552    
553     /* Binary search - search key exact match only is required.
554     *
555     * # <- start | Check mid and move start or end if it doesn't match
556     * # |
557     * # | Since an exact match is wanted we can set end=mid-1
558     * # <- mid | or start=mid+1 because we know that mid doesn't match.
559     * # |
560     * # | Eventually either end=start or end=start+1 and one of
561     * # <- end | start or end is the wanted one.
562     */
563    
564     if(end<start) /* There are no ways */
565     return(NO_WAY);
566     else if(id<waysx->idata[start]) /* Check key is not before start */
567     return(NO_WAY);
568     else if(id>waysx->idata[end]) /* Check key is not after end */
569     return(NO_WAY);
570     else
571     {
572     do
573     {
574     mid=(start+end)/2; /* Choose mid point */
575    
576     if(waysx->idata[mid]<id) /* Mid point is too low */
577     start=mid+1;
578     else if(waysx->idata[mid]>id) /* Mid point is too high */
579     end=mid-1;
580     else /* Mid point is correct */
581     return(mid);
582     }
583     while((end-start)>1);
584    
585     if(waysx->idata[start]==id) /* Start is correct */
586     return(start);
587    
588     if(waysx->idata[end]==id) /* End is correct */
589     return(end);
590     }
591    
592     return(NO_WAY);
593     }
594    
595    
596     /*++++++++++++++++++++++++++++++++++++++
597     Save the way list to a file.
598    
599     WaysX* waysx The set of ways to save.
600    
601     const char *filename The name of the file to save.
602     ++++++++++++++++++++++++++++++++++++++*/
603    
604 amb 398 void SaveWayList(WaysX* waysx,const char *filename)
605 amb 285 {
606     index_t i;
607 amb 555 int fd;
608 amb 310 int position=0;
609 amb 499 WaysFile waysfile={0};
610 amb 529 highways_t highways=0;
611     transports_t allow=0;
612 amb 530 properties_t props=0;
613 amb 285
614 amb 461 /* Print the start message */
615    
616 amb 519 printf_first("Writing Ways: Ways=0");
617 amb 285
618 amb 555 /* Map into memory / open the file */
619 amb 461
620 amb 452 #if !SLIM
621 amb 651 waysx->data=MapFile(waysx->filename);
622 amb 555 #else
623     waysx->fd=ReOpenFile(waysx->filename);
624 amb 452 #endif
625 amb 285
626 amb 461 /* Write out the ways data */
627 amb 285
628 amb 502 fd=OpenFileNew(filename);
629 amb 285
630 amb 461 SeekFile(fd,sizeof(WaysFile));
631 amb 285
632     for(i=0;i<waysx->number;i++)
633     {
634 amb 309 WayX *wayx=LookupWayX(waysx,i,1);
635 amb 285
636 amb 526 highways|=HIGHWAYS(wayx->way.type);
637     allow |=wayx->way.allow;
638     props |=wayx->way.props;
639 amb 398
640 amb 464 SeekFile(fd,sizeof(WaysFile)+(off_t)wayx->prop*sizeof(Way));
641 amb 309 WriteFile(fd,&wayx->way,sizeof(Way));
642    
643 amb 285 if(!((i+1)%10000))
644 amb 519 printf_middle("Writing Ways: Ways=%d",i+1);
645 amb 285 }
646    
647 amb 555 /* Unmap from memory / close the file */
648 amb 398
649 amb 452 #if !SLIM
650 amb 651 waysx->data=UnmapFile(waysx->filename);
651 amb 555 #else
652 amb 612 waysx->fd=CloseFile(waysx->fd);
653 amb 452 #endif
654 amb 285
655 amb 461 /* Write out the ways names */
656 amb 285
657 amb 464 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->cnumber*sizeof(Way));
658 amb 461
659 amb 555 waysx->nfd=ReOpenFile(waysx->nfilename);
660 amb 285
661 amb 309 while(position<waysx->nlength)
662     {
663     int len=1024;
664     char temp[1024];
665    
666     if((waysx->nlength-position)<1024)
667     len=waysx->nlength-position;
668    
669 amb 555 ReadFile(waysx->nfd,temp,len);
670 amb 309 WriteFile(fd,temp,len);
671    
672     position+=len;
673     }
674    
675 amb 555 /* Close the file */
676 amb 309
677 amb 612 waysx->nfd=CloseFile(waysx->nfd);
678 amb 555
679 amb 461 /* Write out the header structure */
680    
681 amb 526 waysfile.number =waysx->cnumber;
682 amb 461 waysfile.onumber=waysx->number;
683    
684 amb 526 waysfile.highways=highways;
685     waysfile.allow =allow;
686     waysfile.props =props;
687 amb 461
688     SeekFile(fd,0);
689     WriteFile(fd,&waysfile,sizeof(WaysFile));
690    
691 amb 285 CloseFile(fd);
692    
693 amb 461 /* Print the final message */
694    
695 amb 519 printf_last("Wrote Ways: Ways=%d",waysx->number);
696 amb 285 }

Properties

Name Value
cvs:description Extended ways functions.