Imported Upstream version 1.5
[routino] / src / segmentsx.c
index 5a4f03b..fe6ed0f 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************
- $Header: /home/amb/routino/src/RCS/segmentsx.c,v 1.51 2010/04/28 17:27:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/segmentsx.c,v 1.68 2010/10/09 14:14:42 amb Exp $
 
  Extended Segment data type functions.
 
 #include <sys/stat.h>
 
 #include "types.h"
-#include "functions.h"
-#include "nodesx.h"
-#include "segmentsx.h"
-#include "waysx.h"
 #include "nodes.h"
 #include "segments.h"
 #include "ways.h"
 
+#include "nodesx.h"
+#include "segmentsx.h"
+#include "waysx.h"
+
+#include "types.h"
+
+#include "files.h"
+#include "functions.h"
 
-/* Variables */
 
-/*+ The command line '--slim' option. +*/
-extern int option_slim;
+/* Variables */
 
 /*+ The command line '--tmpdir' option or its default value. +*/
 extern char *option_tmpdirname;
@@ -73,22 +75,28 @@ SegmentsX *NewSegmentList(int append)
  segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
 
  if(append)
-    sprintf(segmentsx->filename,"%s/segments.input.tmp",option_tmpdirname);
+    sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
  else
-    sprintf(segmentsx->filename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
+    sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
+
+#if SLIM
+ segmentsx->sfilename=(char*)malloc(strlen(option_tmpdirname)+32);
+
+ sprintf(segmentsx->sfilename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
+#endif
 
  if(append)
    {
     off_t size;
 
-    segmentsx->fd=AppendFile(segmentsx->filename);
+    segmentsx->fd=OpenFileAppend(segmentsx->filename);
 
     size=SizeFile(segmentsx->filename);
 
     segmentsx->xnumber=size/sizeof(SegmentX);
    }
  else
-    segmentsx->fd=OpenFile(segmentsx->filename);
+    segmentsx->fd=OpenFileNew(segmentsx->filename);
 
  return(segmentsx);
 }
@@ -115,15 +123,23 @@ void FreeSegmentList(SegmentsX *segmentsx,int keep)
  if(segmentsx->firstnode)
     free(segmentsx->firstnode);
 
+#if !SLIM
  if(segmentsx->sdata)
     free(segmentsx->sdata);
+#endif
+
+#if SLIM
+ DeleteFile(segmentsx->sfilename);
+
+ free(segmentsx->sfilename);
+#endif
 
  free(segmentsx);
 }
 
 
 /*++++++++++++++++++++++++++++++++++++++
-  Append a single segment to a segment list.
+  Append a single segment to an unsorted segment list.
 
   SegmentsX* segmentsx The set of segments to process.
 
@@ -140,8 +156,6 @@ void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,dist
 {
  SegmentX segmentx;
 
- assert(!segmentsx->idata);    /* Must not have idata filled in => unsorted */
-
  segmentx.node1=node1;
  segmentx.node2=node2;
  segmentx.way=way;
@@ -150,6 +164,8 @@ void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,dist
  WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
 
  segmentsx->xnumber++;
+
+ assert(segmentsx->xnumber<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
 }
 
 
@@ -163,9 +179,8 @@ void SortSegmentList(SegmentsX* segmentsx)
 {
  int fd;
 
- /* Check the start conditions */
-
- assert(!segmentsx->idata);    /* Must not have idata filled in => unsorted */
+ if(segmentsx->xnumber==0)
+    return;
 
  /* Print the start message */
 
@@ -179,7 +194,7 @@ void SortSegmentList(SegmentsX* segmentsx)
 
  DeleteFile(segmentsx->filename);
 
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
 
  /* Sort by node indexes */
 
@@ -274,8 +289,6 @@ index_t IndexFirstSegmentX(SegmentsX* segmentsx,node_t node)
     return(index);
    }
 
- assert(segmentsx->idata);      /* Must have idata filled in => sorted by node 1 */
-
  /* Binary search - search key exact match only is required.
   *
   *  # <- start  |  Check mid and move start or end if it doesn't match
@@ -340,8 +353,6 @@ index_t IndexFirstSegmentX(SegmentsX* segmentsx,node_t node)
 
 index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeindex)
 {
- assert(segmentsx->firstnode);   /* Must have firstnode filled in => segments updated */
-
  if(++segindex==segmentsx->firstnode[nodeindex+1])
     return(NO_SEGMENT);
  else
