prt-auf: replace Fun's algorithm with a depth-first search
This commit is contained in:
parent
bc438288c5
commit
99d51f625d
@ -671,38 +671,38 @@ sub port_diff { # find differences between the pkgdb and the repo
|
||||
}
|
||||
|
||||
sub deporder { # returns a sorted list of packages required.
|
||||
my $type=shift; my @seeds=@_; our @treewalk=(); our %missing;
|
||||
our %level = map { $_ => 1 } @seeds; our $maxLevel=1; my @result;
|
||||
my $type=shift; my @seeds=@_; our @treewalk=(); our %missing; our @result;
|
||||
our %given = map { $_ => 1 } @seeds; our %imark=(); our %fmark=();
|
||||
|
||||
# determine the minimal set of targets needed to satisfy all dependencies
|
||||
foreach my $t (@seeds) { recurse_deptree(0,1,$t); }
|
||||
foreach my $t (@seeds) { recurse_deptree(0,$t); }
|
||||
|
||||
sub recurse_deptree {
|
||||
my $greedy=shift; my $thisLevel=shift; my $s=shift; my %curdeps;
|
||||
my $greedy=shift; my $s=shift; my %curdeps=();
|
||||
|
||||
# detect any dependencies that have been dropped from the repositories
|
||||
if (! $V_REPO{$s}) { $missing{$s}=1; delete $level{$s}; return; }
|
||||
# early return if this node has been visited already
|
||||
if ($fmark{$s}) { return; }
|
||||
|
||||
# cycle detection
|
||||
if (grep /^$s$/, @treewalk) {
|
||||
# detect targets that have been dropped from the repositories
|
||||
if (! $V_REPO{$s}) { $missing{$s}=1; $fmark{$s}=0; return; }
|
||||
|
||||
# dependency cycle detection
|
||||
if ($imark{$s}) {
|
||||
return if ($greedy == 1);
|
||||
print "Dependency cycle found: ";
|
||||
foreach (@treewalk) { print "$_ => "; }
|
||||
print "$s\n";
|
||||
} else { push(@treewalk, $s); }
|
||||
}
|
||||
|
||||
# update the hash table and the height of the tree
|
||||
if ( (! $level{$s}) or ($level{$s} < $thisLevel) ) {
|
||||
$level{$s} = $thisLevel;
|
||||
}
|
||||
if ( $maxLevel < $thisLevel ) { $maxLevel = $thisLevel; }
|
||||
push(@treewalk, $s); $imark{$s}=1;
|
||||
|
||||
# assemble the list of dependencies that must be visited next
|
||||
%curdeps = map { $_ => $greedy } split /[ ,]/, $DEPENDS{$s};
|
||||
|
||||
# if the user toggles --softdeps, consider the optional dependencies
|
||||
# that are already installed or are given on the command line
|
||||
if ($odepends{soft} == 1) {
|
||||
foreach (grep { ($V_INST{$_}) or ($level{$_}) }
|
||||
foreach (grep { ($V_INST{$_}) or ($given{$_}) }
|
||||
split /[ ,]/, $SOFTDEPS{$s}) {
|
||||
$curdeps{$_} = 1;
|
||||
}
|
||||
@ -711,20 +711,15 @@ sub deporder { # returns a sorted list of packages required.
|
||||
foreach my $sd (keys %curdeps) {
|
||||
my $subit = who_aliased_to($sd);
|
||||
if ($subit) {
|
||||
recurse_deptree($curdeps{$sd},$thisLevel+1,$subit);
|
||||
recurse_deptree($curdeps{$sd},$subit);
|
||||
} else {
|
||||
recurse_deptree($curdeps{$sd},$thisLevel+1,$sd);
|
||||
recurse_deptree($curdeps{$sd},$sd);
|
||||
}
|
||||
}
|
||||
pop (@treewalk);
|
||||
|
||||
} # proceed with the topological sort
|
||||
# gather up all the targets farthest from the root of the tree,
|
||||
# then reduce by 1 the level at which to search.
|
||||
while ($maxLevel >= 1) {
|
||||
push(@result, grep { ($level{$_} == $maxLevel) } keys %level);
|
||||
$maxLevel -= 1;
|
||||
}
|
||||
delete $imark{$s}; pop(@treewalk);
|
||||
$fmark{$s} = 1;
|
||||
push(@result, $s);
|
||||
}
|
||||
|
||||
if ((keys %missing > 0) and ($type ne "quickdep")) { push (@result, "MISSING", sort(keys %missing)); }
|
||||
return @result;
|
||||
|
Loading…
Reference in New Issue
Block a user