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 532 - (hide annotations) (download) (as text)
Sat Nov 27 14:56:37 2010 UTC (14 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 14923 byte(s)
Split functions.h into fakes.h, sorting.h and the remainder in functions.h.

1 amb 110 /***************************************
2 amb 532 $Header: /home/amb/CVS/routino/src/waysx.c,v 1.56 2010-11-27 14:56:37 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 amb 519 #include "logging.h"
37 amb 532 #include "sorting.h"
38 amb 449
39    
40 amb 262 /* Variables */
41 amb 110
42 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
43 amb 284 extern char *option_tmpdirname;
44 amb 110
45 amb 284 /*+ A temporary file-local variable for use by the sort functions. +*/
46     static WaysX *sortwaysx;
47    
48 amb 110 /* Functions */
49    
50 amb 499 static int sort_by_id(WayX *a,WayX *b);
51     static int sort_by_name_and_id(WayX *a,WayX *b);
52 amb 310 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
53    
54 amb 499 static int deduplicate_and_index_by_id(WayX *wayx,index_t index);
55 amb 272
56 amb 110
57     /*++++++++++++++++++++++++++++++++++++++
58 amb 326 Allocate a new way list (create a new file or open an existing one).
59 amb 110
60     WaysX *NewWayList Returns the way list.
61 amb 326
62     int append Set to 1 if the file is to be opened for appending (now or later).
63 amb 110 ++++++++++++++++++++++++++++++++++++++*/
64    
65 amb 326 WaysX *NewWayList(int append)
66 amb 110 {
67     WaysX *waysx;
68    
69 amb 213 waysx=(WaysX*)calloc(1,sizeof(WaysX));
70 amb 110
71 amb 243 assert(waysx); /* Check calloc() worked */
72    
73 amb 284 waysx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
74 amb 216
75 amb 326 if(append)
76 amb 447 sprintf(waysx->filename,"%s/waysx.input.tmp",option_tmpdirname);
77 amb 326 else
78 amb 447 sprintf(waysx->filename,"%s/waysx.%p.tmp",option_tmpdirname,waysx);
79 amb 262
80 amb 326 if(append)
81     {
82 amb 331 off_t size,position=0;
83 amb 326
84 amb 502 waysx->fd=OpenFileAppend(waysx->filename);
85 amb 326
86 amb 331 size=SizeFile(waysx->filename);
87 amb 326
88 amb 331 while(position<size)
89 amb 326 {
90 amb 331 FILESORT_VARINT waysize;
91 amb 326
92     SeekFile(waysx->fd,position);
93 amb 331 ReadFile(waysx->fd,&waysize,FILESORT_VARSIZE);
94 amb 326
95     waysx->xnumber++;
96 amb 331 position+=waysize+FILESORT_VARSIZE;
97 amb 326 }
98    
99 amb 331 SeekFile(waysx->fd,size);
100 amb 326 }
101     else
102 amb 502 waysx->fd=OpenFileNew(waysx->filename);
103 amb 326
104 amb 284 waysx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32);
105     sprintf(waysx->nfilename,"%s/waynames.%p.tmp",option_tmpdirname,waysx);
106 amb 262
107 amb 110 return(waysx);
108     }
109    
110    
111     /*++++++++++++++++++++++++++++++++++++++
112 amb 226 Free a way list.
113    
114     WaysX *waysx The list to be freed.
115 amb 326
116     int keep Set to 1 if the file is to be kept.
117 amb 226 ++++++++++++++++++++++++++++++++++++++*/
118    
119 amb 326 void FreeWayList(WaysX *waysx,int keep)
120 amb 226 {
121 amb 326 if(!keep)
122     DeleteFile(waysx->filename);
123    
124 amb 283 free(waysx->filename);
125 amb 262
126 amb 226 if(waysx->idata)
127     free(waysx->idata);
128    
129 amb 262 DeleteFile(waysx->nfilename);
130 amb 326
131 amb 283 free(waysx->nfilename);
132 amb 226
133     free(waysx);
134     }
135    
136    
137     /*++++++++++++++++++++++++++++++++++++++
138 amb 493 Append a single way to an unsorted way list.
139 amb 203
140 amb 262 WaysX* waysx The set of ways to process.
141 amb 110
142 amb 262 way_t id The ID of the way.
143 amb 110
144 amb 262 Way *way The way data itself.
145 amb 110
146 amb 262 const char *name The name or reference of the way.
147     ++++++++++++++++++++++++++++++++++++++*/
148 amb 110
149 amb 262 void AppendWay(WaysX* waysx,way_t id,Way *way,const char *name)
150     {
151     WayX wayx;
152 amb 311 FILESORT_VARINT size;
153 amb 110
154 amb 262 wayx.id=id;
155 amb 310 wayx.prop=0;
156 amb 262 wayx.way=*way;
157    
158 amb 310 size=sizeof(WayX)+strlen(name)+1;
159    
160 amb 311 WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
161 amb 262 WriteFile(waysx->fd,&wayx,sizeof(WayX));
162 amb 310 WriteFile(waysx->fd,name,strlen(name)+1);
163 amb 262
164     waysx->xnumber++;
165 amb 466
166     assert(!(waysx->xnumber==0)); /* Zero marks the high-water mark for ways. */
167 amb 110 }
168    
169    
170     /*++++++++++++++++++++++++++++++++++++++
171 amb 224 Sort the list of ways.
172 amb 110
173     WaysX* waysx The set of ways to process.
174     ++++++++++++++++++++++++++++++++++++++*/
175    
176     void SortWayList(WaysX* waysx)
177     {
178 amb 310 index_t i;
179     int fd,nfd;
180     char *names[2]={NULL,NULL};
181     int namelen[2]={0,0};
182 amb 499 int nnames=0;
183 amb 310 uint32_t lastlength=0;
184 amb 110
185 amb 266 /* Print the start message */
186    
187 amb 519 printf_first("Sorting Ways by Name");
188 amb 110
189 amb 310 /* Close the file and re-open it (finished appending) */
190 amb 203
191 amb 262 CloseFile(waysx->fd);
192     waysx->fd=ReOpenFile(waysx->filename);
193 amb 216
194 amb 310 DeleteFile(waysx->filename);
195 amb 262
196 amb 502 fd=OpenFileNew(waysx->filename);
197 amb 310
198 amb 499 /* Sort the ways to allow separating the names */
199 amb 310
200 amb 499 filesort_vary(waysx->fd,fd,(int (*)(const void*,const void*))sort_by_name_and_id,NULL);
201 amb 310
202     /* Close the files */
203    
204     CloseFile(waysx->fd);
205     CloseFile(fd);
206    
207     /* Print the final message */
208    
209 amb 519 printf_last("Sorted Ways by Name: Ways=%d",waysx->xnumber);
210 amb 310
211    
212     /* Print the start message */
213    
214 amb 519 printf_first("Separating Way Names: Ways=0 Names=0");
215 amb 310
216     /* Open the files */
217    
218     waysx->fd=ReOpenFile(waysx->filename);
219    
220 amb 272 DeleteFile(waysx->filename);
221 amb 262
222 amb 502 fd=OpenFileNew(waysx->filename);
223     nfd=OpenFileNew(waysx->nfilename);
224 amb 272
225 amb 499 /* Copy from the single file into two files */
226 amb 310
227 amb 499 for(i=0;i<waysx->xnumber;i++)
228 amb 310 {
229     WayX wayx;
230 amb 311 FILESORT_VARINT size;
231 amb 310
232 amb 311 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
233 amb 310
234     if(namelen[nnames%2]<size)
235     names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
236    
237     ReadFile(waysx->fd,&wayx,sizeof(WayX));
238     ReadFile(waysx->fd,names[nnames%2],size-sizeof(WayX));
239    
240     if(nnames==0 || strcmp(names[0],names[1]))
241     {
242     WriteFile(nfd,names[nnames%2],size-sizeof(WayX));
243    
244     lastlength=waysx->nlength;
245     waysx->nlength+=size-sizeof(WayX);
246    
247     nnames++;
248     }
249    
250     wayx.way.name=lastlength;
251    
252     WriteFile(fd,&wayx,sizeof(WayX));
253    
254     if(!((i+1)%10000))
255 amb 519 printf_middle("Separating Way Names: Ways=%d Names=%d",i+1,nnames);
256 amb 310 }
257    
258     if(names[0]) free(names[0]);
259     if(names[1]) free(names[1]);
260    
261     /* Close the files */
262    
263     CloseFile(waysx->fd);
264     CloseFile(fd);
265    
266     waysx->fd=ReOpenFile(waysx->filename);
267    
268     CloseFile(nfd);
269    
270     /* Print the final message */
271    
272 amb 519 printf_last("Separated Way Names: Ways=%d Names=%d ",waysx->xnumber,nnames);
273 amb 310
274    
275     /* Print the start message */
276    
277 amb 519 printf_first("Sorting Ways");
278 amb 310
279     /* Open the files */
280    
281     waysx->fd=ReOpenFile(waysx->filename);
282    
283     DeleteFile(waysx->filename);
284    
285 amb 502 fd=OpenFileNew(waysx->filename);
286 amb 310
287 amb 272 /* Allocate the array of indexes */
288    
289 amb 499 waysx->idata=(way_t*)malloc(waysx->xnumber*sizeof(way_t));
290 amb 262
291 amb 243 assert(waysx->idata); /* Check malloc() worked */
292    
293 amb 310 /* Sort the ways by index and index them */
294 amb 203
295 amb 499 waysx->number=0;
296    
297 amb 272 sortwaysx=waysx;
298 amb 215
299 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);
300 amb 215
301 amb 262 /* Close the files and re-open them */
302    
303     CloseFile(waysx->fd);
304     CloseFile(fd);
305    
306     waysx->fd=ReOpenFile(waysx->filename);
307    
308 amb 266 /* Print the final message */
309    
310 amb 519 printf_last("Sorted Ways: Ways=%d Duplicates=%d",waysx->number,waysx->xnumber-waysx->number);
311 amb 499 }
312    
313    
314     /*++++++++++++++++++++++++++++++++++++++
315     Compact the list of ways.
316    
317     WaysX* waysx The set of ways to process.
318     ++++++++++++++++++++++++++++++++++++++*/
319    
320     void CompactWayList(WaysX* waysx)
321     {
322     index_t i;
323     int fd;
324     Way lastway;
325    
326     /* Print the start message */
327    
328 amb 519 printf_first("Sorting Ways by Properties");
329 amb 499
330     /* Close the file and re-open it */
331    
332     CloseFile(waysx->fd);
333     waysx->fd=ReOpenFile(waysx->filename);
334    
335     DeleteFile(waysx->filename);
336    
337 amb 502 fd=OpenFileNew(waysx->filename);
338 amb 499
339     /* Sort the ways to allow compacting according to he properties */
340    
341     filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,NULL);
342    
343     /* Close the files */
344    
345     CloseFile(waysx->fd);
346     CloseFile(fd);
347    
348     /* Print the final message */
349    
350 amb 519 printf_last("Sorted Ways by Properties: Ways=%d",waysx->number);
351 amb 499
352    
353     /* Print the start message */
354    
355 amb 519 printf_first("Compacting Ways: Ways=0 Properties=0");
356 amb 499
357     /* Open the files */
358    
359     waysx->fd=ReOpenFile(waysx->filename);
360    
361     DeleteFile(waysx->filename);
362    
363 amb 502 fd=OpenFileNew(waysx->filename);
364 amb 499
365     /* Update the way as we go using the sorted index */
366    
367     waysx->cnumber=0;
368    
369     for(i=0;i<waysx->number;i++)
370     {
371     WayX wayx;
372    
373     ReadFile(waysx->fd,&wayx,sizeof(WayX));
374    
375     if(waysx->cnumber==0 || wayx.way.name!=lastway.name || WaysCompare(&lastway,&wayx.way))
376     {
377     lastway=wayx.way;
378    
379     waysx->cnumber++;
380     }
381    
382     wayx.prop=waysx->cnumber-1;
383    
384     WriteFile(fd,&wayx,sizeof(WayX));
385    
386     if(!((i+1)%10000))
387 amb 519 printf_middle("Compacting Ways: Ways=%d Properties=%d",i+1,waysx->cnumber);
388 amb 499 }
389    
390     /* Close the files */
391    
392     CloseFile(waysx->fd);
393     CloseFile(fd);
394    
395     /* Print the final message */
396    
397 amb 519 printf_last("Compacted Ways: Ways=%d Properties=%d ",waysx->number,waysx->cnumber);
398 amb 499
399    
400     /* Print the start message */
401    
402 amb 519 printf_first("Sorting Ways");
403 amb 499
404     /* Open the files */
405    
406     waysx->fd=ReOpenFile(waysx->filename);
407    
408     DeleteFile(waysx->filename);
409    
410 amb 502 fd=OpenFileNew(waysx->filename);
411 amb 499
412     /* Sort the ways by index */
413    
414     filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,NULL);
415    
416     /* Close the files and re-open them */
417    
418     CloseFile(waysx->fd);
419     CloseFile(fd);
420    
421     waysx->fd=ReOpenFile(waysx->filename);
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 499 Sort the ways into name and 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 499 Deduplicate the extended ways using the id after sorting and create the index.
510 amb 310
511 amb 499 int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise zero.
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 310 int fd,nfd;
608     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 461 /* Map into memory */
619    
620 amb 452 #if !SLIM
621     waysx->xdata=MapFile(waysx->filename);
622     #endif
623 amb 285
624 amb 461 /* Write out the ways data */
625 amb 285
626 amb 502 fd=OpenFileNew(filename);
627 amb 285
628 amb 461 SeekFile(fd,sizeof(WaysFile));
629 amb 285
630     for(i=0;i<waysx->number;i++)
631     {
632 amb 309 WayX *wayx=LookupWayX(waysx,i,1);
633 amb 285
634 amb 526 highways|=HIGHWAYS(wayx->way.type);
635     allow |=wayx->way.allow;
636     props |=wayx->way.props;
637 amb 398
638 amb 464 SeekFile(fd,sizeof(WaysFile)+(off_t)wayx->prop*sizeof(Way));
639 amb 309 WriteFile(fd,&wayx->way,sizeof(Way));
640    
641 amb 285 if(!((i+1)%10000))
642 amb 519 printf_middle("Writing Ways: Ways=%d",i+1);
643 amb 285 }
644    
645 amb 461 /* Unmap from memory */
646 amb 398
647 amb 452 #if !SLIM
648     waysx->xdata=UnmapFile(waysx->filename);
649     #endif
650 amb 285
651 amb 461 /* Write out the ways names */
652 amb 285
653 amb 464 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->cnumber*sizeof(Way));
654 amb 461
655 amb 310 nfd=ReOpenFile(waysx->nfilename);
656 amb 285
657 amb 309 while(position<waysx->nlength)
658     {
659     int len=1024;
660     char temp[1024];
661    
662     if((waysx->nlength-position)<1024)
663     len=waysx->nlength-position;
664    
665 amb 310 ReadFile(nfd,temp,len);
666 amb 309 WriteFile(fd,temp,len);
667    
668     position+=len;
669     }
670    
671 amb 310 CloseFile(nfd);
672 amb 309
673 amb 461 /* Write out the header structure */
674    
675 amb 526 waysfile.number =waysx->cnumber;
676 amb 461 waysfile.onumber=waysx->number;
677    
678 amb 526 waysfile.highways=highways;
679     waysfile.allow =allow;
680     waysfile.props =props;
681 amb 461
682     SeekFile(fd,0);
683     WriteFile(fd,&waysfile,sizeof(WaysFile));
684    
685 amb 285 CloseFile(fd);
686    
687 amb 461 /* Print the final message */
688    
689 amb 519 printf_last("Wrote Ways: Ways=%d",waysx->number);
690 amb 285 }

Properties

Name Value
cvs:description Extended ways functions.