From: jingui.ren Date: Fri, 26 Oct 2018 05:41:27 +0000 (+0800) Subject: optimize the algorithm of get_top_order X-Git-Tag: submit/devel/20190730.074511~2^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2f7e94f7d17ee115192f12b3fc7a88641926f737;p=tools%2Fdepanneur.git optimize the algorithm of get_top_order Change-Id: I310e9425beb75bae53f72218d96ef42be5def21d --- diff --git a/depanneur b/depanneur index d77ecb6..2b08728 100755 --- a/depanneur +++ b/depanneur @@ -1398,92 +1398,36 @@ sub check_circle { } #--------------------------------------------------------------------- -#Get one package's dependence -#Eg: A->B->C->(D H) -#if we get_ddeps_list(A) ,will get @{D H C B} -#--------------------------------------------------------------------- -sub get_ddeps_list { - my $pack = shift; - my @list = (); - - if (! defined($pkgddeps{$pack}) || - scalar $pkgddeps{$pack} == 0 - ) { - return @list; - } - - for my $name (@{ $pkgddeps{$pack} }) { - push @list, get_ddeps_list($name); - push @list, $name; - } - - return @list; -} - -#--------------------------------------------------------------------- -# generate topological sort sequence from global %pkgddeps +# according to BFS to solve topological sorting issue #--------------------------------------------------------------------- sub get_top_order { - my @top_order = (); - my %ref = (); - my $max = 0; - - for my $pack (sort keys %pkgddeps) { - $ref{$pack} = 0; - } - - for my $pack (sort keys %pkgddeps) { - next if (! defined($pkgddeps{$pack})); - for (@{$pkgddeps{$pack} }) { - $ref{$_} += 1; + my @queue = (); + my @top_order = (); + my %ref_build_complete = (); + for my $pack (sort keys %pkgddeps) { + $ref_build_complete{$pack} = 0; + my $pack_in_degree = 0; + if (defined $pkgddeps{$pack}) { + $pack_in_degree = @{$pkgddeps{$pack}}; + } + if ($pack_in_degree == 0) { + push @queue, $pack; + } } - } - - for my $pkg (sort keys %ref) { - if ($max < ($ref{$pkg})) { - $max = ($ref{$pkg}); - } - } - - while (@top_order != scalar (keys %pkgddeps)) { - - for my $pkg (sort keys %ref) { - if ($ref{$pkg} == $max) { - push @top_order, $pkg; - delete $ref{$pkg}; - } else { - $ref{$pkg} += 1; - } - } - } - - my @final_order = (); - for my $name (@top_order) { - next if (! defined($pkgddeps{$name})); - next if ( grep $_ eq $name, @final_order) ; - my @cnt = @{$pkgddeps{$name} }; - if (scalar(@cnt) == 0) { - push @final_order, $name; - } else { - for my $list_pk (@cnt){ - next if ( grep $_ eq $list_pk, @final_order); - - my @tmp_order = get_ddeps_list($list_pk); - for my $pk (@tmp_order) { - if (! grep $_ eq $pk, @final_order) { - push @final_order, $pk; - } - } - push @final_order, $list_pk; - } - push @final_order, $name; - } - } - - return @final_order; + while(@queue) { + my $cur_pack = shift @queue; + push @top_order, $cur_pack; + #print "write $cur_pack\n"; + for (@{$pkgrddeps{$cur_pack}}) { + $ref_build_complete{$_} += 1; + if (@{$pkgddeps{$_}} == $ref_build_complete{$_}) { + push @queue, $_; + } + } + } + return @top_order; } - #--------------------------------------------------------------------- # update dependencies of every packages not build yet #--------------------------------------------------------------------- @@ -1574,7 +1518,7 @@ sub update_pkgddeps { my @top_order = get_top_order(); if ($get_order == 0) { @build_order = @top_order; - $get_order = 1; + $get_order = 1; } %pkgdeps = ();