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 1158 - (hide annotations) (download) (as text)
Mon Nov 19 18:39:12 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 18326 byte(s)
Do not create the way indexes when loading the parsed ways to apply changes
(reverses r1145).

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

Properties

Name Value
cvs:description Extended ways functions.