News:

Simutrans Sites
Know our official sites. Find tools and resources for Simutrans.

[Code v3.7] Pseudo Fresh Paths

Started by knightly, May 12, 2009, 01:28:28 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

knightly

James, in the course of hunting for the default waiting time bugs, I suddenly realised something :

Since connexions are rebuilt on demand (that is, only when paths are requested), there is a pitfall that we have overlooked. Although connexions are indeed rebuilt when requesting paths from a certain halt, *only* connexions of that origin halt are updated. We have forgotten to check if any intermediary halts along the searched paths also need to rebuild connexions.

A typical example would be the global update which occurs every other month, where all paths and all connexions become stale at the same time. Immediately after this, if a path is requested from a halt, that halt rebuilds its connexions before path searching, but the intermediary stops along the search paths haven't rebuilt their connexions, meaning that the paths are not really up-to-date -- they are just pseudo fresh paths.

Thus, I think we need to apply a connexions staleness check on current_node and invoke rebuild_connexions(c) upon it whenever necessary, to ensure that their connexions are up-to-date for us to build truly fresh paths. I would suggest adding such check and call in the following part of code from calculate_paths() :



while(open_list.get_count() > 0 && iterations < max_iterations)
{
current_node = open_list.pop();

if(!current_node->halt.is_bound() || paths[category].get(current_node->halt).journey_time != 65535)
{
// Only insert into the open list if the
// item is not already on the closed list,
// and the halt has not been deleted since
// being added to the open list.
continue;
}

***************   Add Check and Conditional Call Here  *****************

current_connexions = current_node->halt->get_connexions(category);
quickstone_hashtable_iterator_tpl<haltestelle_t, connexion*> iter(*current_connexions);
#ifdef AVOID_ROGUE_VIAS_2
linehandle_t previous_best_line;
convoihandle_t previous_best_convoy;
if(current_node->link != NULL)
{
previous_connexion = current_node->link->halt->get_connexions(category)->get(current_node->halt);
if(previous_connexion != NULL)
{
previous_best_line = previous_connexion->best_line;
previous_best_convoy = previous_connexion->best_convoy;
}
}
#endif
while(iter.next() && iterations <= max_iterations)
{
next_halt = iter.get_current_key();
if(paths[category].get(next_halt).journey_time != 65535)
{
// Only insert into the open list if the
// item is not already on the closed list.
continue;
}

current_connexion = iter.get_current_value();




As shown above in the line with ******, that would be done right before fetching connexion objects from the current_node.

jamespetts

Interesting - thank you for spotting that. The sensible place, I think, though, would be in the get_connexions(uint8 category) method, though, wouldn't it? I am not currently on the computer with the code, but I thought that I already put it in there. If I haven't, that's an omission that I need to remedy. Thank you for spotting that!
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

knightly

You are right. It's already included in get_connexions(). Really sorry that I didn't realise this.

jamespetts

Ahh, don't worry - better to spot too many bugs than too few. Your continued work is very much appreciated.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.