static void *filesort_fixed_heapsort_thread(thread_data *thread) { int fd; size_t item; /* Sort the data pointers using a heap sort */ filesort_heapsort(thread->datap,thread->n,thread->compare); /* Create a temporary file and write the result */ fd=OpenFileBufferedNew(thread->filename); for(item=0;item<thread->n;item++) WriteFileBuffered(fd,thread->datap[item],thread->itemsize); CloseFileBuffered(fd); #if defined(USE_PTHREADS) && USE_PTHREADS if(option_filesort_threads>1) { pthread_mutex_lock(&running_mutex); thread->running=2; pthread_cond_signal(&running_cond); pthread_mutex_unlock(&running_mutex); } #endif return(NULL); }
void AppendWayList(WaysX *waysx,way_t id,Way *way,node_t *nodes,int nnodes,const char *name) { WayX wayx; FILESORT_VARINT size; node_t nonode=NO_NODE_ID; wayx.id=id; wayx.way=*way; size=sizeof(WayX)+(nnodes+1)*sizeof(node_t)+strlen(name)+1; WriteFileBuffered(waysx->fd,&size,FILESORT_VARSIZE); WriteFileBuffered(waysx->fd,&wayx,sizeof(WayX)); WriteFileBuffered(waysx->fd,nodes ,nnodes*sizeof(node_t)); WriteFileBuffered(waysx->fd,&nonode, sizeof(node_t)); WriteFileBuffered(waysx->fd,name,strlen(name)+1); waysx->number++; logassert(waysx->number!=0,"Too many ways (change index_t to 64-bits?)"); /* Zero marks the high-water mark for ways. */ }
relation_t logerror_relation(relation_t id) { if(errorbinfile!=-1) { ErrorLogObject error={0}; error.id=id; error.type='R'; error.offset=errorfileoffset; WriteFileBuffered(errorbinfile,&error,sizeof(ErrorLogObject)); } return(id); }
void PruneIsolatedRegions(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t minimum) { WaysX *newwaysx; WayX tmpwayx; transport_t transport; BitMask *connected,*region; index_t *regionsegments,*othersegments; index_t nallocregionsegments,nallocothersegments; if(nodesx->number==0 || segmentsx->number==0) return; /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFile(nodesx->filename_tmp); segmentsx->data=MapFileWriteable(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFile(nodesx->filename_tmp); segmentsx->fd=SlimMapFileWriteable(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif newwaysx=NewWayList(0,0); CloseFileBuffered(newwaysx->fd); newwaysx->fd=SlimMapFileWriteable(newwaysx->filename_tmp); connected=AllocBitMask(segmentsx->number); region =AllocBitMask(segmentsx->number); logassert(connected,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ logassert(region,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ regionsegments=(index_t*)malloc((nallocregionsegments=1024)*sizeof(index_t)); othersegments =(index_t*)malloc((nallocothersegments =1024)*sizeof(index_t)); logassert(regionsegments,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ logassert(othersegments,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Loop through the transport types */ for(transport=Transport_None+1;transport<Transport_Count;transport++) { index_t i,j; index_t nregions=0,npruned=0,nadjusted=0; const char *transport_str=TransportName(transport); transports_t transports=TRANSPORTS(transport); if(!(waysx->allow&transports)) continue; /* Print the start message */ printf_first("Pruning Isolated Regions (%s): Segments=0 Adjusted=0 Pruned=0",transport_str); /* Loop through the segments and find the disconnected ones */ ClearAllBits(connected,segmentsx->number); ClearAllBits(region ,segmentsx->number); for(i=0;i<segmentsx->number;i++) { index_t nregionsegments=0,nothersegments=0; distance_t total=0; SegmentX *segmentx; WayX *wayx; if(IsBitSet(connected,i)) goto endloop; segmentx=LookupSegmentX(segmentsx,i,1); if(IsPrunedSegmentX(segmentx)) goto endloop; if(segmentx->way<waysx->number) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(!(wayx->way.allow&transports)) goto endloop; othersegments[nothersegments++]=i; SetBit(region,i); do { index_t thissegment,nodes[2]; thissegment=othersegments[--nothersegments]; if(nregionsegments==nallocregionsegments) regionsegments=(index_t*)realloc(regionsegments,(nallocregionsegments+=1024)*sizeof(index_t)); regionsegments[nregionsegments++]=thissegment; segmentx=LookupSegmentX(segmentsx,thissegment,1); nodes[0]=segmentx->node1; nodes[1]=segmentx->node2; total+=DISTANCE(segmentx->distance); for(j=0;j<2;j++) { NodeX *nodex=LookupNodeX(nodesx,nodes[j],1); if(!(nodex->allow&transports)) continue; segmentx=FirstSegmentX(segmentsx,nodes[j],1); while(segmentx) { index_t segment=IndexSegmentX(segmentsx,segmentx); if(segment!=thissegment) { if(segmentx->way<waysx->number) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(wayx->way.allow&transports) { /* Already connected - finish */ if(IsBitSet(connected,segment)) { total=minimum; goto foundconnection; } /* Not in region - add to list */ if(!IsBitSet(region,segment)) { if(nothersegments==nallocothersegments) othersegments=(index_t*)realloc(othersegments,(nallocothersegments+=1024)*sizeof(index_t)); othersegments[nothersegments++]=segment; SetBit(region,segment); } } } segmentx=NextSegmentX(segmentsx,segmentx,nodes[j]); } } } while(nothersegments>0 && total<minimum); foundconnection: /* Prune the segments or mark them as connected */ if(total<minimum) /* not connected - delete them */ { nregions++; for(j=0;j<nregionsegments;j++) { SegmentX *segmentx; WayX *wayx,tmpwayx; SetBit(connected,regionsegments[j]); /* not really connected, but don't need to check again */ ClearBit(region,regionsegments[j]); segmentx=LookupSegmentX(segmentsx,regionsegments[j],1); if(segmentx->way<waysx->number) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(wayx->way.allow==transports) { prune_segment(segmentsx,segmentx); npruned++; } else { if(segmentx->way<waysx->number) /* create a new way */ { tmpwayx=*wayx; tmpwayx.way.allow&=~transports; segmentx->way=waysx->number+newwaysx->number; SlimReplace(newwaysx->fd,&tmpwayx,sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); newwaysx->number++; PutBackSegmentX(segmentsx,segmentx); } else /* modify the existing one */ { tmpwayx.way.allow&=~transports; SlimReplace(newwaysx->fd,&tmpwayx,sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); } nadjusted++; } } } else /* connected - mark as part of the main region */ { for(j=0;j<nregionsegments;j++) { SetBit(connected,regionsegments[j]); ClearBit(region,regionsegments[j]); } for(j=0;j<nothersegments;j++) { SetBit(connected,othersegments[j]); ClearBit(region,othersegments[j]); } } endloop: if(!((i+1)%10000)) printf_middle("Pruning Isolated Regions (%s): Segments=%"Pindex_t" Adjusted=%"Pindex_t" Pruned=%"Pindex_t" (%"Pindex_t" Regions)",transport_str,i+1,nadjusted,npruned,nregions); } /* Print the final message */ printf_last("Pruned Isolated Regions (%s): Segments=%"Pindex_t" Adjusted=%"Pindex_t" Pruned=%"Pindex_t" (%"Pindex_t" Regions)",transport_str,segmentsx->number,nadjusted,npruned,nregions); } /* Unmap from memory / close the files */ free(region); free(connected); free(regionsegments); free(othersegments); #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif SlimUnmapFile(newwaysx->fd); waysx->number+=newwaysx->number; waysx->fd=OpenFileBufferedAppend(waysx->filename_tmp); newwaysx->fd=ReOpenFileBuffered(newwaysx->filename_tmp); while(!ReadFileBuffered(newwaysx->fd,&tmpwayx,sizeof(WayX))) WriteFileBuffered(waysx->fd,&tmpwayx,sizeof(WayX)); CloseFileBuffered(waysx->fd); CloseFileBuffered(newwaysx->fd); FreeWayList(newwaysx,0); }
index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_t), int (*compare_function)(const void*,const void*), int (*post_sort_function)(void*,index_t)) { int *fds=NULL,*heap=NULL; int nfiles=0,ndata=0; index_t count_out=0,count_in=0,total=0; size_t datasize=option_filesort_ramsize/option_filesort_threads; FILESORT_VARINT nextitemsize,largestitemsize=0; void *data,**datap; thread_data *threads; size_t item; int i,more=1; #if defined(USE_PTHREADS) && USE_PTHREADS int nthreads=0; #endif /* Allocate the RAM buffer and other bits */ threads=(thread_data*)malloc(option_filesort_threads*sizeof(thread_data)); for(i=0;i<option_filesort_threads;i++) { threads[i].running=0; threads[i].data=malloc(datasize); threads[i].datap=NULL; threads[i].filename=(char*)malloc(strlen(option_tmpdirname)+24); threads[i].compare=compare_function; } /* Loop around, fill the buffer, sort the data and write a temporary file */ if(ReadFileBuffered(fd_in,&nextitemsize,FILESORT_VARSIZE)) /* Always have the next item size known in advance */ goto tidy_and_exit; do { size_t ramused=FILESORT_VARALIGN-FILESORT_VARSIZE; int thread=0; #if defined(USE_PTHREADS) && USE_PTHREADS if(option_filesort_threads>1) { /* Find a spare slot (one *must* be unused at all times) */ pthread_mutex_lock(&running_mutex); for(thread=0;thread<option_filesort_threads;thread++) if(!threads[thread].running) break; pthread_mutex_unlock(&running_mutex); } #endif threads[thread].datap=threads[thread].data+datasize; threads[thread].n=0; /* Read in the data and create pointers */ while((ramused+FILESORT_VARSIZE+nextitemsize)<=(unsigned)((void*)threads[thread].datap-sizeof(void*)-threads[thread].data)) { FILESORT_VARINT itemsize=nextitemsize; *(FILESORT_VARINT*)(threads[thread].data+ramused)=itemsize; ramused+=FILESORT_VARSIZE; ReadFileBuffered(fd_in,threads[thread].data+ramused,itemsize); if(!pre_sort_function || pre_sort_function(threads[thread].data+ramused,count_in)) { *--threads[thread].datap=threads[thread].data+ramused; /* points to real data */ if(itemsize>largestitemsize) largestitemsize=itemsize; ramused+=itemsize; ramused =FILESORT_VARALIGN*((ramused+FILESORT_VARSIZE-1)/FILESORT_VARALIGN); ramused+=FILESORT_VARALIGN-FILESORT_VARSIZE; total++; threads[thread].n++; } else ramused-=FILESORT_VARSIZE; count_in++; if(ReadFileBuffered(fd_in,&nextitemsize,FILESORT_VARSIZE)) { more=0; break; } } /* No new data read in this time round */ if(threads[thread].n==0) break; /* Sort the data pointers using a heap sort (potentially in a thread) */ if(more==0 && nfiles==0) threads[thread].filename[0]=0; else sprintf(threads[thread].filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles); #if defined(USE_PTHREADS) && USE_PTHREADS /* Shortcut if only one file, don't write to disk */ if(more==0 && nfiles==0) filesort_heapsort(threads[thread].datap,threads[thread].n,threads[thread].compare); else if(option_filesort_threads>1) { pthread_mutex_lock(&running_mutex); while(nthreads==(option_filesort_threads-1)) { for(i=0;i<option_filesort_threads;i++) if(threads[i].running==2) { pthread_join(threads[i].thread,NULL); threads[i].running=0; nthreads--; } if(nthreads==(option_filesort_threads-1)) pthread_cond_wait(&running_cond,&running_mutex); } threads[thread].running=1; pthread_mutex_unlock(&running_mutex); pthread_create(&threads[thread].thread,NULL,(void* (*)(void*))filesort_vary_heapsort_thread,&threads[thread]); nthreads++; } else filesort_vary_heapsort_thread(&threads[thread]); #else /* Shortcut if only one file, don't write to disk */ if(more==0 && nfiles==0) filesort_heapsort(threads[thread].datap,threads[thread].n,threads[thread].compare); else filesort_vary_heapsort_thread(&threads[thread]); #endif nfiles++; } while(more); /* Wait for all of the threads to finish */ #if defined(USE_PTHREADS) && USE_PTHREADS while(option_filesort_threads>1 && nthreads) { pthread_mutex_lock(&running_mutex); pthread_cond_wait(&running_cond,&running_mutex); for(i=0;i<option_filesort_threads;i++) if(threads[i].running==2) { pthread_join(threads[i].thread,NULL); threads[i].running=0; nthreads--; } pthread_mutex_unlock(&running_mutex); } #endif /* Shortcut if only one file, lucky for us we still have the data in RAM) */ if(nfiles==1) { for(item=0;item<threads[0].n;item++) { if(!post_sort_function || post_sort_function(threads[0].datap[item],count_out)) { FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(threads[0].datap[item]-FILESORT_VARSIZE); WriteFileBuffered(fd_out,threads[0].datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE); count_out++; } } DeleteFile(threads[0].filename); goto tidy_and_exit; } /* Check that number of files is less than file size */ largestitemsize=FILESORT_VARALIGN*(1+(largestitemsize+FILESORT_VARALIGN-FILESORT_VARSIZE)/FILESORT_VARALIGN); logassert((unsigned)nfiles<((datasize-nfiles*sizeof(void*))/largestitemsize),"Too many temporary files (use more sorting memory?)"); /* Open all of the temporary files */ fds=(int*)malloc(nfiles*sizeof(int)); for(i=0;i<nfiles;i++) { char *filename=threads[0].filename; sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,i); fds[i]=ReOpenFileBuffered(filename); DeleteFile(filename); } /* Perform an n-way merge using a binary heap */ heap=(int*)malloc((1+nfiles)*sizeof(int)); data=threads[0].data; datap=data+datasize-nfiles*sizeof(void*); /* Fill the heap to start with */ for(i=0;i<nfiles;i++) { int index; FILESORT_VARINT itemsize; datap[i]=data+FILESORT_VARALIGN-FILESORT_VARSIZE+i*largestitemsize; ReadFileBuffered(fds[i],&itemsize,FILESORT_VARSIZE); *(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE)=itemsize; ReadFileBuffered(fds[i],datap[i],itemsize); index=i+1; heap[index]=i; /* Bubble up the new value */ while(index>1) { int newindex; int temp; newindex=index/2; if(compare_function(datap[heap[index]],datap[heap[newindex]])>=0) break; temp=heap[index]; heap[index]=heap[newindex]; heap[newindex]=temp; index=newindex; } } /* Repeatedly pull out the root of the heap and refill from the same file */ ndata=nfiles; do { int index=1; FILESORT_VARINT itemsize; if(!post_sort_function || post_sort_function(datap[heap[index]],count_out)) { itemsize=*(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE); WriteFileBuffered(fd_out,datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE); count_out++; } if(ReadFileBuffered(fds[heap[index]],&itemsize,FILESORT_VARSIZE)) { heap[index]=heap[ndata]; ndata--; } else { *(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE)=itemsize; ReadFileBuffered(fds[heap[index]],datap[heap[index]],itemsize); } /* Bubble down the new value */ while((2*index)<ndata) { int newindex; int temp; newindex=2*index; if(compare_function(datap[heap[newindex]],datap[heap[newindex+1]])>=0) newindex=newindex+1; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) break; temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; index=newindex; } if((2*index)==ndata) { int newindex; int temp; newindex=2*index; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) ; /* break */ else { temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; } } } while(ndata>0); /* Tidy up */ tidy_and_exit: if(fds) { for(i=0;i<nfiles;i++) CloseFileBuffered(fds[i]); free(fds); } if(heap) free(heap); for(i=0;i<option_filesort_threads;i++) { free(threads[i].data); free(threads[i].filename); } free(threads); return(count_out); }
void SaveWayList(WaysX *waysx,const char *filename) { index_t i; int fd; index_t position=0; WayX wayx; WaysFile waysfile={0}; highways_t highways=0; transports_t allow=0; properties_t props=0; /* Print the start message */ printf_first("Writing Ways: Ways=0"); /* Re-open the files */ waysx->fd=ReOpenFileBuffered(waysx->filename_tmp); waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp); /* Write out the ways data */ fd=OpenFileBufferedNew(filename); SeekFileBuffered(fd,sizeof(WaysFile)); for(i=0;i<waysx->number;i++) { ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); highways|=HIGHWAYS(wayx.way.type); allow |=wayx.way.allow; props |=wayx.way.props; WriteFileBuffered(fd,&wayx.way,sizeof(Way)); if(!((i+1)%1000)) printf_middle("Writing Ways: Ways=%"Pindex_t,i+1); } /* Write out the ways names */ SeekFileBuffered(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way)); while(position<waysx->nlength) { size_t len=1024; char temp[1024]; if((waysx->nlength-position)<1024) len=waysx->nlength-position; ReadFileBuffered(waysx->nfd,temp,len); WriteFileBuffered(fd,temp,len); position+=len; } /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); waysx->nfd=CloseFileBuffered(waysx->nfd); /* Write out the header structure */ waysfile.number =waysx->number; waysfile.highways=highways; waysfile.allow =allow; waysfile.props =props; SeekFileBuffered(fd,0); WriteFileBuffered(fd,&waysfile,sizeof(WaysFile)); CloseFileBuffered(fd); /* Print the final message */ printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number); }
void SortWayNames(WaysX *waysx) { index_t i; int nfd; char *names[2]={NULL,NULL}; int namelen[2]={0,0}; int nnames=0; uint32_t lastlength=0; /* Print the start message */ printf_first("Sorting Way Names"); /* Re-open the file read-only and new file writeable */ waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp); DeleteFile(waysx->nfilename_tmp); nfd=OpenFileBufferedNew(waysx->nfilename_tmp); /* Sort the way names */ waysx->nlength=0; filesort_vary(waysx->nfd,nfd,NULL, (int (*)(const void*,const void*))sort_by_name, NULL); /* Close the files */ waysx->nfd=CloseFileBuffered(waysx->nfd); CloseFileBuffered(nfd); /* Print the final message */ printf_last("Sorted Way Names: Ways=%"Pindex_t,waysx->number); /* Print the start message */ printf_first("Updating Ways with Names: Ways=0 Names=0"); /* Map into memory / open the file */ #if !SLIM waysx->data=MapFileWriteable(waysx->filename_tmp); #else waysx->fd=SlimMapFileWriteable(waysx->filename_tmp); #endif /* Re-open the file read-only and new file writeable */ waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp); DeleteFile(waysx->nfilename_tmp); nfd=OpenFileBufferedNew(waysx->nfilename_tmp); /* Update the ways and de-duplicate the names */ for(i=0;i<waysx->number;i++) { WayX *wayx; index_t index; FILESORT_VARINT size; ReadFileBuffered(waysx->nfd,&size,FILESORT_VARSIZE); if(namelen[nnames%2]<size) names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size); ReadFileBuffered(waysx->nfd,&index,sizeof(index_t)); ReadFileBuffered(waysx->nfd,names[nnames%2],size-sizeof(index_t)); if(nnames==0 || strcmp(names[0],names[1])) { WriteFileBuffered(nfd,names[nnames%2],size-sizeof(index_t)); lastlength=waysx->nlength; waysx->nlength+=size-sizeof(index_t); nnames++; } wayx=LookupWayX(waysx,index,1); wayx->way.name=lastlength; PutBackWayX(waysx,wayx); if(!((i+1)%1000)) printf_middle("Updating Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames); } if(names[0]) free(names[0]); if(names[1]) free(names[1]); /* Close the files */ waysx->nfd=CloseFileBuffered(waysx->nfd); CloseFileBuffered(nfd); /* Unmap from memory / close the files */ #if !SLIM waysx->data=UnmapFile(waysx->data); #else waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Updated Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames); }
SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep) { SegmentsX *segmentsx; index_t i; int fd,nfd; char *name=NULL; int namelen=0; /* Print the start message */ printf_first("Splitting Ways: Ways=0 Segments=0"); segmentsx=NewSegmentList(); /* Re-open the file read-only and a new file writeable */ waysx->fd=ReOpenFileBuffered(waysx->filename_tmp); if(keep) RenameFile(waysx->filename_tmp,waysx->filename); else DeleteFile(waysx->filename_tmp); fd=OpenFileBufferedNew(waysx->filename_tmp); nfd=OpenFileBufferedNew(waysx->nfilename_tmp); /* Loop through the ways and create the segments and way names */ for(i=0;i<waysx->number;i++) { WayX wayx; FILESORT_VARINT size; node_t node,prevnode=NO_NODE_ID; index_t index,previndex=NO_NODE; ReadFileBuffered(waysx->fd,&size,FILESORT_VARSIZE); ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); waysx->allow|=wayx.way.allow; while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID) { index=IndexNodeX(nodesx,node); if(prevnode==node) { logerror("Way %"Pway_t" contains node %"Pnode_t" that is connected to itself.\n",logerror_way(wayx.id),logerror_node(node)); } else if(index==NO_NODE) { logerror("Way %"Pway_t" contains node %"Pnode_t" that does not exist in the Routino database.\n",logerror_way(wayx.id),logerror_node(node)); } else if(previndex==NO_NODE) ; else { distance_t segment_flags=0; if(wayx.way.type&Highway_OneWay) segment_flags|=ONEWAY_1TO2; if(wayx.way.type&Highway_Area) segment_flags|=SEGMENT_AREA; AppendSegmentList(segmentsx,i,previndex,index,segment_flags); } prevnode=node; previndex=index; size-=sizeof(node_t); } size-=sizeof(node_t)+sizeof(WayX); if(namelen<size) name=(char*)realloc((void*)name,namelen=size); ReadFileBuffered(waysx->fd,name,size); WriteFileBuffered(fd,&wayx,sizeof(WayX)); size+=sizeof(index_t); WriteFileBuffered(nfd,&size,FILESORT_VARSIZE); WriteFileBuffered(nfd,&i,sizeof(index_t)); WriteFileBuffered(nfd,name,size-sizeof(index_t)); if(!((i+1)%1000)) printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number); } FinishSegmentList(segmentsx); if(name) free(name); /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); CloseFileBuffered(fd); CloseFileBuffered(nfd); /* Print the final message */ printf_last("Split Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number); return(segmentsx); }