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/nodesx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 331 - (hide annotations) (download) (as text)
Sat Mar 20 13:35:15 2010 UTC (15 years ago) by amb
File MIME type: text/x-csrc
File size: 20716 byte(s)
Move the stat() calls to find a file size into a helper function in files.c.

1 amb 110 /***************************************
2 amb 331 $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.55 2010-03-20 13:35:15 amb Exp $
3 amb 110
4     Extented Node data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 326 This file Copyright 2008-2010 Andrew M. Bishop
9 amb 110
10 amb 151 This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU Affero General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU Affero General Public License for more details.
19    
20     You should have received a copy of the GNU Affero General Public License
21     along with this program. If not, see <http://www.gnu.org/licenses/>.
22 amb 110 ***************************************/
23    
24    
25     #include <assert.h>
26     #include <stdlib.h>
27     #include <stdio.h>
28 amb 249 #include <string.h>
29 amb 326 #include <sys/stat.h>
30 amb 110
31     #include "types.h"
32     #include "functions.h"
33     #include "nodesx.h"
34     #include "segmentsx.h"
35 amb 204 #include "waysx.h"
36 amb 228 #include "segments.h"
37     #include "nodes.h"
38 amb 110
39    
40 amb 252 /* Variables */
41 amb 110
42 amb 289 /*+ The command line '--slim' option. +*/
43 amb 252 extern int option_slim;
44 amb 289
45     /*+ The command line '--tmpdir' option or its default value. +*/
46 amb 284 extern char *option_tmpdirname;
47 amb 110
48 amb 284 /*+ A temporary file-local variable for use by the sort functions. +*/
49     static NodesX *sortnodesx;
50    
51 amb 110 /* Functions */
52    
53 amb 271 static int sort_by_id(NodeX *a,NodeX *b);
54 amb 273 static int index_by_id(NodeX *nodex,index_t index);
55 amb 271
56 amb 281 static int sort_by_lat_long(NodeX *a,NodeX *b);
57     static int index_by_lat_long(NodeX *nodex,index_t index);
58 amb 110
59    
60     /*++++++++++++++++++++++++++++++++++++++
61 amb 326 Allocate a new node list (create a new file or open an existing one).
62 amb 110
63     NodesX *NewNodeList Returns the node list.
64 amb 326
65     int append Set to 1 if the file is to be opened for appending (now or later).
66 amb 110 ++++++++++++++++++++++++++++++++++++++*/
67    
68 amb 326 NodesX *NewNodeList(int append)
69 amb 110 {
70     NodesX *nodesx;
71    
72 amb 213 nodesx=(NodesX*)calloc(1,sizeof(NodesX));
73 amb 110
74 amb 243 assert(nodesx); /* Check calloc() worked */
75    
76 amb 284 nodesx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
77 amb 216
78 amb 326 if(append)
79     sprintf(nodesx->filename,"%s/nodes.input.tmp",option_tmpdirname);
80     else
81     sprintf(nodesx->filename,"%s/nodes.%p.tmp",option_tmpdirname,nodesx);
82 amb 249
83 amb 326 if(append)
84     {
85 amb 331 off_t size;
86 amb 326
87     nodesx->fd=AppendFile(nodesx->filename);
88    
89 amb 331 size=SizeFile(nodesx->filename);
90 amb 326
91 amb 331 nodesx->xnumber=size/sizeof(NodeX);
92 amb 326 }
93     else
94     nodesx->fd=OpenFile(nodesx->filename);
95    
96 amb 110 return(nodesx);
97     }
98    
99    
100     /*++++++++++++++++++++++++++++++++++++++
101 amb 226 Free a node list.
102    
103     NodesX *nodesx The list to be freed.
104 amb 326
105     int keep Set to 1 if the file is to be kept.
106 amb 226 ++++++++++++++++++++++++++++++++++++++*/
107    
108 amb 326 void FreeNodeList(NodesX *nodesx,int keep)
109 amb 226 {
110 amb 326 if(!keep)
111     DeleteFile(nodesx->filename);
112    
113 amb 283 free(nodesx->filename);
114 amb 226
115     if(nodesx->idata)
116     free(nodesx->idata);
117    
118     if(nodesx->ndata)
119     free(nodesx->ndata);
120    
121 amb 283 if(nodesx->super)
122     free(nodesx->super);
123    
124 amb 257 if(nodesx->offsets)
125     free(nodesx->offsets);
126    
127 amb 226 free(nodesx);
128     }
129    
130    
131     /*++++++++++++++++++++++++++++++++++++++
132 amb 252 Append a node to a newly created node list (unsorted).
133 amb 243
134 amb 252 NodesX* nodesx The set of nodes to process.
135 amb 243
136 amb 252 node_t id The node identification.
137 amb 110
138 amb 252 double latitude The latitude of the node.
139 amb 110
140 amb 252 double longitude The longitude of the node.
141     ++++++++++++++++++++++++++++++++++++++*/
142 amb 110
143 amb 252 void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude)
144     {
145     NodeX nodex;
146 amb 249
147 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
148    
149     nodex.id=id;
150     nodex.latitude =radians_to_latlong(latitude);
151     nodex.longitude=radians_to_latlong(longitude);
152    
153     WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
154    
155     nodesx->xnumber++;
156 amb 110 }
157    
158    
159     /*++++++++++++++++++++++++++++++++++++++
160 amb 263 Sort the node list (i.e. create the sortable indexes).
161 amb 110
162     NodesX* nodesx The set of nodes to process.
163     ++++++++++++++++++++++++++++++++++++++*/
164    
165 amb 263 void SortNodeList(NodesX* nodesx)
166 amb 110 {
167 amb 263 int fd;
168 amb 110
169 amb 263 /* Check the start conditions */
170    
171 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
172    
173 amb 263 /* Print the start message */
174    
175     printf("Sorting Nodes");
176 amb 227 fflush(stdout);
177 amb 132
178 amb 263 /* Close the files and re-open them (finished appending) */
179 amb 260
180     CloseFile(nodesx->fd);
181     nodesx->fd=ReOpenFile(nodesx->filename);
182    
183 amb 271 DeleteFile(nodesx->filename);
184    
185     fd=OpenFile(nodesx->filename);
186    
187 amb 252 /* Allocate the array of indexes */
188 amb 249
189 amb 252 nodesx->idata=(node_t*)malloc(nodesx->xnumber*sizeof(node_t));
190 amb 249
191 amb 252 assert(nodesx->idata); /* Check malloc() worked */
192 amb 249
193 amb 271 /* Sort by node indexes */
194 amb 249
195 amb 271 sortnodesx=nodesx;
196 amb 110
197 amb 311 filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))index_by_id);
198 amb 252
199 amb 260 /* Close the files and re-open them */
200    
201 amb 257 CloseFile(nodesx->fd);
202     CloseFile(fd);
203 amb 252
204 amb 257 nodesx->fd=ReOpenFile(nodesx->filename);
205 amb 252
206 amb 263 /* Print the final message */
207    
208 amb 273 printf("\rSorted Nodes: Nodes=%d Duplicates=%d\n",nodesx->xnumber,nodesx->xnumber-nodesx->number);
209 amb 263 fflush(stdout);
210 amb 110 }
211    
212    
213     /*++++++++++++++++++++++++++++++++++++++
214     Sort the nodes into id order.
215    
216     int sort_by_id Returns the comparison of the id fields.
217    
218 amb 271 NodeX *a The first extended node.
219 amb 110
220 amb 271 NodeX *b The second extended node.
221 amb 110 ++++++++++++++++++++++++++++++++++++++*/
222    
223 amb 271 static int sort_by_id(NodeX *a,NodeX *b)
224 amb 110 {
225 amb 271 node_t a_id=a->id;
226     node_t b_id=b->id;
227 amb 252
228     if(a_id<b_id)
229     return(-1);
230     else if(a_id>b_id)
231 amb 249 return(1);
232 amb 110 else
233 amb 252 return(0);
234 amb 110 }
235    
236    
237 amb 271 /*++++++++++++++++++++++++++++++++++++++
238     Index the nodes after sorting.
239 amb 252
240 amb 289 int index_by_id Return 1 if the value is to be kept, otherwise zero.
241 amb 273
242 amb 271 NodeX *nodex The extended node.
243 amb 252
244 amb 271 index_t index The index of this node in the total.
245     ++++++++++++++++++++++++++++++++++++++*/
246    
247 amb 273 static int index_by_id(NodeX *nodex,index_t index)
248 amb 271 {
249 amb 273 if(index==0 || sortnodesx->idata[index-1]!=nodex->id)
250     {
251     sortnodesx->idata[index]=nodex->id;
252 amb 271
253 amb 273 sortnodesx->number++;
254    
255     return(1);
256     }
257    
258     return(0);
259 amb 271 }
260    
261    
262 amb 110 /*++++++++++++++++++++++++++++++++++++++
263 amb 212 Sort the node list geographically.
264    
265     NodesX* nodesx The set of nodes to process.
266     ++++++++++++++++++++++++++++++++++++++*/
267    
268     void SortNodeListGeographically(NodesX* nodesx)
269     {
270 amb 281 int fd;
271 amb 212
272 amb 263 /* Print the start message */
273    
274 amb 227 printf("Sorting Nodes Geographically");
275     fflush(stdout);
276 amb 212
277 amb 281 /* Allocate the memory for the geographical offsets array */
278 amb 275
279 amb 281 nodesx->offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
280 amb 275
281 amb 281 nodesx->latlonbin=0;
282 amb 212
283 amb 281 /* Close the files and re-open them */
284 amb 212
285 amb 281 CloseFile(nodesx->fd);
286     nodesx->fd=ReOpenFile(nodesx->filename);
287 amb 243
288 amb 281 DeleteFile(nodesx->filename);
289 amb 212
290 amb 281 fd=OpenFile(nodesx->filename);
291 amb 212
292 amb 281 /* Sort geographically */
293 amb 252
294 amb 281 sortnodesx=nodesx;
295 amb 257
296 amb 311 filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_lat_long,(int (*)(void*,index_t))index_by_lat_long);
297 amb 257
298 amb 281 /* Close the files and re-open them */
299 amb 257
300 amb 281 CloseFile(nodesx->fd);
301     CloseFile(fd);
302 amb 257
303 amb 281 nodesx->fd=ReOpenFile(nodesx->filename);
304 amb 257
305 amb 281 /* Finish off the indexing */
306 amb 257
307 amb 281 for(;nodesx->latlonbin<=(nodesx->latbins*nodesx->lonbins);nodesx->latlonbin++)
308     nodesx->offsets[nodesx->latlonbin]=nodesx->number;
309 amb 257
310 amb 263 /* Print the final message */
311 amb 257
312 amb 227 printf("\rSorted Nodes Geographically \n");
313     fflush(stdout);
314 amb 212 }
315    
316    
317     /*++++++++++++++++++++++++++++++++++++++
318 amb 110 Sort the nodes into latitude and longitude order.
319    
320     int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
321    
322 amb 281 NodeX *a The first extended node.
323 amb 110
324 amb 281 NodeX *b The second extended node.
325 amb 110 ++++++++++++++++++++++++++++++++++++++*/
326    
327 amb 281 static int sort_by_lat_long(NodeX *a,NodeX *b)
328 amb 110 {
329 amb 281 ll_bin_t a_lon=latlong_to_bin(a->longitude);
330     ll_bin_t b_lon=latlong_to_bin(b->longitude);
331 amb 110
332     if(a_lon<b_lon)
333     return(-1);
334     else if(a_lon>b_lon)
335     return(1);
336     else
337     {
338 amb 281 ll_bin_t a_lat=latlong_to_bin(a->latitude);
339     ll_bin_t b_lat=latlong_to_bin(b->latitude);
340 amb 110
341     if(a_lat<b_lat)
342     return(-1);
343     else if(a_lat>b_lat)
344     return(1);
345     else
346 amb 281 {
347     #ifdef REGRESSION_TESTING
348     // Need this for regression testing because heapsort() is not order
349     // preserving like qsort() is (or was when tested).
350    
351     index_t a_id=a->id;
352     index_t b_id=b->id;
353    
354     if(a_id<b_id)
355     return(-1);
356     else if(a_id>b_id)
357     return(1);
358     else
359     #endif
360     return(0);
361     }
362 amb 110 }
363     }
364    
365    
366     /*++++++++++++++++++++++++++++++++++++++
367 amb 281 Index the nodes after sorting.
368    
369 amb 289 int index_by_lat_long Return 1 if the value is to be kept, otherwise zero.
370 amb 281
371     NodeX *nodex The extended node.
372    
373     index_t index The index of this node in the total.
374     ++++++++++++++++++++++++++++++++++++++*/
375    
376     static int index_by_lat_long(NodeX *nodex,index_t index)
377     {
378     /* Work out the offsets */
379    
380     ll_bin_t latbin=latlong_to_bin(nodex->latitude )-sortnodesx->latzero;
381     ll_bin_t lonbin=latlong_to_bin(nodex->longitude)-sortnodesx->lonzero;
382     int llbin=lonbin*sortnodesx->latbins+latbin;
383    
384     for(;sortnodesx->latlonbin<=llbin;sortnodesx->latlonbin++)
385     sortnodesx->offsets[sortnodesx->latlonbin]=index;
386    
387     return(1);
388     }
389    
390    
391     /*++++++++++++++++++++++++++++++++++++++
392 amb 285 Find a particular node index.
393    
394     index_t IndexNodeX Returns the index of the extended node with the specified id.
395    
396     NodesX* nodesx The set of nodes to process.
397    
398     node_t id The node id to look for.
399     ++++++++++++++++++++++++++++++++++++++*/
400    
401     index_t IndexNodeX(NodesX* nodesx,node_t id)
402     {
403     int start=0;
404     int end=nodesx->number-1;
405     int mid;
406    
407     assert(nodesx->idata); /* Must have idata filled in => sorted by id */
408    
409     /* Binary search - search key exact match only is required.
410     *
411     * # <- start | Check mid and move start or end if it doesn't match
412     * # |
413     * # | Since an exact match is wanted we can set end=mid-1
414     * # <- mid | or start=mid+1 because we know that mid doesn't match.
415     * # |
416     * # | Eventually either end=start or end=start+1 and one of
417     * # <- end | start or end is the wanted one.
418     */
419    
420     if(end<start) /* There are no nodes */
421     return(NO_NODE);
422     else if(id<nodesx->idata[start]) /* Check key is not before start */
423     return(NO_NODE);
424     else if(id>nodesx->idata[end]) /* Check key is not after end */
425     return(NO_NODE);
426     else
427     {
428     do
429     {
430     mid=(start+end)/2; /* Choose mid point */
431    
432     if(nodesx->idata[mid]<id) /* Mid point is too low */
433     start=mid+1;
434     else if(nodesx->idata[mid]>id) /* Mid point is too high */
435     end=mid-1;
436     else /* Mid point is correct */
437     return(mid);
438     }
439     while((end-start)>1);
440    
441     if(nodesx->idata[start]==id) /* Start is correct */
442     return(start);
443    
444     if(nodesx->idata[end]==id) /* End is correct */
445     return(end);
446     }
447    
448     return(NO_NODE);
449     }
450    
451    
452     /*++++++++++++++++++++++++++++++++++++++
453     Lookup a particular node.
454    
455     NodeX *LookupNodeX Returns a pointer to the extended node with the specified id.
456    
457     NodesX* nodesx The set of nodes to process.
458    
459     index_t index The node index to look for.
460    
461     int position The position in the cache to use.
462     ++++++++++++++++++++++++++++++++++++++*/
463    
464     NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position)
465     {
466     assert(index!=NO_NODE); /* Must be a valid node */
467    
468     if(option_slim)
469     {
470     SeekFile(nodesx->fd,index*sizeof(NodeX));
471    
472     ReadFile(nodesx->fd,&nodesx->cached[position-1],sizeof(NodeX));
473    
474     return(&nodesx->cached[position-1]);
475     }
476     else
477     {
478     return(&nodesx->xdata[index]);
479     }
480     }
481    
482    
483     /*++++++++++++++++++++++++++++++++++++++
484 amb 110 Remove any nodes that are not part of a highway.
485    
486     NodesX *nodesx The complete node list.
487    
488     SegmentsX *segmentsx The list of segments.
489     ++++++++++++++++++++++++++++++++++++++*/
490    
491     void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx)
492     {
493 amb 263 NodeX nodex;
494 amb 273 int total=0,highway=0,nothighway=0;
495 amb 281 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
496     latlong_t lat_min,lat_max,lon_min,lon_max;
497 amb 263 int fd;
498 amb 110
499 amb 263 /* Check the start conditions */
500    
501 amb 249 assert(nodesx->idata); /* Must have idata filled in => data sorted */
502 amb 213
503 amb 263 /* Print the start message */
504    
505 amb 227 printf("Checking: Nodes=0");
506     fflush(stdout);
507    
508 amb 281 /* While we are here we can work out the range of data */
509    
510     lat_min=radians_to_latlong( 2);
511     lat_max=radians_to_latlong(-2);
512     lon_min=radians_to_latlong( 4);
513     lon_max=radians_to_latlong(-4);
514    
515 amb 263 /* Modify the on-disk image */
516    
517     DeleteFile(nodesx->filename);
518    
519     fd=OpenFile(nodesx->filename);
520     SeekFile(nodesx->fd,0);
521    
522     while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
523 amb 110 {
524 amb 275 if(IndexFirstSegmentX(segmentsx,nodex.id)==NO_SEGMENT)
525 amb 271 nothighway++;
526     else
527 amb 263 {
528 amb 280 nodex.id=highway;
529    
530 amb 263 WriteFile(fd,&nodex,sizeof(NodeX));
531    
532     nodesx->idata[highway]=nodesx->idata[total];
533 amb 110 highway++;
534 amb 281
535     if(nodex.latitude<lat_min)
536     lat_min=nodex.latitude;
537     if(nodex.latitude>lat_max)
538     lat_max=nodex.latitude;
539     if(nodex.longitude<lon_min)
540     lon_min=nodex.longitude;
541     if(nodex.longitude>lon_max)
542     lon_max=nodex.longitude;
543 amb 263 }
544 amb 110
545 amb 263 total++;
546    
547     if(!(total%10000))
548 amb 110 {
549 amb 273 printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",total,highway,nothighway);
550 amb 110 fflush(stdout);
551     }
552     }
553    
554 amb 263 /* Close the files and re-open them */
555    
556     CloseFile(nodesx->fd);
557     CloseFile(fd);
558    
559     nodesx->fd=ReOpenFile(nodesx->filename);
560    
561     nodesx->number=highway;
562    
563 amb 281 /* Work out the number of bins */
564    
565     lat_min_bin=latlong_to_bin(lat_min);
566     lon_min_bin=latlong_to_bin(lon_min);
567     lat_max_bin=latlong_to_bin(lat_max);
568     lon_max_bin=latlong_to_bin(lon_max);
569    
570     nodesx->latzero=lat_min_bin;
571     nodesx->lonzero=lon_min_bin;
572    
573     nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
574     nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
575    
576 amb 263 /* Allocate and clear the super-node markers */
577    
578     nodesx->super=(uint8_t*)calloc(nodesx->number,sizeof(uint8_t));
579    
580     assert(nodesx->super); /* Check calloc() worked */
581    
582     /* Print the final message */
583    
584 amb 273 printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",total,highway,nothighway);
585 amb 110 fflush(stdout);
586     }
587    
588    
589     /*++++++++++++++++++++++++++++++++++++++
590 amb 212 Create the real node data.
591 amb 110
592 amb 212 NodesX *nodesx The set of nodes to use.
593 amb 110
594 amb 212 int iteration The final super-node iteration.
595 amb 110 ++++++++++++++++++++++++++++++++++++++*/
596    
597 amb 212 void CreateRealNodes(NodesX *nodesx,int iteration)
598 amb 110 {
599 amb 214 index_t i;
600 amb 110
601 amb 275 /* Check the start conditions */
602    
603 amb 243 assert(!nodesx->ndata); /* Must not have ndata filled in => no real nodes */
604 amb 110
605 amb 275 /* Print the start message */
606    
607 amb 227 printf("Creating Real Nodes: Nodes=0");
608     fflush(stdout);
609    
610 amb 275 /* Map into memory */
611    
612     if(!option_slim)
613     nodesx->xdata=MapFile(nodesx->filename);
614    
615 amb 212 /* Allocate the memory */
616    
617     nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node));
618    
619 amb 243 assert(nodesx->ndata); /* Check malloc() worked */
620    
621 amb 212 /* Loop through and allocate. */
622    
623 amb 110 for(i=0;i<nodesx->number;i++)
624     {
625 amb 275 NodeX *nodex=LookupNodeX(nodesx,i,1);
626 amb 208
627 amb 281 nodesx->ndata[nodex->id].latoffset=latlong_to_off(nodex->latitude);
628     nodesx->ndata[nodex->id].lonoffset=latlong_to_off(nodex->longitude);
629     nodesx->ndata[nodex->id].firstseg=SEGMENT(NO_SEGMENT);
630 amb 212
631 amb 281 if(nodesx->super[nodex->id]==iteration)
632     nodesx->ndata[nodex->id].firstseg|=NODE_SUPER;
633 amb 212
634 amb 110 if(!((i+1)%10000))
635     {
636 amb 212 printf("\rCreating Real Nodes: Nodes=%d",i+1);
637 amb 110 fflush(stdout);
638     }
639     }
640    
641 amb 280 /* Free the unneeded memory */
642    
643     free(nodesx->super);
644     nodesx->super=NULL;
645    
646 amb 275 /* Unmap from memory */
647    
648     if(!option_slim)
649     nodesx->xdata=UnmapFile(nodesx->filename);
650    
651     /* Print the final message */
652    
653 amb 212 printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number);
654 amb 110 fflush(stdout);
655     }
656    
657    
658     /*++++++++++++++++++++++++++++++++++++++
659     Assign the segment indexes to the nodes.
660    
661     NodesX *nodesx The list of nodes to process.
662    
663     SegmentsX* segmentsx The set of segments to use.
664     ++++++++++++++++++++++++++++++++++++++*/
665    
666 amb 209 void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx)
667 amb 110 {
668 amb 214 index_t i;
669 amb 110
670 amb 275 /* Check the start conditions */
671    
672 amb 243 assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
673     assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
674 amb 110
675 amb 275 /* Print the start message */
676    
677 amb 227 printf("Indexing Segments: Segments=0");
678     fflush(stdout);
679    
680 amb 275 /* Map into memory */
681    
682     if(!option_slim)
683 amb 281 {
684     nodesx->xdata=MapFile(nodesx->filename);
685 amb 275 segmentsx->xdata=MapFile(segmentsx->filename);
686 amb 281 }
687 amb 275
688 amb 110 /* Index the nodes */
689    
690     for(i=0;i<segmentsx->number;i++)
691     {
692 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
693 amb 257 node_t id1=segmentx->node1;
694     node_t id2=segmentx->node2;
695 amb 279 Node *node1=&nodesx->ndata[id1];
696     Node *node2=&nodesx->ndata[id2];
697 amb 110
698     /* Check node1 */
699    
700 amb 212 if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT))
701 amb 110 {
702 amb 212 node1->firstseg^=SEGMENT(NO_SEGMENT);
703     node1->firstseg|=i;
704 amb 110 }
705     else
706     {
707 amb 212 index_t index=SEGMENT(node1->firstseg);
708 amb 110
709     do
710     {
711 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
712 amb 256
713 amb 257 if(segmentx->node1==id1)
714 amb 110 {
715 amb 209 index++;
716 amb 128
717 amb 256 if(index>=segmentsx->number)
718 amb 209 break;
719 amb 256
720 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
721 amb 256
722 amb 257 if(segmentx->node1!=id1)
723 amb 256 break;
724 amb 110 }
725     else
726     {
727 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
728 amb 110 {
729 amb 209 segmentsx->sdata[index].next2=i;
730     break;
731 amb 110 }
732     else
733 amb 209 index=segmentsx->sdata[index].next2;
734 amb 110 }
735     }
736 amb 209 while(1);
737 amb 110 }
738    
739     /* Check node2 */
740    
741 amb 212 if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT))
742 amb 110 {
743 amb 212 node2->firstseg^=SEGMENT(NO_SEGMENT);
744     node2->firstseg|=i;
745 amb 110 }
746     else
747     {
748 amb 212 index_t index=SEGMENT(node2->firstseg);
749 amb 110
750     do
751     {
752 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
753 amb 256
754 amb 257 if(segmentx->node1==id2)
755 amb 110 {
756 amb 209 index++;
757 amb 128
758 amb 256 if(index>=segmentsx->number)
759 amb 209 break;
760 amb 256
761 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
762 amb 256
763 amb 257 if(segmentx->node1!=id2)
764 amb 256 break;
765 amb 110 }
766     else
767     {
768 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
769 amb 110 {
770 amb 209 segmentsx->sdata[index].next2=i;
771     break;
772 amb 110 }
773     else
774 amb 209 index=segmentsx->sdata[index].next2;
775 amb 110 }
776     }
777 amb 209 while(1);
778 amb 110 }
779    
780     if(!((i+1)%10000))
781     {
782     printf("\rIndexing Segments: Segments=%d",i+1);
783     fflush(stdout);
784     }
785     }
786    
787 amb 275 /* Unmap from memory */
788    
789     if(!option_slim)
790 amb 281 {
791     nodesx->xdata=UnmapFile(nodesx->filename);
792 amb 275 segmentsx->xdata=UnmapFile(segmentsx->filename);
793 amb 281 }
794 amb 275
795     /* Print the final message */
796    
797 amb 110 printf("\rIndexed Segments: Segments=%d \n",segmentsx->number);
798     fflush(stdout);
799     }
800 amb 285
801    
802     /*++++++++++++++++++++++++++++++++++++++
803     Save the node list to a file.
804    
805     NodesX* nodesx The set of nodes to save.
806    
807     const char *filename The name of the file to save.
808     ++++++++++++++++++++++++++++++++++++++*/
809    
810     void SaveNodeList(NodesX* nodesx,const char *filename)
811     {
812     index_t i;
813     int fd;
814     Nodes *nodes;
815     int super_number=0;
816    
817     /* Check the start conditions */
818    
819     assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
820    
821     /* Print the start message */
822    
823     printf("Writing Nodes: Nodes=0");
824     fflush(stdout);
825    
826     /* Map into memory */
827    
828     if(!option_slim)
829     nodesx->xdata=MapFile(nodesx->filename);
830    
831     /* Count the number of super-nodes */
832    
833     for(i=0;i<nodesx->number;i++)
834     if(nodesx->ndata[i].firstseg&NODE_SUPER)
835     super_number++;
836    
837     /* Fill in a Nodes structure with the offset of the real data in the file after
838     the Node structure itself. */
839    
840     nodes=calloc(1,sizeof(Nodes));
841    
842     assert(nodes); /* Check calloc() worked */
843    
844     nodes->number=nodesx->number;
845     nodes->snumber=super_number;
846    
847     nodes->latbins=nodesx->latbins;
848     nodes->lonbins=nodesx->lonbins;
849    
850     nodes->latzero=nodesx->latzero;
851     nodes->lonzero=nodesx->lonzero;
852    
853     nodes->data=NULL;
854    
855     nodes->offsets=(void*)sizeof(Nodes);
856     nodes->nodes=(void*)(sizeof(Nodes)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
857    
858     /* Write out the Nodes structure and then the real data. */
859    
860     fd=OpenFile(filename);
861    
862     WriteFile(fd,nodes,sizeof(Nodes));
863    
864     WriteFile(fd,nodesx->offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
865    
866     for(i=0;i<nodes->number;i++)
867     {
868     NodeX *nodex=LookupNodeX(nodesx,i,1);
869     Node *node=&nodesx->ndata[nodex->id];
870    
871     WriteFile(fd,node,sizeof(Node));
872    
873     if(!((i+1)%10000))
874     {
875     printf("\rWriting Nodes: Nodes=%d",i+1);
876     fflush(stdout);
877     }
878     }
879    
880     CloseFile(fd);
881    
882     /* Unmap from memory */
883    
884     if(!option_slim)
885     nodesx->xdata=UnmapFile(nodesx->filename);
886    
887     /* Print the final message */
888    
889     printf("\rWrote Nodes: Nodes=%d \n",nodes->number);
890     fflush(stdout);
891    
892     /* Free the fake Nodes */
893    
894     free(nodes);
895     }

Properties

Name Value
cvs:description Extended nodes functions.