1
0
Fork 0

Improved package sorting

pull/2644/head
Olivier Laviale 2014-01-29 14:15:32 +01:00
parent 0238aaf5ac
commit 46776c8e23
1 changed files with 70 additions and 32 deletions

View File

@ -611,45 +611,83 @@ FOOTER;
protected function sortPackageMap(array $packageMap) protected function sortPackageMap(array $packageMap)
{ {
$positions = array(); $packages = array();
$names = array(); $paths = array();
$indexes = array(); $usageList = array();
foreach ($packageMap as $position => $item) {
$mainName = $item[0]->getName();
$names = array_merge(array_fill_keys($item[0]->getNames(), $mainName), $names);
$names[$mainName] = $mainName;
$indexes[$mainName] = $positions[$mainName] = $position;
}
foreach ($packageMap as $item) { foreach ($packageMap as $item) {
$position = $positions[$item[0]->getName()]; list($package, $path) = $item;
foreach (array_merge($item[0]->getRequires(), $item[0]->getDevRequires()) as $link) { $name = $package->getName();
$packages[$name] = $package;
$paths[$name] = $path;
foreach (array_merge($package->getRequires(), $package->getDevRequires()) as $link) {
$target = $link->getTarget(); $target = $link->getTarget();
if (!isset($names[$target])) { $usageList[$target][] = $name;
continue; }
} }
$target = $names[$target]; $computing = array();
if ($positions[$target] <= $position) { $computed = array();
continue; $compute_importance = function($name) use(&$compute_importance, &$computing, &$computed, $usageList) {
# reusing computed importance
if (isset($computed[$name])) {
return $computed[$name];
} }
foreach ($positions as $key => $value) { # canceling circular dependency
if ($value >= $position) { if (isset($computing[$name])) {
break; return 0;
}
$positions[$key]--;
} }
$positions[$target] = $position - 1; $computing[$name] = true;
$weight = 0;
if (isset($usageList[$name])) {
foreach ($usageList[$name] as $user) {
$weight -= 1 - $compute_importance($user);
} }
asort($positions);
} }
unset($computing[$name]);
$computed[$name] = $weight;
return $weight;
};
$weightList = array();
foreach ($packages as $name => $package) {
$weight = $compute_importance($name);
$weightList[$name] = $weight;
}
$stable_sort = function(&$array) {
static $transform, $restore;
$i = 0;
if (!$transform) {
$transform = function(&$v, $k) use(&$i) {
$v = array($v, ++$i, $k, $v);
};
$restore = function(&$v, $k) {
$v = $v[3];
};
}
array_walk($array, $transform);
asort($array);
array_walk($array, $restore);
};
$stable_sort($weightList);
$sortedPackageMap = array(); $sortedPackageMap = array();
foreach (array_keys($positions) as $packageName) {
$sortedPackageMap[] = $packageMap[$indexes[$packageName]]; foreach (array_keys($weightList) as $name) {
$sortedPackageMap[] = array($packages[$name], $paths[$name]);
} }
return $sortedPackageMap; return $sortedPackageMap;