virtual unique_ptr<DocResult> FirstResult(uint64_t startId) { // build full key key_build_.PushDocSeq(startId); // seek in index to GTE entry iter_->Seek(key_build_.key()); //revert key_build_.PopDocSeq(); return NextResult(); }
void FixForwardRoute(Results *results,Result *finish_result) { Result *result2=finish_result; /* Erase the old route if there is one */ if(results->finish_node!=NO_NODE) { Result *result1=FirstResult(results); while(result1) { result1->next=NULL; result1=NextResult(results,result1); } } /* Create the forward links for the optimum path */ do { Result *result1; if(result2->prev) { index_t node1=result2->prev->node; index_t seg1=result2->prev->segment; result1=FindResult(results,node1,seg1); assert(!result1->next); /* Bugs elsewhere can lead to infinite loop here. */ result1->next=result2; result2=result1; } else result2=NULL; } while(result2); results->finish_node=finish_result->node; results->last_segment=finish_result->segment; }
int IOProcess::stdinPipeHandler() { char command[131072]; while( m_stdin_buffer.GetNextLine( command, sizeof( command ) ) ) { dprintf (D_FULLDEBUG, "got stdin: '%s'\n", command); Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print each result line // Print number of results printf("%s %d\n", GAHP_RESULT_SUCCESS, numOfResult()); fflush(stdout); startResultIteration(); char* next = NULL; while ((next = NextResult()) != NULL) { printf ("%s", next); fflush(stdout); deleteCurrentResult(); } m_new_results_signaled = false; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); io_process_exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { m_async_mode = true; m_new_results_signaled = false; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { m_async_mode = false; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_STATISTICS) == 0) { printf( "%s %d %d %d %d\n", GAHP_RESULT_SUCCESS, NumRequests, NumDistinctRequests, NumRequestsExceedingLimit, NumExpiredSignatures ); fflush( stdout ); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { StringList amazon_commands; int num_commands = 0; num_commands = allAmazonCommands(amazon_commands); num_commands += 7; const char *commands[num_commands]; int i = 0; commands[i++] = GAHP_RESULT_SUCCESS; commands[i++] = GAHP_COMMAND_ASYNC_MODE_ON; commands[i++] = GAHP_COMMAND_ASYNC_MODE_OFF; commands[i++] = GAHP_COMMAND_RESULTS; commands[i++] = GAHP_COMMAND_QUIT; commands[i++] = GAHP_COMMAND_VERSION; commands[i++] = GAHP_COMMAND_COMMANDS; amazon_commands.rewind(); char *one_amazon_command = NULL; while( (one_amazon_command = amazon_commands.next() ) != NULL ) { commands[i++] = one_amazon_command; } gahp_output_return (commands, i); } else { // got new command if( !addNewRequest(command) ) { gahp_output_return_error(); } else { gahp_output_return_success(); } } } else { gahp_output_return_error(); } } // check if GetNextLine() returned NULL because of an error or EOF if (m_stdin_buffer.IsError() || m_stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); io_process_exit(1); } return TRUE; }
SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) { index_t i; SegmentsX *supersegmentsx; index_t sn=0,ss=0; supersegmentsx=NewSegmentList(0); if(segmentsx->number==0 || waysx->number==0) return(supersegmentsx); /* Print the start message */ printf_first("Creating Super-Segments: Super-Nodes=0 Super-Segments=0"); /* Map into memory / open the files */ #if !SLIM segmentsx->data=MapFile(segmentsx->filename); waysx->data=MapFile(waysx->filename); #else segmentsx->fd=ReOpenFile(segmentsx->filename); waysx->fd=ReOpenFile(waysx->filename); #endif /* Create super-segments for each super-node. */ for(i=0;i<nodesx->number;i++) { if(IsBitSet(nodesx->super,i)) { SegmentX *segmentx; int count=0,match; Way prevway[MAX_SEG_PER_NODE]; segmentx=FirstSegmentX(segmentsx,i,1); while(segmentx) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); /* Check that this type of way hasn't already been routed */ match=0; if(count>0) { int j; for(j=0;j<count;j++) if(!WaysCompare(&prevway[j],&wayx->way)) { match=1; break; } } assert(count<MAX_SEG_PER_NODE); /* Only a limited amount of history stored. */ prevway[count++]=wayx->way; /* Route the way and store the super-segments. */ if(!match) { Results *results=FindRoutesWay(nodesx,segmentsx,waysx,i,&wayx->way); Result *result=FirstResult(results); while(result) { if(IsBitSet(nodesx->super,result->node) && result->segment!=NO_SEGMENT) { if(wayx->way.type&Way_OneWay && result->node!=i) AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2); else AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)); ss++; } result=NextResult(results,result); } FreeResultsList(results); } segmentx=NextSegmentX(segmentsx,segmentx,i); } sn++; if(!(sn%10000)) printf_middle("Creating Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss); } } /* Unmap from memory / close the files */ #if !SLIM segmentsx->data=UnmapFile(segmentsx->filename); waysx->data=UnmapFile(waysx->filename); #else segmentsx->fd=CloseFile(segmentsx->fd); waysx->fd=CloseFile(waysx->fd); #endif /* Print the final message */ printf_last("Created Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss); return(supersegmentsx); }
Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Results *begin,Results *end,Profile *profile) { Results *results; Queue *queue; index_t node1,node2; index_t end_prev; score_t finish_score; double finish_lat,finish_lon; Result *result1,*result2,*result3; Segment *segment; Way *way; if(!option_quiet) { printf("Routing: Super-Nodes checked = 0"); fflush(stdout); } /* Set up the finish conditions */ finish_score=INF_DISTANCE; end_prev=NO_NODE; if(IsFakeNode(end->finish)) GetFakeLatLong(end->finish,&finish_lat,&finish_lon); else GetLatLong(nodes,end->finish,&finish_lat,&finish_lon); /* Create the list of results and insert the first node into the queue */ results=NewResultsList(2048); results->start=begin->start; results->finish=end->finish; result1=InsertResult(results,begin->start); result3=FindResult(begin,begin->start); *result1=*result3; queue=NewQueueList(); /* Insert the finish points of the beginning part of the path into the queue */ result3=FirstResult(begin); while(result3) { if(result3->node!=begin->start && !IsFakeNode(result3->node) && IsSuperNode(nodes,result3->node)) { result2=InsertResult(results,result3->node); *result2=*result3; result2->prev=begin->start; result2->sortby=result2->score; InsertInQueue(queue,result2); } result3=NextResult(begin,result3); } if(begin->number==1) InsertInQueue(queue,result1); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { if(result1->score>finish_score) continue; node1=result1->node; segment=FirstSegment(segments,nodes,node1); while(segment) { score_t segment_pref,segment_score,cumulative_score; int i; if(!IsSuperSegment(segment)) goto endloop; if(profile->oneway && IsOnewayTo(segment,node1)) goto endloop; node2=OtherNode(segment,node1); if(result1->prev==node2) goto endloop; way=LookupWay(ways,segment->way); if(!(way->allow&profile->allow)) goto endloop; if(!profile->highway[HIGHWAY(way->type)]) goto endloop; if(way->weight && way->weight<profile->weight) goto endloop; if((way->height && way->height<profile->height) || (way->width && way->width <profile->width ) || (way->length && way->length<profile->length)) goto endloop; segment_pref=profile->highway[HIGHWAY(way->type)]; for(i=1;i<Property_Count;i++) if(ways->props & PROPERTIES(i)) { if(way->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } if(segment_pref==0) goto endloop; if(option_quickest==0) segment_score=(score_t)DISTANCE(segment->distance)/segment_pref; else segment_score=(score_t)Duration(segment,way,profile)/segment_pref; cumulative_score=result1->score+segment_score; if(cumulative_score>finish_score) goto endloop; result2=FindResult(results,node2); if(!result2) /* New end node */ { result2=InsertResult(results,node2); result2->prev=node1; result2->next=NO_NODE; result2->score=cumulative_score; result2->segment=segment; if((result3=FindResult(end,node2))) { if((result2->score+result3->score)<finish_score) { finish_score=result2->score+result3->score; end_prev=node2; } } else { double lat,lon; distance_t direct; GetLatLong(nodes,node2,&lat,&lon); direct=Distance(lat,lon,finish_lat,finish_lon); if(option_quickest==0) result2->sortby=result2->score+(score_t)direct/profile->max_pref; else result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref; InsertInQueue(queue,result2); } } else if(cumulative_score<result2->score) /* New end node is better */ { result2->prev=node1; result2->score=cumulative_score; result2->segment=segment; if((result3=FindResult(end,node2))) { if((result2->score+result3->score)<finish_score) { finish_score=result2->score+result3->score; end_prev=node2; } } else if(result2->score<finish_score) { double lat,lon; distance_t direct; GetLatLong(nodes,node2,&lat,&lon); direct=Distance(lat,lon,finish_lat,finish_lon); if(option_quickest==0) result2->sortby=result2->score+(score_t)direct/profile->max_pref; else result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref; InsertInQueue(queue,result2); } } endloop: if(!option_quiet && !(results->number%10000)) { printf("\rRouting: Super-Nodes checked = %d",results->number); fflush(stdout); } segment=NextSegment(segments,segment,node1); } } if(!option_quiet) { printf("\rRouting: Super-Nodes checked = %d\n",results->number); fflush(stdout); } /* Finish off the end part of the route. */ if(!FindResult(results,end->finish) && end_prev!=NO_NODE) { result2=InsertResult(results,end->finish); result3=FindResult(end,end->finish); *result2=*result3; result2->prev=end_prev; result2->score=finish_score; } FreeQueueList(queue); /* Check it worked */ if(end_prev==NO_NODE) { FreeResultsList(results); return(NULL); } FixForwardRoute(results,end->finish); return(results); }
Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node) { Results *results,*results2; Queue *queue; Result *result1,*result2,*result3; /* Create the results and insert the finish node */ results=NewResultsList(64); results->finish_node=finish_node; result1=InsertResult(results,finish_node,NO_SEGMENT); /* Insert the first node into the queue */ queue=NewQueueList(); InsertInQueue(queue,result1); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { index_t node1,seg1,seg1r; Segment *segment; index_t turnrelation=NO_RELATION; node1=result1->node; seg1=result1->segment; if(IsFakeSegment(seg1)) seg1r=IndexRealSegment(seg1); else seg1r=seg1; /* lookup if a turn restriction applies */ if(profile->turns && !IsFakeNode(node1) && IsTurnRestrictedNode(LookupNode(nodes,node1,1))) turnrelation=FindFirstTurnRelation1(relations,node1); /* working backwards => turn relation sort order doesn't help */ /* Loop across all segments */ if(IsFakeNode(node1)) segment=FirstFakeSegment(node1); else segment=FirstSegment(segments,nodes,node1,1); while(segment) { Way *way; index_t node2,seg2,seg2r; score_t segment_pref,segment_score,cumulative_score; int i; /* must be a normal segment */ if((IsFakeNode(node1) || !IsSuperNode(LookupNode(nodes,node1,1))) && !IsNormalSegment(segment)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayFrom(segment,node1)) /* Disallow oneway from node2 *to* node1 */ goto endloop; node2=OtherNode(segment,node1); if(IsFakeNode(node1) || IsFakeNode(node2)) { seg2 =IndexFakeSegment(segment); seg2r=IndexRealSegment(seg2); } else { seg2 =IndexSegment(segments,segment); seg2r=seg2; } /* must not perform U-turn (unless profile allows) */ if(profile->turns && (seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2)))) goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION) { index_t turnrelation2=FindFirstTurnRelation2(relations,node1,seg2r); /* node2 -> node1 -> result1->next->node */ if(turnrelation2!=NO_RELATION && !IsTurnAllowed(relations,turnrelation2,node1,seg2r,seg1r,profile->allow)) goto endloop; } way=LookupWay(ways,segment->way,1); /* mode of transport must be allowed on the highway */ if(!(way->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(way->weight && way->weight<profile->weight) goto endloop; /* must obey height/width/length restriction (if exists) */ if((way->height && way->height<profile->height) || (way->width && way->width <profile->width ) || (way->length && way->length<profile->length)) goto endloop; segment_pref=profile->highway[HIGHWAY(way->type)]; for(i=1;i<Property_Count;i++) if(ways->file.props & PROPERTIES(i)) { if(way->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; /* mode of transport must be allowed through node2 */ if(!IsFakeNode(node2)) { Node *node=LookupNode(nodes,node2,2); if(!(node->allow&profile->allow)) goto endloop; } if(option_quickest==0) segment_score=(score_t)DISTANCE(segment->distance)/segment_pref; else segment_score=(score_t)Duration(segment,way,profile)/segment_pref; cumulative_score=result1->score+segment_score; result2=FindResult(results,node2,seg2); if(!result2) /* New end node */ { result2=InsertResult(results,node2,seg2); result2->next=result1; /* working backwards */ result2->score=cumulative_score; if(IsFakeNode(node1) || (!IsFakeNode(node1) && !IsSuperNode(LookupNode(nodes,node1,1)))) /* Overshoot by one segment */ { result2->sortby=result2->score; InsertInQueue(queue,result2); } } else if(cumulative_score<result2->score) /* New end node is better */ { result2->next=result1; /* working backwards */ result2->score=cumulative_score; if(IsFakeNode(node1) || (!IsFakeNode(node1) && !IsSuperNode(LookupNode(nodes,node1,1)))) /* Overshoot by one segment */ { result2->sortby=result2->score; InsertInQueue(queue,result2); } } endloop: if(IsFakeNode(node1)) segment=NextFakeSegment(segment,node1); else segment=NextSegment(segments,segment,node1); } } FreeQueueList(queue); /* Check it worked */ if(results->number==1) { FreeResultsList(results); return(NULL); } /* Create a results structure with the node at the end of the segment opposite the start */ results2=NewResultsList(64); results2->finish_node=results->finish_node; result3=FirstResult(results); while(result3) { if(result3->next) { result2=InsertResult(results2,result3->next->node,result3->segment); result2->score=result3->next->score; } result3=NextResult(results,result3); } /* Fix up the result->next pointers */ result3=FirstResult(results); while(result3) { if(result3->next && result3->next->next) { result1=FindResult(results2,result3->next->node,result3->segment); result2=FindResult(results2,result3->next->next->node,result3->next->segment); result1->next=result2; } result3=NextResult(results,result3); } FreeResultsList(results); return(results2); }
Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *end) { Results *results; Queue *queue; Result *finish_result; score_t finish_score; double finish_lat,finish_lon; Result *result1,*result2,*result3,*result4; if(!option_quiet) printf_first("Routing: Super-Nodes checked = 0"); /* Set up the finish conditions */ finish_score=INF_DISTANCE; finish_result=NULL; if(IsFakeNode(end->finish_node)) GetFakeLatLong(end->finish_node,&finish_lat,&finish_lon); else GetLatLong(nodes,end->finish_node,&finish_lat,&finish_lon); /* Create the list of results and insert the first node into the queue */ results=NewResultsList(65536); results->start_node=begin->start_node; results->prev_segment=begin->prev_segment; if(begin->number==1) { if(begin->prev_segment==NO_SEGMENT) results->prev_segment=NO_SEGMENT; else { index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,begin->start_node,begin->prev_segment); results->prev_segment=superseg; } } result1=InsertResult(results,results->start_node,results->prev_segment); queue=NewQueueList(); /* Insert the finish points of the beginning part of the path into the queue, translating the segments into super-segments. */ result3=FirstResult(begin); while(result3) { if((results->start_node!=result3->node || results->prev_segment!=result3->segment) && !IsFakeNode(result3->node) && IsSuperNode(LookupNode(nodes,result3->node,1))) { Result *result5=result1; index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,result3->node,result3->segment); if(superseg!=result3->segment) { result5=InsertResult(results,result3->node,result3->segment); result5->prev=result1; } if(!FindResult(results,result3->node,superseg)) { result2=InsertResult(results,result3->node,superseg); result2->prev=result5; result2->score=result3->score; result2->sortby=result3->score; InsertInQueue(queue,result2); if((result4=FindResult(end,result2->node,result2->segment))) { if((result2->score+result4->score)<finish_score) { finish_score=result2->score+result4->score; finish_result=result2; } } } } result3=NextResult(begin,result3); } if(begin->number==1) InsertInQueue(queue,result1); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { index_t node1,seg1; Segment *segment; index_t turnrelation=NO_RELATION; /* score must be better than current best score */ if(result1->score>finish_score) continue; node1=result1->node; seg1=result1->segment; /* lookup if a turn restriction applies */ if(profile->turns && IsTurnRestrictedNode(LookupNode(nodes,node1,1))) /* node1 cannot be a fake node (must be a super-node) */ turnrelation=FindFirstTurnRelation2(relations,node1,seg1); /* Loop across all segments */ segment=FirstSegment(segments,nodes,node1,1); /* node1 cannot be a fake node (must be a super-node) */ while(segment) { Way *way; Node *node; index_t node2,seg2; score_t segment_pref,segment_score,cumulative_score; int i; /* must be a super segment */ if(!IsSuperSegment(segment)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayTo(segment,node1)) goto endloop; node2=OtherNode(segment,node1); seg2=IndexSegment(segments,segment); /* node2 cannot be a fake node (must be a super-node) */ /* must not perform U-turn */ if(seg1==seg2) /* No fake segments, applies to all profiles */ goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,node1,seg1,seg2,profile->allow)) goto endloop; way=LookupWay(ways,segment->way,1); /* transport must be allowed on the highway */ if(!(way->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(way->weight && way->weight<profile->weight) goto endloop; /* must obey height/width/length restriction (if exists) */ if((way->height && way->height<profile->height) || (way->width && way->width <profile->width ) || (way->length && way->length<profile->length)) goto endloop; segment_pref=profile->highway[HIGHWAY(way->type)]; for(i=1;i<Property_Count;i++) if(ways->file.props & PROPERTIES(i)) { if(way->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; node=LookupNode(nodes,node2,2); /* node2 cannot be a fake node (must be a super-node) */ /* mode of transport must be allowed through node2 */ if(!(node->allow&profile->allow)) goto endloop; if(option_quickest==0) segment_score=(score_t)DISTANCE(segment->distance)/segment_pref; else segment_score=(score_t)Duration(segment,way,profile)/segment_pref; cumulative_score=result1->score+segment_score; /* score must be better than current best score */ if(cumulative_score>finish_score) goto endloop; result2=FindResult(results,node2,seg2); if(!result2) /* New end node/segment pair */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_score; if((result3=FindResult(end,node2,seg2))) { if((result2->score+result3->score)<finish_score) { finish_score=result2->score+result3->score; finish_result=result2; } } else { double lat,lon; distance_t direct; GetLatLong(nodes,node2,&lat,&lon); /* node2 cannot be a fake node (must be a super-node) */ direct=Distance(lat,lon,finish_lat,finish_lon); if(option_quickest==0) result2->sortby=result2->score+(score_t)direct/profile->max_pref; else result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref; InsertInQueue(queue,result2); } } else if(cumulative_score<result2->score) /* New end node/segment pair is better */ { result2->prev=result1; result2->score=cumulative_score; if((result3=FindResult(end,node2,seg2))) { if((result2->score+result3->score)<finish_score) { finish_score=result2->score+result3->score; finish_result=result2; } } else if(result2->score<finish_score) { double lat,lon; distance_t direct; GetLatLong(nodes,node2,&lat,&lon); /* node2 cannot be a fake node (must be a super-node) */ direct=Distance(lat,lon,finish_lat,finish_lon); if(option_quickest==0) result2->sortby=result2->score+(score_t)direct/profile->max_pref; else result2->sortby=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref; InsertInQueue(queue,result2); } } if(!option_quiet && !(results->number%1000)) printf_middle("Routing: Super-Nodes checked = %d",results->number); endloop: segment=NextSegment(segments,segment,node1); /* node1 cannot be a fake node (must be a super-node) */ } } if(!option_quiet) printf_last("Routing: Super-Nodes checked = %d",results->number); FreeQueueList(queue); /* Check it worked */ if(!finish_result) { FreeResultsList(results); return(NULL); } /* Finish off the end part of the route */ if(finish_result->node!=end->finish_node) { result3=InsertResult(results,end->finish_node,NO_SEGMENT); result3->prev=finish_result; result3->score=finish_score; finish_result=result3; } FixForwardRoute(results,finish_result); return(results); }