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 463 - (hide annotations) (download) (as text)
Sat Jul 31 10:28:52 2010 UTC (14 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 19430 byte(s)
Remove the assert statements that check the order of calling the functions.

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

Properties

Name Value
cvs:description Extended nodes functions.