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 1349 - (hide annotations) (download) (as text)
Wed May 29 17:33:26 2013 UTC (11 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 20647 byte(s)
Simplify the segments by using the node and way index instead of node and way id
which avoids lots of IndexNodeX() lookups.  Move some other code around to cope
with it.

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     /* Close the files */
324    
325     waysx->fd=CloseFile(waysx->fd);
326     CloseFile(fd);
327    
328     /* Print the final message */
329    
330     printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number);
331     }
332    
333    
334     /*++++++++++++++++++++++++++++++++++++++
335 amb 1160 Sort the ways into id order.
336    
337     int sort_by_id Returns the comparison of the id fields.
338    
339     WayX *a The first extended way.
340    
341     WayX *b The second extended way.
342     ++++++++++++++++++++++++++++++++++++++*/
343    
344     static int sort_by_id(WayX *a,WayX *b)
345     {
346     way_t a_id=a->id;
347     way_t b_id=b->id;
348    
349     if(a_id<b_id)
350     return(-1);
351     else if(a_id>b_id)
352     return(1);
353     else
354     return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
355     }
356    
357    
358     /*++++++++++++++++++++++++++++++++++++++
359 amb 1348 Discard duplicate ways and create and index of ids.
360 amb 1160
361     int deduplicate_by_id Return 1 if the value is to be kept, otherwise 0.
362    
363     WayX *wayx The extended way.
364    
365     index_t index The number of sorted ways that have already been written to the output file.
366     ++++++++++++++++++++++++++++++++++++++*/
367    
368 amb 1348 static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
369 amb 1160 {
370     static way_t previd=NO_WAY_ID;
371    
372     if(wayx->id!=previd)
373     {
374     previd=wayx->id;
375    
376     if(wayx->way.type==WAY_DELETED)
377     return(0);
378     else
379 amb 1348 {
380     sortwaysx->idata[index]=wayx->id;
381    
382 amb 1160 return(1);
383 amb 1348 }
384 amb 1160 }
385     else
386     return(0);
387     }
388    
389    
390     /*++++++++++++++++++++++++++++++++++++++
391 amb 1348 Split the ways into segments and way names.
392 amb 1129
393     WaysX *waysx The set of ways to process.
394 amb 1136
395 amb 1349 NodesX *nodesx The set of nodes to use.
396    
397 amb 1167 int keep If set to 1 then keep the old data file otherwise delete it.
398 amb 1129 ++++++++++++++++++++++++++++++++++++++*/
399    
400 amb 1349 SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep)
401 amb 1129 {
402 amb 1339 SegmentsX *segmentsx;
403 amb 1129 index_t i;
404 amb 1348 int fd,nfd;
405 amb 1339 char *name=NULL;
406     int namelen=0;
407 amb 110
408 amb 266 /* Print the start message */
409    
410 amb 1348 printf_first("Splitting Ways: Ways=0 Segments=0");
411 amb 110
412 amb 1339 segmentsx=NewSegmentList();
413    
414 amb 555 /* Re-open the file read-only and a new file writeable */
415    
416 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
417 amb 216
418 amb 1167 if(keep)
419 amb 1136 RenameFile(waysx->filename_tmp,waysx->filename);
420     else
421     DeleteFile(waysx->filename_tmp);
422 amb 262
423 amb 1317 waysx->knumber=waysx->number;
424    
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     while(!ReadFile(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID)
443     {
444 amb 1349 index=IndexNodeX(nodesx,node);
445    
446     if(prevnode==node)
447     {
448     logerror("Way %"Pway_t" contains node %"Pnode_t" that is connected to itself.\n",logerror_way(wayx.id),logerror_node(node));
449     }
450     else if(index==NO_NODE)
451     {
452     logerror("Way %"Pway_t" contains node %"Pnode_t" that does not exist in the Routino database.\n",logerror_way(wayx.id),logerror_node(node));
453     }
454     else if(previndex==NO_NODE)
455 amb 1347 ;
456     else
457 amb 1339 {
458     distance_t segment_flags=0;
459    
460     if(wayx.way.type&Highway_OneWay)
461     segment_flags|=ONEWAY_1TO2;
462    
463     if(wayx.way.type&Highway_Area)
464     segment_flags|=SEGMENT_AREA;
465    
466 amb 1349 AppendSegmentList(segmentsx,i,previndex,index,segment_flags);
467 amb 1339 }
468    
469     prevnode=node;
470 amb 1349 previndex=index;
471 amb 1339
472     size-=sizeof(node_t);
473     }
474    
475 amb 1348 size-=sizeof(node_t)+sizeof(WayX);
476 amb 1339
477     if(namelen<size)
478     name=(char*)realloc((void*)name,namelen=size);
479    
480 amb 1348 ReadFile(waysx->fd,name,size);
481 amb 1339
482     WriteFile(fd,&wayx,sizeof(WayX));
483    
484 amb 1348 size+=sizeof(index_t);
485    
486     WriteFile(nfd,&size,FILESORT_VARSIZE);
487     WriteFile(nfd,&i,sizeof(index_t));
488     WriteFile(nfd,name,size-sizeof(index_t));
489    
490 amb 1339 if(!((i+1)%1000))
491 amb 1348 printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number);
492 amb 1339 }
493    
494     FinishSegmentList(segmentsx);
495    
496     if(name) free(name);
497    
498     /* Close the files */
499    
500     waysx->fd=CloseFile(waysx->fd);
501     CloseFile(fd);
502    
503 amb 1348 close(nfd);
504    
505 amb 1339 /* Print the final message */
506    
507 amb 1348 printf_last("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number);
508 amb 1339
509     return(segmentsx);
510     }
511    
512    
513    
514     /*++++++++++++++++++++++++++++++++++++++
515 amb 1348 Sort the way names and assign the offsets to the ways.
516 amb 1339
517     WaysX *waysx The set of ways to process.
518     ++++++++++++++++++++++++++++++++++++++*/
519    
520 amb 1348 void SortWayNames(WaysX *waysx)
521 amb 1339 {
522     index_t i;
523 amb 1348 int nfd;
524 amb 1339 char *names[2]={NULL,NULL};
525     int namelen[2]={0,0};
526     int nnames=0;
527     uint32_t lastlength=0;
528    
529     /* Print the start message */
530    
531 amb 1348 printf_first("Sorting Way Names");
532 amb 1339
533 amb 1348 /* Re-open the file read-only and new file writeable */
534 amb 1339
535 amb 1348 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
536 amb 1339
537 amb 1348 DeleteFile(waysx->nfilename_tmp);
538 amb 1339
539 amb 1348 nfd=OpenFileNew(waysx->nfilename_tmp);
540 amb 1339
541 amb 1348 /* Sort the way names */
542 amb 310
543 amb 1348 waysx->nlength=0;
544 amb 310
545 amb 1348 filesort_vary(waysx->nfd,nfd,NULL,
546     (int (*)(const void*,const void*))sort_by_name,
547     NULL);
548    
549 amb 310 /* Close the files */
550    
551 amb 1348 waysx->nfd=CloseFile(waysx->nfd);
552     CloseFile(nfd);
553 amb 310
554     /* Print the final message */
555    
556 amb 1348 printf_last("Sorted Way Names: Ways=%"Pindex_t,waysx->number);
557 amb 310
558    
559 amb 1348 #if !SLIM
560     waysx->data=MapFileWriteable(waysx->filename_tmp);
561     #else
562     waysx->fd=ReOpenFileWriteable(waysx->filename_tmp);
563     #endif
564    
565 amb 310 /* Print the start message */
566    
567 amb 1348 printf_first("Updating Ways with Names: Ways=0 Names=0");
568 amb 310
569 amb 1348 /* Re-open the file read-only and new file writeable */
570 amb 310
571 amb 1348 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
572 amb 310
573 amb 1348 DeleteFile(waysx->nfilename_tmp);
574 amb 262
575 amb 1348 nfd=OpenFileNew(waysx->nfilename_tmp);
576 amb 272
577 amb 499 /* Copy from the single file into two files */
578 amb 310
579 amb 650 for(i=0;i<waysx->number;i++)
580 amb 310 {
581 amb 1348 WayX *wayx;
582     index_t index;
583 amb 311 FILESORT_VARINT size;
584 amb 310
585 amb 1348 ReadFile(waysx->nfd,&size,FILESORT_VARSIZE);
586 amb 310
587     if(namelen[nnames%2]<size)
588     names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
589    
590 amb 1348 ReadFile(waysx->nfd,&index,sizeof(index_t));
591     ReadFile(waysx->nfd,names[nnames%2],size-sizeof(index_t));
592 amb 310
593     if(nnames==0 || strcmp(names[0],names[1]))
594     {
595 amb 1348 WriteFile(nfd,names[nnames%2],size-sizeof(index_t));
596 amb 310
597     lastlength=waysx->nlength;
598 amb 1348 waysx->nlength+=size-sizeof(index_t);
599 amb 310
600     nnames++;
601     }
602    
603 amb 1348 wayx=LookupWayX(waysx,index,1);
604 amb 310
605 amb 1348 wayx->way.name=lastlength;
606 amb 310
607 amb 1348 PutBackWayX(waysx,wayx);
608    
609 amb 757 if(!((i+1)%1000))
610 amb 1348 printf_middle("Updating Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames);
611 amb 310 }
612    
613     if(names[0]) free(names[0]);
614     if(names[1]) free(names[1]);
615    
616     /* Close the files */
617    
618 amb 612 waysx->nfd=CloseFile(waysx->nfd);
619 amb 1348 CloseFile(nfd);
620 amb 310
621     /* Print the final message */
622    
623 amb 1348 printf_last("Updated Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames);
624 amb 310
625    
626 amb 1348 /* Unmap from memory / close the files */
627 amb 310
628 amb 1348 #if !SLIM
629     waysx->data=UnmapFile(waysx->data);
630     #else
631 amb 612 waysx->fd=CloseFile(waysx->fd);
632 amb 1348 #endif
633 amb 499 }
634    
635    
636     /*++++++++++++++++++++++++++++++++++++++
637 amb 1348 Sort the ways into name order.
638 amb 1160
639     int sort_by_name Returns the comparison of the name fields.
640    
641 amb 1348 char *a The first way name.
642 amb 1160
643 amb 1348 char *b The second way name.
644 amb 1160 ++++++++++++++++++++++++++++++++++++++*/
645    
646 amb 1348 static int sort_by_name(char *a,char *b)
647 amb 1160 {
648     int compare;
649 amb 1348 char *a_name=a+sizeof(index_t);
650     char *b_name=b+sizeof(index_t);
651 amb 1160
652     compare=strcmp(a_name,b_name);
653    
654     if(compare)
655     return(compare);
656     else
657     return(FILESORT_PRESERVE_ORDER(a,b));
658     }
659    
660    
661     /*++++++++++++++++++++++++++++++++++++++
662 amb 1100 Compact the way list, removing duplicated ways and unused ways.
663 amb 499
664 amb 1100 WaysX *waysx The set of ways to process.
665 amb 1092
666 amb 1100 SegmentsX *segmentsx The set of segments to check.
667 amb 499 ++++++++++++++++++++++++++++++++++++++*/
668    
669 amb 1100 void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
670 amb 499 {
671 amb 1100 int fd;
672     index_t cnumber;
673 amb 499
674 amb 1208 if(waysx->number==0)
675     return;
676    
677 amb 499 /* Print the start message */
678    
679 amb 1094 printf_first("Sorting Ways and Compacting");
680 amb 1092
681 amb 1093 /* Allocate the array of indexes */
682 amb 499
683 amb 1093 waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t));
684 amb 499
685 amb 1166 logassert(waysx->cdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
686 amb 499
687 amb 1100 /* Re-open the file read-only and a new file writeable */
688 amb 499
689 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
690 amb 1093
691 amb 1120 DeleteFile(waysx->filename_tmp);
692 amb 1100
693 amb 1120 fd=OpenFileNew(waysx->filename_tmp);
694 amb 1100
695 amb 1094 /* Sort the ways to allow compacting according to the properties */
696 amb 499
697 amb 1094 sortwaysx=waysx;
698 amb 1100 sortsegmentsx=segmentsx;
699 amb 499
700 amb 1114 cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused,
701 amb 1106 (int (*)(const void*,const void*))sort_by_name_and_prop_and_id,
702     (int (*)(void*,index_t))deduplicate_and_index_by_compact_id);
703 amb 499
704 amb 1100 /* Close the files */
705 amb 499
706 amb 1094 waysx->fd=CloseFile(waysx->fd);
707 amb 1100 CloseFile(fd);
708 amb 499
709     /* Print the final message */
710    
711 amb 1100 printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber);
712     waysx->number=cnumber;
713 amb 499
714 amb 1100 free(segmentsx->usedway);
715     segmentsx->usedway=NULL;
716 amb 224 }
717    
718    
719     /*++++++++++++++++++++++++++++++++++++++
720 amb 1160 Delete the ways that are no longer being used.
721 amb 224
722 amb 1160 int delete_unused Return 1 if the value is to be kept, otherwise 0.
723 amb 262
724 amb 1160 WayX *wayx The extended way.
725 amb 262
726 amb 1160 index_t index The number of unsorted ways that have been read from the input file.
727 amb 262 ++++++++++++++++++++++++++++++++++++++*/
728    
729 amb 1160 static int delete_unused(WayX *wayx,index_t index)
730 amb 262 {
731 amb 1160 if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index))
732     {
733     sortwaysx->cdata[index]=NO_WAY;
734 amb 262
735 amb 1160 return(0);
736     }
737 amb 262 else
738 amb 1160 {
739     wayx->id=index;
740 amb 262
741 amb 1160 return(1);
742     }
743 amb 499 }
744    
745    
746     /*++++++++++++++++++++++++++++++++++++++
747     Sort the ways into name, properties and id order.
748    
749     int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
750    
751     WayX *a The first extended Way.
752    
753     WayX *b The second extended Way.
754     ++++++++++++++++++++++++++++++++++++++*/
755    
756     static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
757     {
758     int compare;
759     index_t a_name=a->way.name;
760     index_t b_name=b->way.name;
761    
762     if(a_name<b_name)
763     return(-1);
764     else if(a_name>b_name)
765     return(1);
766    
767 amb 310 compare=WaysCompare(&a->way,&b->way);
768    
769     if(compare)
770     return(compare);
771    
772     return(sort_by_id(a,b));
773     }
774    
775    
776     /*++++++++++++++++++++++++++++++++++++++
777 amb 1113 Create the index of compacted Way identifiers and ignore Ways with duplicated properties.
778    
779     int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0.
780    
781     WayX *wayx The extended way.
782    
783     index_t index The number of sorted ways that have already been written to the output file.
784     ++++++++++++++++++++++++++++++++++++++*/
785    
786     static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
787     {
788     static Way lastway;
789    
790 amb 1100 if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
791 amb 1094 {
792 amb 1100 lastway=wayx->way;
793 amb 1094
794 amb 1100 sortwaysx->cdata[wayx->id]=index;
795 amb 1094
796 amb 1100 wayx->id=index;
797    
798     return(1);
799 amb 1094 }
800 amb 1100 else
801     {
802     sortwaysx->cdata[wayx->id]=index-1;
803 amb 1094
804 amb 1100 return(0);
805     }
806 amb 1094 }
807    
808    
809     /*++++++++++++++++++++++++++++++++++++++
810 amb 285 Save the way list to a file.
811    
812 amb 682 WaysX *waysx The set of ways to save.
813 amb 285
814     const char *filename The name of the file to save.
815     ++++++++++++++++++++++++++++++++++++++*/
816    
817 amb 682 void SaveWayList(WaysX *waysx,const char *filename)
818 amb 285 {
819     index_t i;
820 amb 555 int fd;
821 amb 1302 index_t position=0;
822 amb 1104 WayX wayx;
823 amb 499 WaysFile waysfile={0};
824 amb 529 highways_t highways=0;
825     transports_t allow=0;
826 amb 530 properties_t props=0;
827 amb 285
828 amb 461 /* Print the start message */
829    
830 amb 519 printf_first("Writing Ways: Ways=0");
831 amb 285
832 amb 1104 /* Re-open the files */
833 amb 461
834 amb 1120 waysx->fd=ReOpenFile(waysx->filename_tmp);
835     waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
836 amb 285
837 amb 461 /* Write out the ways data */
838 amb 285
839 amb 502 fd=OpenFileNew(filename);
840 amb 285
841 amb 461 SeekFile(fd,sizeof(WaysFile));
842 amb 285
843     for(i=0;i<waysx->number;i++)
844     {
845 amb 1104 ReadFile(waysx->fd,&wayx,sizeof(WayX));
846 amb 285
847 amb 1104 highways|=HIGHWAYS(wayx.way.type);
848     allow |=wayx.way.allow;
849     props |=wayx.way.props;
850 amb 398
851 amb 1104 WriteFile(fd,&wayx.way,sizeof(Way));
852 amb 309
853 amb 757 if(!((i+1)%1000))
854 amb 790 printf_middle("Writing Ways: Ways=%"Pindex_t,i+1);
855 amb 285 }
856    
857 amb 461 /* Write out the ways names */
858 amb 285
859 amb 1100 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
860 amb 461
861 amb 309 while(position<waysx->nlength)
862     {
863 amb 1302 size_t len=1024;
864 amb 309 char temp[1024];
865    
866     if((waysx->nlength-position)<1024)
867     len=waysx->nlength-position;
868    
869 amb 555 ReadFile(waysx->nfd,temp,len);
870 amb 1104
871 amb 309 WriteFile(fd,temp,len);
872    
873     position+=len;
874     }
875    
876 amb 1104 /* Close the files */
877 amb 309
878 amb 1104 waysx->fd=CloseFile(waysx->fd);
879 amb 612 waysx->nfd=CloseFile(waysx->nfd);
880 amb 555
881 amb 461 /* Write out the header structure */
882    
883 amb 1100 waysfile.number =waysx->number;
884 amb 461
885 amb 526 waysfile.highways=highways;
886     waysfile.allow =allow;
887     waysfile.props =props;
888 amb 461
889     SeekFile(fd,0);
890     WriteFile(fd,&waysfile,sizeof(WaysFile));
891    
892 amb 285 CloseFile(fd);
893    
894 amb 461 /* Print the final message */
895    
896 amb 1100 printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number);
897 amb 285 }

Properties

Name Value
cvs:description Extended ways functions.