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 500 - (hide annotations) (download) (as text)
Fri Sep 17 18:39:28 2010 UTC (14 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 19524 byte(s)
Zero the NodesFile and SegmentsFile data structures before writing them (zeros
unused bytes).

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

Properties

Name Value
cvs:description Extended nodes functions.