Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java')
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java123
1 files changed, 56 insertions, 67 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
index 59e8eb271..ba401bbd0 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
@@ -11,6 +11,7 @@
* Jed Anderson - switch from opb files to API calls to DependencyHelper in bug 200380
* Sonatype, Inc. - ongoing development
* Rapicorp, Inc. - split the optimization function
+ * Red Hat, Inc. - support for remediation page
******************************************************************************/
package org.eclipse.equinox.internal.p2.director;
@@ -27,9 +28,10 @@ import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.osgi.util.NLS;
+import org.sat4j.minisat.restarts.LubyRestarts;
import org.sat4j.pb.*;
-import org.sat4j.pb.tools.DependencyHelper;
-import org.sat4j.pb.tools.WeightedObject;
+import org.sat4j.pb.core.PBSolverResolution;
+import org.sat4j.pb.tools.*;
import org.sat4j.specs.*;
/**
@@ -53,7 +55,7 @@ public class Projector {
private IQueryable<IInstallableUnit> picker;
private QueryableArray patches;
- private Map<IInstallableUnit, AbstractVariable> noopVariables; //key IU, value AbstractVariable
+ private List<AbstractVariable> allOptionalAbstractRequirements;
private List<AbstractVariable> abstractVariables;
private Map<String, Map<Version, IInstallableUnit>> slice; //The IUs that have been considered to be part of the problem
@@ -78,6 +80,9 @@ public class Projector {
private Map<IInstallableUnit, AbstractVariable> nonGreedyVariables = new HashMap<IInstallableUnit, AbstractVariable>();
private Map<AbstractVariable, List<Object>> nonGreedyProvider = new HashMap<AbstractVariable, List<Object>>(); //Keeps track of all the "object" that provide an IU that is non greedly requested
+ private boolean emptyBecauseFiltered;
+ private boolean userDefinedFunction;
+
static class AbstractVariable {
// private String name;
@@ -154,24 +159,19 @@ public class Projector {
public Projector(IQueryable<IInstallableUnit> q, Map<String, String> context, Set<IInstallableUnit> nonGreedyIUs, boolean considerMetaRequirements) {
picker = q;
- noopVariables = new HashMap<IInstallableUnit, AbstractVariable>();
slice = new HashMap<String, Map<Version, IInstallableUnit>>();
selectionContext = InstallableUnit.contextIU(context);
abstractVariables = new ArrayList<AbstractVariable>();
+ allOptionalAbstractRequirements = new ArrayList<AbstractVariable>();
result = new MultiStatus(DirectorActivator.PI_DIRECTOR, IStatus.OK, Messages.Planner_Problems_resolving_plan, null);
assumptions = new ArrayList<Object>();
this.nonGreedyIUs = nonGreedyIUs;
this.considerMetaRequirements = considerMetaRequirements;
}
- // protected boolean isInstalled(IInstallableUnit iu) {
- // return !lastState.query(QueryUtil.createIUQuery(iu), null).isEmpty();
- // }
-
@SuppressWarnings("unchecked")
public void encode(IInstallableUnit entryPointIU, IInstallableUnit[] alreadyExistingRoots, IQueryable<IInstallableUnit> installedIUs, Collection<IInstallableUnit> newRoots, IProgressMonitor monitor) {
alreadyInstalledIUs = Arrays.asList(alreadyExistingRoots);
- // numberOfInstalledIUs = sizeOf(installedIUs);
lastState = installedIUs;
this.entryPoint = entryPointIU;
try {
@@ -184,7 +184,14 @@ public class Projector {
if (DEBUG_ENCODING) {
solver = new UserFriendlyPBStringSolver<Object>();
} else {
- solver = SolverFactory.newEclipseP2();
+ if (userDefinedFunction) {
+ PBSolverResolution mysolver = SolverFactory.newCompetPBResLongWLMixedConstraintsObjectiveExpSimp();
+ mysolver.setSimplifier(mysolver.SIMPLE_SIMPLIFICATION);
+ mysolver.setRestartStrategy(new LubyRestarts(512));
+ solver = mysolver;
+ } else {
+ solver = SolverFactory.newEclipseP2();
+ }
}
int timeout = DEFAULT_SOLVER_TIMEOUT;
String timeoutString = null;
@@ -204,10 +211,13 @@ public class Projector {
solver.setTimeoutOnConflicts(timeout);
IQueryResult<IInstallableUnit> queryResult = picker.query(QueryUtil.createIUAnyQuery(), null);
if (DEBUG_ENCODING) {
- dependencyHelper = new DependencyHelper<Object, Explanation>(solver, false);
+ dependencyHelper = new LexicoHelper<Object, Explanation>(solver, false);
((UserFriendlyPBStringSolver<Object>) solver).setMapping(dependencyHelper.getMappingToDomain());
} else {
- dependencyHelper = new DependencyHelper<Object, Explanation>(solver);
+ if (userDefinedFunction)
+ dependencyHelper = new LexicoHelper<Object, Explanation>(solver);
+ else
+ dependencyHelper = new DependencyHelper<Object, Explanation>(solver);
}
List<IInstallableUnit> iusToOrder = new ArrayList<IInstallableUnit>(queryResult.toSet());
Collections.sort(iusToOrder);
@@ -255,13 +265,28 @@ public class Projector {
}
+ private void createOptimizationFunction(IInstallableUnit entryPointIU, Collection<IInstallableUnit> newRoots) {
+ if (!userDefinedFunction) {
+ createStandardOptimizationFunction(entryPointIU, newRoots);
+ } else {
+ createUserDefinedOptimizationFunction(entryPointIU, newRoots);
+ }
+ }
+
//Create an optimization function favoring the highest version of each IU
- private void createOptimizationFunction(IInstallableUnit metaIu, Collection<IInstallableUnit> newRoots) {
- List<WeightedObject<? extends Object>> weights = new OptimizationFunction(lastState, abstractVariables, picker, selectionContext, slice).createOptimizationFunction(metaIu, newRoots);
+ private void createStandardOptimizationFunction(IInstallableUnit entryPointIU, Collection<IInstallableUnit> newRoots) {
+ List<WeightedObject<? extends Object>> weights = new OptimizationFunction(lastState, abstractVariables, allOptionalAbstractRequirements, picker, selectionContext, slice).createOptimizationFunction(entryPointIU, newRoots);
+ createObjectiveFunction(weights);
+ }
+
+ private void createUserDefinedOptimizationFunction(IInstallableUnit entryPointIU, Collection<IInstallableUnit> newRoots) {
+ List<WeightedObject<? extends Object>> weights = new UserDefinedOptimizationFunction(lastState, abstractVariables, allOptionalAbstractRequirements, picker, selectionContext, slice, dependencyHelper, alreadyInstalledIUs).createOptimizationFunction(entryPointIU, newRoots);
createObjectiveFunction(weights);
}
private void createObjectiveFunction(List<WeightedObject<? extends Object>> weightedObjects) {
+ if (weightedObjects == null)
+ return;
if (DEBUG) {
StringBuffer b = new StringBuffer();
for (WeightedObject<? extends Object> object : weightedObjects) {
@@ -399,6 +424,7 @@ public class Projector {
addNonGreedyProvider(getNonGreedyVariable(current), abs);
}
}
+ optionalAbstractRequirements.add(abs);
} else {
abs = getAbstractVariable(req, false);
List<Object> newConstraint = new ArrayList<Object>();
@@ -408,7 +434,6 @@ public class Projector {
}
createImplication(new Object[] {abs, iu}, newConstraint, Explanation.OPTIONAL_REQUIREMENT);
}
- optionalAbstractRequirements.add(abs);
}
}
}
@@ -425,11 +450,9 @@ public class Projector {
private void expandRequirements(Collection<IRequirement> reqs, IInstallableUnit iu, boolean isRootIu) throws ContradictionException {
if (reqs.isEmpty())
return;
- List<AbstractVariable> optionalAbstractRequirements = new ArrayList<AbstractVariable>();
for (IRequirement req : reqs) {
- expandRequirement(req, iu, optionalAbstractRequirements, isRootIu);
+ expandRequirement(req, iu, allOptionalAbstractRequirements, isRootIu);
}
- createOptionalityExpression(iu, optionalAbstractRequirements);
}
public void processIU(IInstallableUnit iu, boolean isRootIU) throws ContradictionException {
@@ -452,7 +475,7 @@ public class Projector {
expandRequirements(getRequiredCapabilities(iu), iu, isRootIU);
} else {
//Patches are applicable to the IU
- expandRequirementsWithPatches(iu, applicablePatches, isRootIU);
+ expandRequirementsWithPatches(iu, applicablePatches, allOptionalAbstractRequirements, isRootIU);
}
}
@@ -480,7 +503,7 @@ public class Projector {
Object left;
}
- private void expandRequirementsWithPatches(IInstallableUnit iu, IQueryResult<IInstallableUnit> applicablePatches, boolean isRootIu) throws ContradictionException {
+ private void expandRequirementsWithPatches(IInstallableUnit iu, IQueryResult<IInstallableUnit> applicablePatches, List<AbstractVariable> optionalAbstractRequirements, boolean isRootIu) throws ContradictionException {
//Unmodified dependencies
Collection<IRequirement> iuRequirements = getRequiredCapabilities(iu);
Map<IRequirement, List<IInstallableUnitPatch>> unchangedRequirements = new HashMap<IRequirement, List<IInstallableUnitPatch>>(iuRequirements.size());
@@ -496,7 +519,6 @@ public class Projector {
// noop(IU)-> ~ABS
// IU -> (noop(IU) or ABS)
// Therefore we only need one optional requirement statement per IU
- List<AbstractVariable> optionalAbstractRequirements = new ArrayList<AbstractVariable>();
for (int i = 0; i < reqs.length; i++) {
//The requirement is unchanged
if (reqs[i][0] == reqs[i][1]) {
@@ -568,6 +590,7 @@ public class Projector {
addNonGreedyProvider(getNonGreedyVariable(current), abs);
}
}
+ optionalAbstractRequirements.add(abs);
} else {
abs = getAbstractVariable(req, false);
List<Object> newConstraint = new ArrayList<Object>(matches.size());
@@ -577,7 +600,6 @@ public class Projector {
}
createImplication(new Object[] {patch, abs, iu}, newConstraint, Explanation.OPTIONAL_REQUIREMENT);
}
- optionalAbstractRequirements.add(abs);
}
}
}
@@ -683,7 +705,6 @@ public class Projector {
}
}
}
- createOptionalityExpression(iu, optionalAbstractRequirements);
}
// Fix: now create the pending non-patch requirements based on the full set of patches
@@ -691,7 +712,6 @@ public class Projector {
createImplication(pending.left, pending.matches, pending.explanation);
}
- List<AbstractVariable> optionalAbstractRequirements = new ArrayList<AbstractVariable>();
for (Entry<IRequirement, List<IInstallableUnitPatch>> entry : unchangedRequirements.entrySet()) {
List<IInstallableUnitPatch> patchesApplied = entry.getValue();
Iterator<IInstallableUnit> allPatches = applicablePatches.iterator();
@@ -779,7 +799,6 @@ public class Projector {
}
}
}
- createOptionalityExpression(iu, optionalAbstractRequirements);
}
private void expandLifeCycle(IInstallableUnit iu, boolean isRootIu) throws ContradictionException {
@@ -797,8 +816,6 @@ public class Projector {
createNegation(iu, req);
}
- private boolean emptyBecauseFiltered;
-
/**
* @param req
* @return a list of mandatory requirements if any, an empty list if req.isOptional().
@@ -828,7 +845,7 @@ public class Projector {
for (int i = 0; i < changes.size(); i++) {
IRequirementChange change = changes.get(i);
for (int j = 0; j < originalRequirements.length; j++) {
- if (originalRequirements[j] != null && change.matches((IRequiredCapability) originalRequirements[j])) {
+ if (originalRequirements[j] != null && safeMatch(originalRequirements, change, j)) {
found = true;
if (change.newValue() != null)
rrr.add(new IRequirement[] {originalRequirements[j], change.newValue()});
@@ -850,24 +867,12 @@ public class Projector {
return rrr.toArray(new IRequirement[rrr.size()][]);
}
- /**
- * Optional requirements are encoded via:
- * ABS -> (match1(req) or match2(req) or ... or matchN(req))
- * noop(IU)-> ~ABS
- * IU -> (noop(IU) or ABS)
- * @param iu
- * @param optionalRequirements
- * @throws ContradictionException
- */
- private void createOptionalityExpression(IInstallableUnit iu, List<AbstractVariable> optionalRequirements) throws ContradictionException {
- if (optionalRequirements.isEmpty())
- return;
- AbstractVariable noop = getNoOperationVariable(iu);
- for (AbstractVariable abs : optionalRequirements) {
- createIncompatibleValues(abs, noop);
+ private boolean safeMatch(IRequirement[] originalRequirements, IRequirementChange change, int j) {
+ try {
+ return change.matches((IRequiredCapability) originalRequirements[j]);
+ } catch (ClassCastException e) {
+ return false;
}
- optionalRequirements.add(noop);
- createImplication(iu, optionalRequirements, Explanation.OPTIONAL_REQUIREMENT);
}
//This will create as many implication as there is element in the right argument
@@ -948,18 +953,6 @@ public class Projector {
dependencyHelper.atMost(1, (Object[]) ius).named(new Explanation.Singleton(ius));
}
- private void createIncompatibleValues(AbstractVariable v1, AbstractVariable v2) throws ContradictionException {
- AbstractVariable[] vars = {v1, v2};
- if (DEBUG) {
- StringBuffer b = new StringBuffer();
- for (int i = 0; i < vars.length; i++) {
- b.append(vars[i].toString());
- }
- Tracing.debug("At most 1 of " + b); //$NON-NLS-1$
- }
- dependencyHelper.atMost(1, (Object[]) vars).named(Explanation.OPTIONAL_REQUIREMENT);
- }
-
private AbstractVariable getAbstractVariable(IRequirement req) {
return getAbstractVariable(req, true);
}
@@ -972,15 +965,6 @@ public class Projector {
return abstractVariable;
}
- private AbstractVariable getNoOperationVariable(IInstallableUnit iu) {
- AbstractVariable v = noopVariables.get(iu);
- if (v == null) {
- v = DEBUG_ENCODING ? new AbstractVariable("Noop_" + iu.toString()) : new AbstractVariable(); //$NON-NLS-1$
- noopVariables.put(iu, v);
- }
- return v;
- }
-
private AbstractVariable getNonGreedyVariable(IInstallableUnit iu) {
AbstractVariable v = nonGreedyVariables.get(iu);
if (v == null) {
@@ -1007,7 +991,7 @@ public class Projector {
backToIU();
long stop = System.currentTimeMillis();
if (DEBUG)
- Tracing.debug("Solver solution found: " + (stop - start)); //$NON-NLS-1$
+ Tracing.debug("Solver solution found in: " + (stop - start) + " ms."); //$NON-NLS-1$
} else {
long stop = System.currentTimeMillis();
if (DEBUG) {
@@ -1029,6 +1013,7 @@ public class Projector {
private void backToIU() {
solution = new ArrayList<IInstallableUnit>();
+ //TODO WORK AROUND BECAUE OF A BUG IN SAT4J
IVec<Object> sat4jSolution = dependencyHelper.getSolution();
for (Iterator<Object> iter = sat4jSolution.iterator(); iter.hasNext();) {
Object var = iter.next();
@@ -1111,4 +1096,8 @@ public class Projector {
}
existingMatches.retainAll(matches);
}
+
+ public void setUserDefined(boolean containsKey) {
+ userDefinedFunction = containsKey;
+ }
} \ No newline at end of file

Back to the top