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 466 - (hide annotations) (download) (as text)
Sat Jul 31 14:56:17 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 19549 byte(s)
Assert if the number of nodes, segments or ways exceeds the legal range of the
index counters.

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

Properties

Name Value
cvs:description Extended nodes functions.