Merge remote-tracking branch 'olvlvl/improved_package_sorting_alone'
commit
d26dda5c95
|
@ -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];
|
|
||||||
if ($positions[$target] <= $position) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($positions as $key => $value) {
|
|
||||||
if ($value >= $position) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$positions[$key]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
$positions[$target] = $position - 1;
|
|
||||||
}
|
}
|
||||||
asort($positions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$computing = array();
|
||||||
|
$computed = array();
|
||||||
|
$computeImportance = function($name) use(&$computeImportance, &$computing, &$computed, $usageList) {
|
||||||
|
// reusing computed importance
|
||||||
|
if (isset($computed[$name])) {
|
||||||
|
return $computed[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
// canceling circular dependency
|
||||||
|
if (isset($computing[$name])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$computing[$name] = true;
|
||||||
|
$weight = 0;
|
||||||
|
|
||||||
|
if (isset($usageList[$name])) {
|
||||||
|
foreach ($usageList[$name] as $user) {
|
||||||
|
$weight -= 1 - $computeImportance($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($computing[$name]);
|
||||||
|
$computed[$name] = $weight;
|
||||||
|
|
||||||
|
return $weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
$weightList = array();
|
||||||
|
|
||||||
|
foreach ($packages as $name => $package) {
|
||||||
|
$weight = $computeImportance($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;
|
||||||
|
|
Loading…
Reference in New Issue