@@ -350,37 +361,6 @@ index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeinde
  
  
 /*++++++++++++++++++++++++++++++++++++++
-  Lookup a particular segment.
-
-  SegmentX *LookupSegmentX Returns a pointer to the extended segment with the specified id.
-
-  SegmentsX* segmentsx The set of segments to process.
-
-  index_t index The segment index to look for.
-
-  int position The position in the cache to use.
-  ++++++++++++++++++++++++++++++++++++++*/
-
-SegmentX *LookupSegmentX(SegmentsX* segmentsx,index_t index,int position)
-{
- assert(index!=NO_SEGMENT);     /* Must be a valid segment */
-
- if(option_slim)
-   {
-    SeekFile(segmentsx->fd,index*sizeof(SegmentX));
-
-    ReadFile(segmentsx->fd,&segmentsx->cached[position-1],sizeof(SegmentX));
-
-    return(&segmentsx->cached[position-1]);
-   }
- else
-   {
-    return(&segmentsx->xdata[index]);
-   }
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
   Remove bad segments (duplicated, zero length or missing nodes).
 
   NodesX *nodesx The nodes to check.
@@ -410,7 +390,7 @@ void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
 
  DeleteFile(segmentsx->filename);
 
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
  SeekFile(segmentsx->fd,0);
 
  while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
@@ -481,8 +461,9 @@ void UpdateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  /* Map into memory */
 
- if(!option_slim)
-    nodesx->xdata=MapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+#endif
 
  /* Free the now-unneeded index */
 
@@ -504,7 +485,7 @@ void UpdateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  DeleteFile(segmentsx->filename);
 
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
  SeekFile(segmentsx->fd,0);
 
  while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
@@ -561,8 +542,9 @@ void UpdateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  /* Unmap from memory */
 
- if(!option_slim)
-    nodesx->xdata=UnmapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+#endif
 
  /* Print the final message */
 
@@ -583,10 +565,6 @@ void RotateSegments(SegmentsX* segmentsx)
  int fd;
  SegmentX segmentx;
 
- /* Check the start conditions */
-
- assert(!segmentsx->idata);    /* Must not have idata filled in => not sorted by node 1 */
-
  /* Print the start message */
 
  printf("Rotating Segments: Segments=0 Rotated=0");
@@ -599,7 +577,7 @@ void RotateSegments(SegmentsX* segmentsx)
 
  DeleteFile(segmentsx->filename);
 
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
 
  /* Modify the file contents */
 
@@ -668,8 +646,9 @@ void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  /* Map into memory */
 
- if(!option_slim)
-    waysx->xdata=MapFile(waysx->filename);
+#if !SLIM
+ waysx->xdata=MapFile(waysx->filename);
+#endif
 
  /* Allocate the array of indexes */
 
@@ -686,7 +665,7 @@ void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  DeleteFile(segmentsx->filename);
 
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
  SeekFile(segmentsx->fd,0);
 
  while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
@@ -764,8 +743,9 @@ void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
 
  /* Unmap from memory */
 
- if(!option_slim)
-    waysx->xdata=UnmapFile(waysx->filename);
+#if !SLIM
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
 
  /* Print the final message */
 
@@ -786,9 +766,8 @@ void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
 {
  index_t i;
 
- /* Check the start conditions */
-
- assert(!segmentsx->sdata);     /* Must not have sdata filled in => no real segments */
+ if(segmentsx->number==0 || waysx->number==0)
+    return;
 
  /* Print the start message */
 
@@ -797,35 +776,43 @@ void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
 
  /* Map into memory */
 
- if(!option_slim)
-   {
-    segmentsx->xdata=MapFile(segmentsx->filename);
-    waysx->xdata=MapFile(waysx->filename);
-   }
+#if !SLIM
+ segmentsx->xdata=MapFile(segmentsx->filename);
+ waysx->xdata=MapFile(waysx->filename);
+#endif
 
  /* Free the unneeded memory */
 
  free(segmentsx->firstnode);
  segmentsx->firstnode=NULL;
 
- /* Allocate the memory */
+ /* Allocate the memory (or open the file) */
 
+#if !SLIM
  segmentsx->sdata=(Segment*)malloc(segmentsx->number*sizeof(Segment));
 
  assert(segmentsx->sdata); /* Check malloc() worked */
+#else
+ segmentsx->sfd=OpenFileNew(segmentsx->sfilename);
+#endif
 
  /* Loop through and fill */
 
  for(i=0;i<segmentsx->number;i++)
    {
     SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
-    WayX *wayx=LookupWayX(waysx,segmentx->way,1);
+    Segment  *segment =LookupSegmentXSegment(segmentsx,i,1);
+    WayX     *wayx=LookupWayX(waysx,segmentx->way,1);
 
-    segmentsx->sdata[i].node1=0;
-    segmentsx->sdata[i].node2=0;
-    segmentsx->sdata[i].next2=NO_NODE;
-    segmentsx->sdata[i].way=wayx->prop;
-    segmentsx->sdata[i].distance=segmentx->distance;
+    segment->node1=0;
+    segment->node2=0;
+    segment->next2=NO_NODE;
+    segment->way=wayx->prop;
+    segment->distance=segmentx->distance;
+
+#if SLIM
+    PutBackSegmentXSegment(segmentsx,i,1);
+#endif
 
     if(!((i+1)%10000))
       {
@@ -836,11 +823,10 @@ void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
 
  /* Unmap from memory */
 
- if(!option_slim)
-   {
-    segmentsx->xdata=UnmapFile(segmentsx->filename);
-    waysx->xdata=UnmapFile(waysx->filename);
-   }
+#if !SLIM
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
 
  /* Print the final message */
 
@@ -861,10 +847,8 @@ void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
 {
  index_t i;
 
- /* Check the start conditions */
-
- assert(nodesx->ndata);         /* Must have ndata filled in => real nodes exist */
- assert(segmentsx->sdata);      /* Must have sdata filled in => real segments exist */
+ if(nodesx->number==0 || segmentsx->number==0)
+    return;
 
  /* Print the start message */
 
@@ -873,27 +857,31 @@ void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
 
  /* Map into memory */
 
- if(!option_slim)
-   {
-    nodesx->xdata=MapFile(nodesx->filename);
-    segmentsx->xdata=MapFile(segmentsx->filename);
-   }
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+ segmentsx->xdata=MapFile(segmentsx->filename);
+#endif
 
  /* Index the segments */
 
  for(i=0;i<nodesx->number;i++)
    {
     NodeX  *nodex=LookupNodeX(nodesx,i,1);
-    Node   *node =&nodesx->ndata[nodex->id];
-    index_t index=SEGMENT(node->firstseg);
+    Node   *node =LookupNodeXNode(nodesx,nodex->id,1);
+    index_t index=node->firstseg;
 
     do
       {
        SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
+       Segment  *segment =LookupSegmentXSegment(segmentsx,index,1);
 
        if(segmentx->node1==nodex->id)
          {
-          segmentsx->sdata[index].node1=i;
+          segment->node1=i;
+
+#if SLIM
+          PutBackSegmentXSegment(segmentsx,index,1);
+#endif
 
           index++;
 
@@ -907,12 +895,16 @@ void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
          }
        else
          {
-          segmentsx->sdata[index].node2=i;
+          segment->node2=i;
 
-          if(segmentsx->sdata[index].next2==NO_NODE)
+#if SLIM
+          PutBackSegmentXSegment(segmentsx,index,1);
+#endif
+
+          if(segment->next2==NO_NODE)
              break;
           else
-             index=segmentsx->sdata[index].next2;
+             index=segment->next2;
          }
       }
     while(1);
@@ -926,11 +918,10 @@ void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
 
  /* Unmap from memory */
 
- if(!option_slim)
-   {
-    nodesx->xdata=UnmapFile(nodesx->filename);
-    segmentsx->xdata=UnmapFile(segmentsx->filename);
-   }
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+#endif
 
  /* Print the final message */
 
@@ -951,51 +942,30 @@ void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
 {
  index_t i;
  int fd;
- Segments *segments;
+ SegmentsFile segmentsfile={0};
  int super_number=0,normal_number=0;
 
- /* Check the start conditions */
-
- assert(segmentsx->sdata);      /* Must have sdata filled in => real segments */
-
  /* Print the start message */
 
  printf("Writing Segments: Segments=0");
  fflush(stdout);
 
- /* Count the number of super-segments and normal segments */
+ /* Write out the segments data */
+
+ fd=OpenFileNew(filename);
+
+ SeekFile(fd,sizeof(SegmentsFile));
 
  for(i=0;i<segmentsx->number;i++)
    {
-    if(IsSuperSegment(&segmentsx->sdata[i]))
+    Segment *segment=LookupSegmentXSegment(segmentsx,i,1);
+
+    if(IsSuperSegment(segment))
        super_number++;
-    if(IsNormalSegment(&segmentsx->sdata[i]))
+    if(IsNormalSegment(segment))
        normal_number++;
-   }
-
- /* Fill in a Segments structure with the offset of the real data in the file after
-    the Segment structure itself. */
-
- segments=calloc(1,sizeof(Segments));
-
- assert(segments); /* Check calloc() worked */
-
- segments->number=segmentsx->number;
- segments->snumber=super_number;
- segments->nnumber=normal_number;
-
- segments->data=NULL;
- segments->segments=NULL;
 
- /* Write out the Segments structure and then the real data. */
-
- fd=OpenFile(filename);
-
- WriteFile(fd,segments,sizeof(Segments));
-
- for(i=0;i<segments->number;i++)
-   {
-    WriteFile(fd,&segmentsx->sdata[i],sizeof(Segment));
+    WriteFile(fd,segment,sizeof(Segment));
 
     if(!((i+1)%10000))
       {
@@ -1004,16 +974,21 @@ void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
       }
    }
 
+ /* Write out the header structure */
+
+ segmentsfile.number=segmentsx->number;
+ segmentsfile.snumber=super_number;
+ segmentsfile.nnumber=normal_number;
+
+ SeekFile(fd,0);
+ WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
+
  CloseFile(fd);
 
  /* Print the final message */
 
- printf("\rWrote Segments: Segments=%d  \n",segments->number);
+ printf("\rWrote Segments: Segments=%d  \n",segmentsx->number);
  fflush(stdout);
-
- /* Free the fake Segments */
-
- free(segments);
 }