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 1148 - (hide annotations) (download) (as text)
Sat Nov 17 17:44:07 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 19339 byte(s)
Replace a hard-coded constant with the #defined value it should have been.

1 amb 110 /***************************************
2     Extended Way data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 110 ******************/ /******************
6 amb 948 This file Copyright 2008-2012 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     #include <string.h>
26    
27 amb 955 #include "types.h"
28 amb 228 #include "ways.h"
29 amb 110
30 amb 955 #include "typesx.h"
31 amb 1092 #include "segmentsx.h"
32 amb 449 #include "waysx.h"
33 amb 110
34 amb 449 #include "files.h"
35 amb 519 #include "logging.h"
36 amb 532 #include "sorting.h"
37 amb 449
38    
39 amb 680 /* Global 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 1146 /*+ The option to apply changes (needed to suppress some error log messages) +*/
45     extern int option_changes;
46    
47 amb 680 /* Local variables */
48    
49 amb 1094 /*+ Temporary file-local variables for use by the sort functions. +*/
50 amb 284 static WaysX *sortwaysx;
51 amb 1100 static SegmentsX *sortsegmentsx;
52 amb 284
53 amb 1100 /* Local functions */
54 amb 680
55 amb 499 static int sort_by_id(WayX *a,WayX *b);
56 amb 1129 static int sort_by_name(WayX *a,WayX *b);
57 amb 310 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
58    
59 amb 1114 static int delete_unused(WayX *wayx,index_t index);
60 amb 1135 static int deduplicate_by_id(WayX *wayx,index_t index);
61     static int index_by_id(WayX *wayx,index_t index);
62 amb 1094 static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index);
63 amb 272
64 amb 110
65     /*++++++++++++++++++++++++++++++++++++++
66 amb 326 Allocate a new way list (create a new file or open an existing one).
67 amb 110
68     WaysX *NewWayList Returns the way list.
69 amb 326
70 amb 1123 int append Set to 1 if the file is to be opened for appending.
71    
72 amb 1139 int readonly Set to 1 if the file is to be opened for reading.
73 amb 1145
74     int index Set to 1 if the file is to be indexed (requires append=1).
75 amb 110 ++++++++++++++++++++++++++++++++++++++*/
76    
77 amb 1145 WaysX *NewWayList(int append,int readonly,int index)
78 amb 110 {
79     WaysX *waysx;
80    
81 amb 213 waysx=(WaysX*)calloc(1,sizeof(WaysX));
82 amb 110
83 amb 243 assert(waysx); /* Check calloc() worked */
84    
85 amb 1120 waysx->filename =(char*)malloc(strlen(option_tmpdirname)+32);
86     waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
87 amb 216
88 amb 1120 sprintf(waysx->filename ,"%s/waysx.parsed.mem",option_tmpdirname);
89     sprintf(waysx->filename_tmp,"%s/waysx.%p.tmp" ,option_tmpdirname,(void*)waysx);
90 amb 262
91 amb 1123 if(append || readonly)
92     if(ExistsFile(waysx->filename))
93     {
94     off_t size,position=0;
95     int fd;
96 amb 326
97 amb 1123 size=SizeFile(waysx->filename);
98 amb 326
99 amb 1123 fd=ReOpenFile(waysx->filename);
100 amb 326
101 amb 1123 while(position<size)
102     {
103     FILESORT_VARINT waysize;
104 amb 326
105 amb 1123 SeekReadFile(fd,&waysize,FILESORT_VARSIZE,position);
106 amb 326
107 amb 1123 waysx->number++;
108     position+=waysize+FILESORT_VARSIZE;
109     }
110    
111     CloseFile(fd);
112 amb 1139
113 amb 1145 if(append && index)
114     {
115     /* Allocate the array of indexes */
116    
117     waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
118    
119     assert(waysx->idata); /* Check malloc() worked */
120    
121     /* Read through the file again */
122    
123     fd=ReOpenFile(waysx->filename);
124    
125     position=0;
126    
127     while(position<size)
128     {
129     FILESORT_VARINT waysize;
130     WayX wayx;
131    
132     SeekReadFile(fd,&waysize,FILESORT_VARSIZE,position);
133    
134 amb 1148 SeekReadFile(fd,&wayx,sizeof(WayX),position+FILESORT_VARSIZE);
135 amb 1145
136     waysx->idata[waysx->inumber]=wayx.id;
137    
138     waysx->inumber++;
139     position+=waysize+FILESORT_VARSIZE;
140     }
141    
142     CloseFile(fd);
143     }
144    
145 amb 1139 RenameFile(waysx->filename,waysx->filename_tmp);
146 amb 326 }
147    
148 amb 1123 if(append)
149 amb 1139 waysx->fd=OpenFileAppend(waysx->filename_tmp);
150 amb 1123 else if(!readonly)
151 amb 1139 waysx->fd=OpenFileNew(waysx->filename_tmp);
152 amb 326 else
153 amb 1123 waysx->fd=-1;
154 amb 326
155 amb 262
156 amb 1120 waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
157    
158     sprintf(waysx->nfilename_tmp,"%s/waynames.%p.tmp",option_tmpdirname,(void*)waysx);
159    
160 amb 110 return(waysx);
161     }
162    
163    
164     /*++++++++++++++++++++++++++++++++++++++
165 amb 226 Free a way list.
166    
167 amb 681 WaysX *waysx The set of ways to be freed.
168 amb 226 ++++++++++++++++++++++++++++++++++++++*/
169    
170 amb 1136 void FreeWayList(WaysX *waysx)
171 amb 226 {
172 amb 1120 DeleteFile(waysx->filename_tmp);
173    
174 amb 283 free(waysx->filename);
175 amb 1120 free(waysx->filename_tmp);
176 amb 262
177 amb 226 if(waysx->idata)
178     free(waysx->idata);
179    
180 amb 1093 if(waysx->cdata)
181     free(waysx->cdata);
182    
183 amb 1120 DeleteFile(waysx->nfilename_tmp);
184 amb 326
185 amb 1120 free(waysx->nfilename_tmp);
186 amb 226
187     free(waysx);
188     }
189    
190    
191     /*++++++++++++++++++++++++++++++++++++++
192 amb 493 Append a single way to an unsorted way list.
193 amb 203
194 amb 682 WaysX *waysx The set of ways to process.
195 amb 110
196 amb 262 way_t id The ID of the way.
197 amb 110
198 amb 262 Way *way The way data itself.
199 amb 110
200 amb 262 const char *name The name or reference of the way.
201     ++++++++++++++++++++++++++++++++++++++*/
202 amb 110
203 amb 682 void AppendWay(WaysX *waysx,way_t id,Way *way,const char *name)
204 amb 262 {
205     WayX wayx;
206 amb 311 FILESORT_VARINT size;
207 amb 110
208 amb 262 wayx.id=id;
209     wayx.way=*way;
210    
211 amb 310 size=sizeof(WayX)+strlen(name)+1;
212    
213 amb 311 WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
214 amb 262 WriteFile(waysx->fd,&wayx,sizeof(WayX));
215 amb 310 WriteFile(waysx->fd,name,strlen(name)+1);
216 amb 262
217 amb 650 waysx->number++;
218 amb 466
219 amb 1065 assert(waysx->number!=0); /* Zero marks the high-water mark for ways. */
220 amb 110 }
221    
222    
223     /*++++++++++++++++++++++++++++++++++++++
224 amb 1120 Finish appending ways and change the filename over.
225    
226     WaysX *waysx The ways that have been appended.
227 amb 1139
228     int preserve If set then the results file is to be preserved.
229 amb 1120 ++++++++++++++++++++++++++++++++++++++*/
230    
231 amb 1139 void FinishWayList(WaysX *waysx,int preserve)
232 amb 1120 {
233 amb 1145 if(waysx->idata)
234     {free(waysx->idata);waysx->idata=NULL;}
235    
236 amb 1120 /* Close the file (finished appending) */
237    
238 amb 1136 if(waysx->fd!=-1)
239     waysx->fd=CloseFile(waysx->fd);
240 amb 1120
241 amb 1139 /* Rename the file if keeping it */
242 amb 1120
243 amb 1139 if(preserve)
244     RenameFile(waysx->filename_tmp,waysx->filename);
245 amb 1120 }
246    
247    
248     /*++++++++++++++++++++++++++++++++++++++
249 amb 224 Sort the list of ways.
250 amb 110
251 amb 682 WaysX *waysx The set of ways to process.
252 amb 110 ++++++++++++++++++++++++++++++++++++++*/
253    
254 amb 682 void SortWayList(WaysX *waysx)
255 amb 110 {
256 amb 1129 index_t xnumber;
257 amb 555 int fd;
258 amb 1129
259     /* Print the start message */
260    
261     printf_first("Sorting Ways");
262    
263     /* Re-open the file read-only and a new file writeable */
264    
265     waysx->fd=ReOpenFile(waysx->filename_tmp);
266    
267     DeleteFile(waysx->filename_tmp);
268    
269     fd=OpenFileNew(waysx->filename_tmp);
270    
271     /* Sort the ways by ID and index them */
272    
273     xnumber=waysx->number;
274    
275     waysx->number=filesort_vary(waysx->fd,fd,NULL,
276     (int (*)(const void*,const void*))sort_by_id,
277 amb 1135 (int (*)(void*,index_t))deduplicate_by_id);
278 amb 1129
279     /* Close the files */
280    
281     waysx->fd=CloseFile(waysx->fd);
282     CloseFile(fd);
283    
284     /* Print the final message */
285    
286     printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number);
287     }
288    
289    
290     /*++++++++++++++++++++++++++++++++++++++
291     Extract the way names from the ways and reference the list of names from the ways.
292    
293     WaysX *waysx The set of ways to process.
294 amb 1136
295     int preserve If set to 1 then keep the old data file otherwise delete it.
296 amb 1129 ++++++++++++++++++++++++++++++++++++++*/
297    
298 amb 1136 void ExtractWayNames(WaysX *waysx,int preserve)
299 amb 1129 {
300     index_t i;
301     int fd;
302 amb 310 char *names[2]={NULL,NULL};
303     int namelen[2]={0,0};
304 amb 499 int nnames=0;
305 amb 310 uint32_t lastlength=0;
306 amb 110
307 amb 266 /* Print the start message */
308    
309 amb 519 printf_first("Sorting Ways by Name");
310 amb 110
311 amb 555 /* Re-open the file read-only and a new file writeable */
312    
313 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
314 amb 216
315 amb 1136 if(preserve)
316     RenameFile(waysx->filename_tmp,waysx->filename);
317     else
318     DeleteFile(waysx->filename_tmp);
319 amb 262
320 amb 1120 fd=OpenFileNew(waysx->filename_tmp);
321 amb 310
322 amb 499 /* Sort the ways to allow separating the names */
323 amb 310
324 amb 1106 filesort_vary(waysx->fd,fd,NULL,
325 amb 1129 (int (*)(const void*,const void*))sort_by_name,
326 amb 1106 NULL);
327 amb 310
328     /* Close the files */
329    
330 amb 612 waysx->fd=CloseFile(waysx->fd);
331 amb 310 CloseFile(fd);
332    
333     /* Print the final message */
334    
335 amb 790 printf_last("Sorted Ways by Name: Ways=%"Pindex_t,waysx->number);
336 amb 310
337    
338     /* Print the start message */
339    
340 amb 519 printf_first("Separating Way Names: Ways=0 Names=0");
341 amb 310
342 amb 555 /* Re-open the file read-only and new files writeable */
343 amb 310
344 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
345 amb 310
346 amb 1120 DeleteFile(waysx->filename_tmp);
347 amb 262
348 amb 1120 fd=OpenFileNew(waysx->filename_tmp);
349 amb 272
350 amb 1120 waysx->nfd=OpenFileNew(waysx->nfilename_tmp);
351 amb 555
352 amb 499 /* Copy from the single file into two files */
353 amb 310
354 amb 650 for(i=0;i<waysx->number;i++)
355 amb 310 {
356     WayX wayx;
357 amb 311 FILESORT_VARINT size;
358 amb 310
359 amb 311 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
360 amb 310
361     if(namelen[nnames%2]<size)
362     names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
363    
364     ReadFile(waysx->fd,&wayx,sizeof(WayX));
365     ReadFile(waysx->fd,names[nnames%2],size-sizeof(WayX));
366    
367     if(nnames==0 || strcmp(names[0],names[1]))
368     {
369 amb 555 WriteFile(waysx->nfd,names[nnames%2],size-sizeof(WayX));
370 amb 310
371     lastlength=waysx->nlength;
372     waysx->nlength+=size-sizeof(WayX);
373    
374     nnames++;
375     }
376    
377     wayx.way.name=lastlength;
378    
379     WriteFile(fd,&wayx,sizeof(WayX));
380    
381 amb 757 if(!((i+1)%1000))
382 amb 790 printf_middle("Separating Way Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames);
383 amb 310 }
384    
385     if(names[0]) free(names[0]);
386     if(names[1]) free(names[1]);
387    
388     /* Close the files */
389    
390 amb 612 waysx->fd=CloseFile(waysx->fd);
391 amb 310 CloseFile(fd);
392    
393 amb 612 waysx->nfd=CloseFile(waysx->nfd);
394 amb 310
395     /* Print the final message */
396    
397 amb 1092 printf_last("Separated Way Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames);
398 amb 310
399    
400     /* Print the start message */
401    
402 amb 519 printf_first("Sorting Ways");
403 amb 310
404 amb 555 /* Re-open the file read-only and a new file writeable */
405 amb 310
406 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
407 amb 310
408 amb 1120 DeleteFile(waysx->filename_tmp);
409 amb 310
410 amb 1120 fd=OpenFileNew(waysx->filename_tmp);
411 amb 310
412 amb 1135 /* Allocate the array of indexes */
413    
414     waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
415    
416     assert(waysx->idata); /* Check malloc() worked */
417    
418 amb 1145 waysx->inumber=waysx->number;
419    
420 amb 1129 /* Sort the ways by ID */
421 amb 272
422 amb 1135 sortwaysx=waysx;
423    
424 amb 1129 filesort_fixed(waysx->fd,fd,sizeof(WayX),NULL,
425     (int (*)(const void*,const void*))sort_by_id,
426 amb 1135 (int (*)(void*,index_t))index_by_id);
427 amb 262
428 amb 555 /* Close the files */
429 amb 262
430 amb 612 waysx->fd=CloseFile(waysx->fd);
431 amb 262 CloseFile(fd);
432    
433 amb 266 /* Print the final message */
434    
435 amb 1129 printf_last("Sorted Ways: Ways=%"Pindex_t,waysx->number);
436 amb 499 }
437    
438    
439     /*++++++++++++++++++++++++++++++++++++++
440 amb 1100 Compact the way list, removing duplicated ways and unused ways.
441 amb 499
442 amb 1100 WaysX *waysx The set of ways to process.
443 amb 1092
444 amb 1100 SegmentsX *segmentsx The set of segments to check.
445 amb 499 ++++++++++++++++++++++++++++++++++++++*/
446    
447 amb 1100 void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
448 amb 499 {
449 amb 1100 int fd;
450     index_t cnumber;
451 amb 499
452     /* Print the start message */
453    
454 amb 1094 printf_first("Sorting Ways and Compacting");
455 amb 1092
456 amb 1093 /* Allocate the array of indexes */
457 amb 499
458 amb 1093 waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t));
459 amb 499
460 amb 1093 assert(waysx->cdata); /* Check malloc() worked */
461 amb 499
462 amb 1100 /* Re-open the file read-only and a new file writeable */
463 amb 499
464 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
465 amb 1093
466 amb 1120 DeleteFile(waysx->filename_tmp);
467 amb 1100
468 amb 1120 fd=OpenFileNew(waysx->filename_tmp);
469 amb 1100
470 amb 1094 /* Sort the ways to allow compacting according to the properties */
471 amb 499
472 amb 1094 sortwaysx=waysx;
473 amb 1100 sortsegmentsx=segmentsx;
474 amb 499
475 amb 1114 cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused,
476 amb 1106 (int (*)(const void*,const void*))sort_by_name_and_prop_and_id,
477     (int (*)(void*,index_t))deduplicate_and_index_by_compact_id);
478 amb 499
479 amb 1100 /* Close the files */
480 amb 499
481 amb 1094 waysx->fd=CloseFile(waysx->fd);
482 amb 1100 CloseFile(fd);
483 amb 499
484     /* Print the final message */
485    
486 amb 1100 printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber);
487     waysx->number=cnumber;
488 amb 499
489 amb 1100 free(segmentsx->usedway);
490     segmentsx->usedway=NULL;
491 amb 224 }
492    
493    
494     /*++++++++++++++++++++++++++++++++++++++
495 amb 262 Sort the ways into id order.
496 amb 224
497 amb 262 int sort_by_id Returns the comparison of the id fields.
498    
499 amb 272 WayX *a The first extended way.
500 amb 262
501 amb 272 WayX *b The second extended way.
502 amb 262 ++++++++++++++++++++++++++++++++++++++*/
503    
504 amb 272 static int sort_by_id(WayX *a,WayX *b)
505 amb 262 {
506 amb 272 way_t a_id=a->id;
507     way_t b_id=b->id;
508 amb 262
509     if(a_id<b_id)
510     return(-1);
511     else if(a_id>b_id)
512     return(1);
513     else
514 amb 1140 return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
515 amb 262 }
516    
517    
518     /*++++++++++++++++++++++++++++++++++++++
519 amb 680 Sort the ways into name order and then id order.
520 amb 272
521 amb 1129 int sort_by_name Returns the comparison of the name fields.
522 amb 272
523 amb 310 WayX *a The first extended Way.
524    
525     WayX *b The second extended Way.
526     ++++++++++++++++++++++++++++++++++++++*/
527    
528 amb 1129 static int sort_by_name(WayX *a,WayX *b)
529 amb 310 {
530     int compare;
531     char *a_name=(char*)a+sizeof(WayX);
532     char *b_name=(char*)b+sizeof(WayX);
533    
534     compare=strcmp(a_name,b_name);
535    
536     if(compare)
537     return(compare);
538 amb 1129 else
539     return(FILESORT_PRESERVE_ORDER(a,b));
540 amb 499 }
541    
542    
543     /*++++++++++++++++++++++++++++++++++++++
544     Sort the ways into name, properties and id order.
545    
546     int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
547    
548     WayX *a The first extended Way.
549    
550     WayX *b The second extended Way.
551     ++++++++++++++++++++++++++++++++++++++*/
552    
553     static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
554     {
555     int compare;
556     index_t a_name=a->way.name;
557     index_t b_name=b->way.name;
558    
559     if(a_name<b_name)
560     return(-1);
561     else if(a_name>b_name)
562     return(1);
563    
564 amb 310 compare=WaysCompare(&a->way,&b->way);
565    
566     if(compare)
567     return(compare);
568    
569     return(sort_by_id(a,b));
570     }
571    
572    
573     /*++++++++++++++++++++++++++++++++++++++
574 amb 1135 Discard duplicate ways.
575 amb 310
576 amb 1135 int deduplicate_by_id Return 1 if the value is to be kept, otherwise 0.
577 amb 310
578 amb 272 WayX *wayx The extended way.
579    
580 amb 1106 index_t index The number of sorted ways that have already been written to the output file.
581 amb 272 ++++++++++++++++++++++++++++++++++++++*/
582    
583 amb 1135 static int deduplicate_by_id(WayX *wayx,index_t index)
584 amb 272 {
585 amb 1140 static way_t previd=NO_WAY_ID;
586 amb 310
587 amb 1140 if(wayx->id!=previd)
588 amb 272 {
589 amb 310 previd=wayx->id;
590 amb 272
591 amb 1140 if(wayx->way.type==WAY_DELETED)
592     return(0);
593     else
594     return(1);
595 amb 272 }
596 amb 812 else
597     {
598 amb 1146 if(!option_changes)
599     logerror("Way %"Pway_t" is duplicated.\n",wayx->id);
600 amb 272
601 amb 812 return(0);
602     }
603 amb 272 }
604    
605    
606     /*++++++++++++++++++++++++++++++++++++++
607 amb 1135 Create the index of identifiers.
608    
609     int index_by_id Return 1 if the value is to be kept, otherwise 0.
610    
611     WayX *wayx The extended way.
612    
613     index_t index The number of sorted ways that have already been written to the output file.
614     ++++++++++++++++++++++++++++++++++++++*/
615    
616     static int index_by_id(WayX *wayx,index_t index)
617     {
618     sortwaysx->idata[index]=wayx->id;
619    
620     return(1);
621     }
622    
623    
624     /*++++++++++++++++++++++++++++++++++++++
625 amb 1113 Delete the ways that are no longer being used.
626 amb 1094
627 amb 1114 int delete_unused Return 1 if the value is to be kept, otherwise 0.
628 amb 1094
629     WayX *wayx The extended way.
630    
631 amb 1113 index_t index The number of unsorted ways that have been read from the input file.
632 amb 1094 ++++++++++++++++++++++++++++++++++++++*/
633    
634 amb 1114 static int delete_unused(WayX *wayx,index_t index)
635 amb 1094 {
636 amb 1114 if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index))
637 amb 1094 {
638 amb 1114 sortwaysx->cdata[index]=NO_WAY;
639 amb 1094
640 amb 1100 return(0);
641 amb 1094 }
642 amb 1114 else
643     {
644     wayx->id=index;
645 amb 1100
646 amb 1114 return(1);
647     }
648 amb 1113 }
649    
650    
651     /*++++++++++++++++++++++++++++++++++++++
652     Create the index of compacted Way identifiers and ignore Ways with duplicated properties.
653    
654     int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0.
655    
656     WayX *wayx The extended way.
657    
658     index_t index The number of sorted ways that have already been written to the output file.
659     ++++++++++++++++++++++++++++++++++++++*/
660    
661     static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
662     {
663     static Way lastway;
664    
665 amb 1100 if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
666 amb 1094 {
667 amb 1100 lastway=wayx->way;
668 amb 1094
669 amb 1100 sortwaysx->cdata[wayx->id]=index;
670 amb 1094
671 amb 1100 wayx->id=index;
672    
673     return(1);
674 amb 1094 }
675 amb 1100 else
676     {
677     sortwaysx->cdata[wayx->id]=index-1;
678 amb 1094
679 amb 1100 return(0);
680     }
681 amb 1094 }
682    
683    
684     /*++++++++++++++++++++++++++++++++++++++
685 amb 285 Find a particular way index.
686    
687     index_t IndexWayX Returns the index of the extended way with the specified id.
688    
689 amb 682 WaysX *waysx The set of ways to process.
690 amb 285
691     way_t id The way id to look for.
692     ++++++++++++++++++++++++++++++++++++++*/
693    
694 amb 682 index_t IndexWayX(WaysX *waysx,way_t id)
695 amb 285 {
696 amb 780 index_t start=0;
697 amb 1145 index_t end=waysx->inumber-1;
698 amb 780 index_t mid;
699 amb 285
700     /* Binary search - search key exact match only is required.
701     *
702     * # <- start | Check mid and move start or end if it doesn't match
703     * # |
704     * # | Since an exact match is wanted we can set end=mid-1
705     * # <- mid | or start=mid+1 because we know that mid doesn't match.
706     * # |
707     * # | Eventually either end=start or end=start+1 and one of
708     * # <- end | start or end is the wanted one.
709     */
710    
711     if(end<start) /* There are no ways */
712     return(NO_WAY);
713     else if(id<waysx->idata[start]) /* Check key is not before start */
714     return(NO_WAY);
715     else if(id>waysx->idata[end]) /* Check key is not after end */
716     return(NO_WAY);
717     else
718     {
719     do
720     {
721     mid=(start+end)/2; /* Choose mid point */
722    
723     if(waysx->idata[mid]<id) /* Mid point is too low */
724     start=mid+1;
725     else if(waysx->idata[mid]>id) /* Mid point is too high */
726 amb 843 end=mid?(mid-1):mid;
727 amb 285 else /* Mid point is correct */
728     return(mid);
729     }
730     while((end-start)>1);
731    
732     if(waysx->idata[start]==id) /* Start is correct */
733     return(start);
734    
735     if(waysx->idata[end]==id) /* End is correct */
736     return(end);
737     }
738    
739     return(NO_WAY);
740     }
741    
742    
743     /*++++++++++++++++++++++++++++++++++++++
744     Save the way list to a file.
745    
746 amb 682 WaysX *waysx The set of ways to save.
747 amb 285
748     const char *filename The name of the file to save.
749     ++++++++++++++++++++++++++++++++++++++*/
750    
751 amb 682 void SaveWayList(WaysX *waysx,const char *filename)
752 amb 285 {
753     index_t i;
754 amb 555 int fd;
755 amb 310 int position=0;
756 amb 1104 WayX wayx;
757 amb 499 WaysFile waysfile={0};
758 amb 529 highways_t highways=0;
759     transports_t allow=0;
760 amb 530 properties_t props=0;
761 amb 285
762 amb 461 /* Print the start message */
763    
764 amb 519 printf_first("Writing Ways: Ways=0");
765 amb 285
766 amb 1104 /* Re-open the files */
767 amb 461
768 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
769     waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
770 amb 285
771 amb 461 /* Write out the ways data */
772 amb 285
773 amb 502 fd=OpenFileNew(filename);
774 amb 285
775 amb 461 SeekFile(fd,sizeof(WaysFile));
776 amb 285
777     for(i=0;i<waysx->number;i++)
778     {
779 amb 1104 ReadFile(waysx->fd,&wayx,sizeof(WayX));
780 amb 285
781 amb 1104 highways|=HIGHWAYS(wayx.way.type);
782     allow |=wayx.way.allow;
783     props |=wayx.way.props;
784 amb 398
785 amb 1104 WriteFile(fd,&wayx.way,sizeof(Way));
786 amb 309
787 amb 757 if(!((i+1)%1000))
788 amb 790 printf_middle("Writing Ways: Ways=%"Pindex_t,i+1);
789 amb 285 }
790    
791 amb 461 /* Write out the ways names */
792 amb 285
793 amb 1100 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
794 amb 461
795 amb 309 while(position<waysx->nlength)
796     {
797     int len=1024;
798     char temp[1024];
799    
800     if((waysx->nlength-position)<1024)
801     len=waysx->nlength-position;
802    
803 amb 555 ReadFile(waysx->nfd,temp,len);
804 amb 1104
805 amb 309 WriteFile(fd,temp,len);
806    
807     position+=len;
808     }
809    
810 amb 1104 /* Close the files */
811 amb 309
812 amb 1104 waysx->fd=CloseFile(waysx->fd);
813 amb 612 waysx->nfd=CloseFile(waysx->nfd);
814 amb 555
815 amb 461 /* Write out the header structure */
816    
817 amb 1100 waysfile.number =waysx->number;
818 amb 461
819 amb 526 waysfile.highways=highways;
820     waysfile.allow =allow;
821     waysfile.props =props;
822 amb 461
823     SeekFile(fd,0);
824     WriteFile(fd,&waysfile,sizeof(WaysFile));
825    
826 amb 285 CloseFile(fd);
827    
828 amb 461 /* Print the final message */
829    
830 amb 1100 printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number);
831 amb 285 }

Properties

Name Value
cvs:description Extended ways functions.