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 1405 - (hide annotations) (download) (as text)
Thu Jun 20 18:36:47 2013 UTC (11 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 20830 byte(s)
Use the new functions for buffering while reading when looping through files
that use the FILESORT_VARINT method of storing data.

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

Properties

Name Value
cvs:description Extended ways functions.