}
#---------------------------------------------------------------------
-#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
#---------------------------------------------------------------------
my @top_order = get_top_order();
if ($get_order == 0) {
@build_order = @top_order;
- $get_order = 1;
+ $get_order = 1;
}
%pkgdeps = ();