Skip to content

Commit

Permalink
Clean-up and simplify Slicer, PermissiveSlicer ans SimplePlanner
Browse files Browse the repository at this point in the history
  • Loading branch information
HannesWell committed Oct 21, 2023
1 parent 158291b commit 571da71
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 271 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,94 +14,68 @@
package org.eclipse.equinox.internal.p2.director;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.query.QueryUtil;

public class AttachmentHelper {
private static final IInstallableUnitFragment[] NO_FRAGMENTS = new IInstallableUnitFragment[0];

public static Collection<IInstallableUnit> attachFragments(Iterator<IInstallableUnit> toAttach, Map<IInstallableUnitFragment, List<IInstallableUnit>> fragmentsToIUs) {
public static Collection<IInstallableUnit> attachFragments(Stream<IInstallableUnit> toAttach,
Map<IInstallableUnitFragment, List<IInstallableUnit>> fragmentsToIUs) {
Map<IInstallableUnit, IInstallableUnitFragment[]> fragmentBindings = new HashMap<>();
//Build a map inverse of the one provided in input (host --> List of fragments)
Map<IInstallableUnit, List<IInstallableUnitFragment>> iusToFragment = new HashMap<>(fragmentsToIUs.size());
for (Map.Entry<IInstallableUnitFragment, List<IInstallableUnit>> mapping : fragmentsToIUs.entrySet()) {
IInstallableUnitFragment fragment = mapping.getKey();
List<IInstallableUnit> existingMatches = mapping.getValue();

fragmentsToIUs.forEach((fragment, existingMatches) -> {
for (IInstallableUnit host : existingMatches) {
List<IInstallableUnitFragment> potentialFragments = iusToFragment.get(host);
if (potentialFragments == null) {
potentialFragments = new ArrayList<>();
iusToFragment.put(host, potentialFragments);
}
potentialFragments.add(fragment);
iusToFragment.computeIfAbsent(host, h -> new ArrayList<>()).add(fragment);
}
}
});

for (Map.Entry<IInstallableUnit, List<IInstallableUnitFragment>> entry : iusToFragment.entrySet()) {
IInstallableUnit hostIU = entry.getKey();
List<IInstallableUnitFragment> potentialIUFragments = entry.getValue();
ArrayList<IInstallableUnitFragment> applicableFragments = new ArrayList<>();
iusToFragment.forEach((hostIU, potentialIUFragments) -> {
List<IInstallableUnitFragment> applicableFragments = new ArrayList<>();
for (IInstallableUnitFragment potentialFragment : potentialIUFragments) {
if (hostIU.equals(potentialFragment))
if (hostIU.equals(potentialFragment)) {
continue;

}
// Check to make sure the host meets the requirements of the fragment
Collection<IRequirement> reqsFromFragment = potentialFragment.getHost();
boolean match = true;
boolean requirementMatched = false;
for (Iterator<IRequirement> iterator = reqsFromFragment.iterator(); iterator.hasNext() && match == true;) {
IRequirement reqs = iterator.next();
requirementMatched = false;
if (hostIU.satisfies(reqs))
requirementMatched = true;
if (requirementMatched == false) {
match = false;
break;
}

}
if (match) {
if (reqsFromFragment.stream().allMatch(hostIU::satisfies)) {
applicableFragments.add(potentialFragment);
}
}

IInstallableUnitFragment theFragment = null;
int specificityLevel = 0;
LinkedList<IInstallableUnitFragment> fragments = new LinkedList<>();
Deque<IInstallableUnitFragment> fragments = new LinkedList<>();
for (IInstallableUnitFragment fragment : applicableFragments) {
if (isTranslation(fragment)) {
fragments.add(fragment);
fragments.addLast(fragment);
continue;
}
if (fragment.getHost().size() > specificityLevel) {
theFragment = fragment;
specificityLevel = fragment.getHost().size();
}
}
if (theFragment != null)
if (theFragment != null) {
fragments.addFirst(theFragment);
if (!fragments.isEmpty())
fragmentBindings.put(hostIU, fragments.toArray(new IInstallableUnitFragment[fragments.size()]));
}
}
if (!fragments.isEmpty()) {
fragmentBindings.put(hostIU, fragments.toArray(IInstallableUnitFragment[]::new));
}
});
//build the collection of resolved IUs
Collection<IInstallableUnit> result = new HashSet<>();
while (toAttach.hasNext()) {
IInstallableUnit iu = toAttach.next();
if (iu == null)
continue;
return toAttach.filter(Objects::nonNull).map(iu -> {
//just return fragments as they are
if (QueryUtil.isFragment(iu)) {
result.add(iu);
continue;
return iu;
}
//return a new IU that combines the IU with its bound fragments
IInstallableUnitFragment[] fragments = fragmentBindings.get(iu);
if (fragments == null)
fragments = NO_FRAGMENTS;
result.add(MetadataFactory.createResolvedInstallableUnit(iu, fragments));
}
return result;
IInstallableUnitFragment[] fragments = fragmentBindings.getOrDefault(iu, NO_FRAGMENTS);
return (MetadataFactory.createResolvedInstallableUnit(iu, fragments));
}).collect(Collectors.toSet());
}

private static boolean isTranslation(IInstallableUnitFragment fragment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public List<WeightedObject<? extends Object>> createOptimizationFunction(IInstal
if (newRoots.isEmpty()) {
transitiveClosure = Collections.emptySet();
} else {
IQueryable<IInstallableUnit> queryable = new Slicer(picker, selectionContext, false).slice(newRoots.toArray(new IInstallableUnit[newRoots.size()]), new NullProgressMonitor());
IQueryable<IInstallableUnit> queryable = new Slicer(picker, selectionContext, false).slice(newRoots, null);
if (queryable == null) {
transitiveClosure = Collections.emptySet();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.IQueryable;

public class PermissiveSlicer extends Slicer {
Expand All @@ -29,7 +30,7 @@ public class PermissiveSlicer extends Slicer {

public PermissiveSlicer(IQueryable<IInstallableUnit> input, Map<String, String> context, boolean includeOptionalDependencies, boolean everythingGreedy, boolean evalFilterTo, boolean considerOnlyStrictDependency, boolean onlyFilteredRequirements) {
super(input, context, true);
this.considerFilter = (context != null && context.size() > 1) ? true : false;
this.considerFilter = context != null && context.size() > 1;
this.includeOptionalDependencies = includeOptionalDependencies;
this.everythingGreedy = everythingGreedy;
this.evalFilterTo = evalFilterTo;
Expand All @@ -39,45 +40,31 @@ public PermissiveSlicer(IQueryable<IInstallableUnit> input, Map<String, String>

@Override
protected boolean isApplicable(IInstallableUnit iu) {
if (considerFilter)
if (considerFilter) {
return super.isApplicable(iu);
if (iu.getFilter() == null)
return true;
return evalFilterTo;
}
return iu.getFilter() == null || evalFilterTo;
}

@Override
protected boolean isApplicable(IRequirement req) {
//Every filter in this method needs to continue except when the filter does not pass
if (!includeOptionalDependencies)
if (req.getMin() == 0)
return false;

if (considerOnlyStrictDependency) {
if (!RequiredCapability.isStrictVersionRequirement(req.getMatches()))
return false;
if (!includeOptionalDependencies && req.getMin() == 0) {
return false;
}

//deal with filters
if (considerFilter) {
if (onlyFilteredRequirements && req.getFilter() == null) {
return false;
}
return super.isApplicable(req);
if (considerOnlyStrictDependency && !RequiredCapability.isStrictVersionRequirement(req.getMatches())) {
return false;
}
if (req.getFilter() == null) {
if (onlyFilteredRequirements)
return false;
return true;
//deal with filters
IMatchExpression<IInstallableUnit> filter = req.getFilter();
if (filter == null) {
return !onlyFilteredRequirements;
}
return evalFilterTo;
return considerFilter ? filter.isMatch(selectionContext) : evalFilterTo;
}

@Override
protected boolean isGreedy(IRequirement req) {
if (everythingGreedy) {
return true;
}
return super.isGreedy(req);
return everythingGreedy || super.isGreedy(req);
}
}
Loading

0 comments on commit 571da71

Please sign in to comment.