summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2016-04-29 21:26:09 +0200
committerDaniel Friesel <derf@finalrewind.org>2016-04-29 21:26:09 +0200
commit694bde71f8d6abc6c0cfcc7f96ba850abf597a90 (patch)
tree7282c650994aed70c5edd289969ed81b5970b9c6
parentdc92c7f29cbbb8d2d6e93f8fca06646bc7a42627 (diff)
Use iterative related-station fetch instead of recursive approach
-rw-r--r--lib/Travel/Status/DE/IRIS.pm94
1 files changed, 42 insertions, 52 deletions
diff --git a/lib/Travel/Status/DE/IRIS.pm b/lib/Travel/Status/DE/IRIS.pm
index 347b68a..4e3cad4 100644
--- a/lib/Travel/Status/DE/IRIS.pm
+++ b/lib/Travel/Status/DE/IRIS.pm
@@ -160,65 +160,55 @@ sub get_station {
my ( $self, %opt ) = @_;
my @ret;
- my $recursion_depth = $opt{recursion_depth} // 0;
-
- my ( $raw, $err )
- = $self->get_with_cache( $self->{main_cache},
- $self->{iris_base} . '/station/' . $opt{name} );
- if ($err) {
- $self->{errstr} = "Failed to fetch station data: $err";
- return;
- }
-
- my $xml_st = XML::LibXML->load_xml( string => $raw );
+ my @queue = ( $opt{name} );
+ my @seen;
+
+ while (@queue) {
+ my $station = shift(@queue);
+ push( @seen, $station );
+
+ my ( $raw, $err )
+ = $self->get_with_cache( $self->{main_cache},
+ $self->{iris_base} . '/station/' . $station );
+ if ($err) {
+ $self->{errstr} = "Failed to fetch station data: $err";
+ return;
+ }
- my $station_node = ( $xml_st->findnodes('//station') )[0];
+ my $xml_st = XML::LibXML->load_xml( string => $raw );
- if ( not $station_node ) {
- if ( $opt{root} ) {
- $self->{errstr}
- = "The station '$opt{name}' has no associated timetable";
- }
- return;
- }
- if ( $recursion_depth > 5 ) {
- cluck("Reached recursion depth $recursion_depth while tracking IDs");
- return;
- }
+ my $station_node = ( $xml_st->findnodes('//station') )[0];
- push(
- @ret,
- {
- uic => $station_node->getAttribute('eva'),
- name => $station_node->getAttribute('name'),
- ds100 => $station_node->getAttribute('ds100'),
+ if ( not $station_node ) {
+ if ( $opt{root} ) {
+ $self->{errstr}
+ = "The station '$opt{name}' has no associated timetable";
+ return;
+ }
+ next;
}
- );
- if ( $self->{developer_mode} ) {
- printf( " -> %s (%s / %s)\n", @{ $ret[0] }{qw{name uic ds100}} );
- }
+ push( @seen, $station_node->getAttribute('eva') );
- # TODO this approach is flawed, iterative is probably better
-
- if ( $opt{recursive} and $station_node->hasAttribute('meta') ) {
- my @recursion_blacklist = @{ $opt{recursion_blacklist} // [] };
- my @refs = uniq(split( m{ \| }x, $station_node->getAttribute('meta') ));
-
- push( @recursion_blacklist, map { $_->{uic} } @ret );
-
- for my $ref (@refs) {
- if ( not( $ref ~~ \@recursion_blacklist ) ) {
- push(
- @ret,
- $self->get_station(
- name => $ref,
- recursive => 1,
- recursion_depth => $recursion_depth + 1,
- recursion_blacklist => \@recursion_blacklist,
- )
- );
+ push(
+ @ret,
+ {
+ uic => $station_node->getAttribute('eva'),
+ name => $station_node->getAttribute('name'),
+ ds100 => $station_node->getAttribute('ds100'),
}
+ );
+
+ if ( $self->{developer_mode} ) {
+ printf( " -> %s (%s / %s)\n", @{ $ret[-1] }{qw{name uic ds100}} );
+ }
+
+ if ( $opt{recursive} ) {
+ my @refs
+ = uniq( split( m{ \| }x, $station_node->getAttribute('meta') ) );
+ @refs = grep { not( $_ ~~ \@seen or $_ ~~ \@queue ) } @refs;
+ push( @queue, @refs );
+ $opt{root} = 0;
}
}