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 1380 - (hide annotations) (download) (as text)
Tue Jun 4 19:03:55 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20680 byte(s)
Remember what types of transports we have so that we don't spend time pruning
for transport types we don't have.

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

Properties

Name Value
cvs:description Extended ways functions.