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 1695 - (hide annotations) (download) (as text)
Fri May 29 16:49:00 2015 UTC (9 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 21610 byte(s)
Ensure that allocated strings are long enough even if the %p format is
extravagant in the number of characters it uses.

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

Properties

Name Value
cvs:description Extended ways functions.