#include "zypp/base/PtrTypes.h"
#include "zypp/ResPool.h"
+#include "zypp/TriBool.h"
+#include "zypp/base/SerialNumber.h"
#include "zypp/solver/detail/Types.h"
-#include "zypp/solver/detail/ResolverQueue.h"
-#include "zypp/solver/detail/ResolverContext.h"
-#include "zypp/solver/detail/ContextPool.h"
+#include "zypp/solver/detail/SolverQueueItem.h"
#include "zypp/ProblemTypes.h"
#include "zypp/ResolverProblem.h"
#include "zypp/ProblemSolution.h"
-#include "zypp/UpgradeStatistics.h"
-
-#include "zypp/CapSet.h"
+#include "zypp/Capabilities.h"
+#include "zypp/Capability.h"
/////////////////////////////////////////////////////////////////////////
namespace zypp
{ ///////////////////////////////////////////////////////////////////////
+
+ namespace sat
+ {
+ class Transaction;
+ }
+
///////////////////////////////////////////////////////////////////////
namespace solver
{ /////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
+ class SATResolver;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ItemCapKind
+ //
+ /** */
+ struct ItemCapKind
+ {
+ public:
+ Capability cap; //Capability which has triggerd this selection
+ Dep capKind; //Kind of that capability
+ PoolItem item; //Item which has triggered this selection
+ bool initialInstallation; //This item has triggered the installation
+ //Not already fullfilled requierement only.
+
+ ItemCapKind() : capKind(Dep::PROVIDES) {}
+ ItemCapKind( PoolItem i, Capability c, Dep k, bool initial)
+ : cap( c )
+ , capKind( k )
+ , item( i )
+ , initialInstallation( initial )
+ { }
+ };
+ typedef std::multimap<PoolItem,ItemCapKind> ItemCapKindMap;
+ typedef std::list<ItemCapKind> ItemCapKindList;
+
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Resolver
-
+/** A mid layer class we should remove
+ * \todo Merge this and class SATResolver. Logic and date are horribly
+ * distributed between this and SATResolver. Either SATResolver becomes
+ * a pure wrapper adapting the libsolv C interface to fit our needs, and
+ * all the solver logic and problem handling goes here; or completely merge
+ * both classes.
+ */
class Resolver : public base::ReferenceCounted, private base::NonCopyable {
private:
ResPool _pool;
-
- unsigned _timeout_seconds;
- unsigned _maxSolverPasses;
- bool _verifying;
- bool _testing;
-
- // In order reducing solver time we are reducing the branches
- // by skipping resolvables which have worse architecture,edition
- // than a resolvable which provides the same cababilities.
- // BUT if there is no valid solution we will regard the "other"
- // resolvables in a second solver run too.
- bool _tryAllPossibilities; // Try ALL alternatives
-
- // list populated by calls to addPoolItemTo*()
- QueueItemList _initial_items;
- PoolItemList _items_to_install;
- PoolItemList _items_to_establish;
- PoolItemList _items_to_remove;
- PoolItemList _items_to_verify;
- PoolItemList _items_to_lockUninstalled;
-
- // pool of valid contexts which are "recycled" in order to fasten the solver
- ContextPool contextPool;
-
- // list of problematic items after doUpgrade()
- PoolItemList _update_items;
-
-
- CapSet _extra_caps;
- CapSet _extra_conflicts;
-
- //typedef std::multimap<PoolItem_Ref,Capability> IgnoreMap;
-
- // These conflict should be ignored of the concering item
- IgnoreMap _ignoreConflicts;
- // These requires should be ignored of the concering item
- IgnoreMap _ignoreRequires;
- // These obsoletes should be ignored of the concering item
- IgnoreMap _ignoreObsoletes;
- // Ignore architecture of the item
- PoolItemList _ignoreArchitecture;
- // Ignore the status "installed" of the item
- PoolItemList _ignoreInstalledItem;
- // Ignore the architecture of the item
- PoolItemList _ignoreArchitectureItem;
-
-
- ResolverQueueList _pending_queues;
- ResolverQueueList _pruned_queues;
- ResolverQueueList _complete_queues;
- ResolverQueueList _deferred_queues;
- ResolverQueueList _invalid_queues;
-
- int _valid_solution_count;
-
- ResolverContext_Ptr _best_context;
- // Context of the last establishing call ( without any transaction )
- ResolverContext_Ptr _establish_context;
- bool _timed_out;
-
- std::set<Source_Ref> _subscribed;
-
- Arch _architecture;
-
- bool _forceResolve; // remove items which are conflicts with others or
- // have unfulfilled requirements.
- // This behaviour is favourited by ZMD
- bool _upgradeMode; // Resolver has been called with doUpgrade
- bool _preferHighestVersion; // Prefer the result with the newest version
- //if there are more solver results.
+ SATResolver *_satResolver;
+ SerialNumberWatcher _poolchanged;
+
+ CapabilitySet _extra_requires;
+ CapabilitySet _extra_conflicts;
+ std::set<Repository> _upgradeRepos;
+
+ // Regard dependencies of the item weak onl
+ PoolItemList _addWeak;
+
+ /** \name Solver flags */
+ //@{
+ bool _forceResolve; // remove items which are conflicts with others or
+ // have unfulfilled requirements.
+ // This behaviour is favourited by ZMD
+ bool _upgradeMode; // Resolver has been called with doUpgrade
+ bool _updateMode; // Resolver has been called with doUpdate
+ bool _verifying; // The system will be checked
+ bool _onlyRequires; // do install required resolvables only
+ // no recommended resolvables, language
+ // packages, hardware packages (modalias)
+ bool _allowVendorChange; // whether the solver should allow or disallow vendor changes.
+ bool _solveSrcPackages; // whether to generate solver jobs for selected source packges.
+ bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements
+
+ bool _ignoreAlreadyRecommended; //ignore recommended packages that have already been recommended by the installed packages
+ //@}
+
+ // Additional QueueItems which has to be regarded by the solver
+ // This will be used e.g. by solution actions
+ solver::detail::SolverQueueItemList _removed_queue_items;
+ solver::detail::SolverQueueItemList _added_queue_items;
+
+ // Additional information about the solverrun
+ ItemCapKindMap _isInstalledBy;
+ ItemCapKindMap _installs;
+ ItemCapKindMap _satifiedByInstalled;
+ ItemCapKindMap _installedSatisfied;
// helpers
- bool doesObsoleteCapability (PoolItem_Ref candidate, const Capability & cap);
- bool doesObsoleteItem (PoolItem_Ref candidate, PoolItem_Ref installed);
+ void collectResolverInfo();
+
+ // Unmaintained packages which does not fit to the updated system
+ // (broken dependencies) will be deleted.
+ // returns true if solving was successful
+ bool checkUnmaintainedItems ();
+
+ void solverInit();
public:
- Resolver (const ResPool & pool);
+ Resolver( const ResPool & pool );
virtual ~Resolver();
// ---------------------------------- I/O
virtual std::ostream & dumpOn( std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream& str, const Resolver & obj)
+ friend std::ostream& operator<<( std::ostream& str, const Resolver & obj )
{ return obj.dumpOn (str); }
- void dumpTaskList(const PoolItemList &install, const PoolItemList &remove );
-
- // ---------------------------------- accessors
- QueueItemList initialItems () const { return _initial_items; }
-
- ResolverQueueList pendingQueues () const { return _pending_queues; }
- ResolverQueueList prunedQueues () const { return _pruned_queues; }
- ResolverQueueList completeQueues () const { return _complete_queues; }
- ResolverQueueList deferredQueues () const { return _deferred_queues; }
- ResolverQueueList invalidQueues () const { return _invalid_queues; }
+ // ---------------------------------- methods
- ResolverContext_Ptr bestContext (void) const { return _best_context; }
+ ResPool pool() const;
+ void setPool( const ResPool & pool ) { _pool = pool; }
- /** depending on the last solver result, either return bestContext()
- of the first invalid context */
- ResolverContext_Ptr context (void) const;
+ void addUpgradeRepo( Repository repo_r ) { if ( repo_r && ! repo_r.isSystemRepo() ) _upgradeRepos.insert( repo_r ); }
+ bool upgradingRepo( Repository repo_r ) const { return( _upgradeRepos.find( repo_r ) != _upgradeRepos.end() ); }
+ void removeUpgradeRepo( Repository repo_r ) { _upgradeRepos.erase( repo_r ); }
+ void removeUpgradeRepos() { _upgradeRepos.clear(); }
+ const std::set<Repository> & upgradeRepos() const { return _upgradeRepos; }
- // ---------------------------------- methods
+ void addExtraRequire( const Capability & capability );
+ void removeExtraRequire( const Capability & capability );
+ void addExtraConflict( const Capability & capability );
+ void removeExtraConflict( const Capability & capability );
- void setTimeout (int seconds) { _timeout_seconds = seconds; }
- void setMaxSolverPasses (int count) { _maxSolverPasses = count; }
- int timeout () { return _timeout_seconds; }
- int maxSolverPasses () { return _maxSolverPasses; }
+ void removeQueueItem( SolverQueueItem_Ptr item );
+ void addQueueItem( SolverQueueItem_Ptr item );
- ResPool pool (void) const;
- void setPool (const ResPool & pool) { _pool = pool; }
+ CapabilitySet extraRequires() const { return _extra_requires; }
+ CapabilitySet extraConflicts() const { return _extra_conflicts; }
- void addSubscribedSource (Source_Ref source);
+ void addWeak( const PoolItem & item );
- void addPoolItemToInstall (PoolItem_Ref item);
- void addPoolItemsToInstallFromList (PoolItemList & rl);
+ bool verifySystem();
+ bool resolvePool();
+ bool resolveQueue( SolverQueueItemList & queue );
+ void doUpdate();
- void addPoolItemToLockUninstalled (PoolItem_Ref item);
+ bool doUpgrade();
+ PoolItemList problematicUpdateItems() const;
- void addPoolItemToRemove (PoolItem_Ref item);
- void addPoolItemsToRemoveFromList (PoolItemList & rl);
+ /** \name Solver flags */
+ //@{
+ bool ignoreAlreadyRecommended() const { return _ignoreAlreadyRecommended; }
+ void setIgnoreAlreadyRecommended( bool yesno_r ) { _ignoreAlreadyRecommended = yesno_r; }
- void addPoolItemToEstablish (PoolItem_Ref item);
- void addPoolItemsToEstablishFromList (PoolItemList & rl);
+ bool onlyRequires () const { return _onlyRequires; }
+ void setOnlyRequires( TriBool state_r );
- void addPoolItemToVerify (PoolItem_Ref item);
+ bool forceResolve() const { return _forceResolve; }
+ void setForceResolve( TriBool state_r ) { _forceResolve = indeterminate(state_r) ? false : bool(state_r); }
- void addExtraCapability (const Capability & capability);
- void addExtraConflict (const Capability & capability);
+ bool isUpgradeMode() const { return _upgradeMode; }// Resolver has been called with doUpgrade
+ void setUpgradeMode( bool yesno_r ) { _upgradeMode = yesno_r; }
- void addIgnoreConflict (const PoolItem_Ref item,
- const Capability & capability);
- void addIgnoreRequires (const PoolItem_Ref item,
- const Capability & capability);
- void addIgnoreObsoletes (const PoolItem_Ref item,
- const Capability & capability);
- void addIgnoreInstalledItem (const PoolItem_Ref item);
- void addIgnoreArchitectureItem (const PoolItem_Ref item);
+ bool isUpdateMode() const { return _updateMode; } // Resolver has been called with doUpdate
- void setForceResolve (const bool force) { _forceResolve = force; }
- const bool forceResolve() { return _forceResolve; }
- void setPreferHighestVersion (const bool highestVersion) { _preferHighestVersion = highestVersion; }
- const bool preferHighestVersion() { return _preferHighestVersion; }
+ bool isVerifyingMode() const { return _verifying; } // The system will be checked
+ void setVerifyingMode( TriBool state_r ) { _verifying = indeterminate(state_r) ? false : bool(state_r); }
- void setTryAllPossibilities (const bool tryAllPossibilities) { _tryAllPossibilities = tryAllPossibilities; }
- const bool tryAllPossibilities () { return _tryAllPossibilities; };
-
- bool verifySystem (bool considerNewHardware = false);
- void establishState (ResolverContext_Ptr context = NULL);
- bool establishPool (void);
- void freshenState( ResolverContext_Ptr context = NULL, bool resetAfterSolve = true );
- bool freshenPool( bool resetAfterSolve = true );
- bool resolveDependencies (const ResolverContext_Ptr context = NULL);
- bool resolvePool( bool tryAllPossibilities = false );
+ bool allowVendorChange() const { return _allowVendorChange; }
+ void setAllowVendorChange( TriBool state_r );
- bool transactResObject( ResObject::constPtr robj,
- bool install = true,
- bool recursive = false);
- bool transactResKind( Resolvable::Kind kind );
- void transactReset( ResStatus::TransactByValue causer );
+ bool solveSrcPackages() const { return _solveSrcPackages; }
+ void setSolveSrcPackages( TriBool state_r ) { _solveSrcPackages = indeterminate(state_r) ? false : bool(state_r); }
- void doUpgrade( zypp::UpgradeStatistics & opt_stats_r );
- PoolItemList problematicUpdateItems( void ) const { return _update_items; }
+ bool cleandepsOnRemove() const { return _cleandepsOnRemove; }
+ void setCleandepsOnRemove( TriBool state_r );
+ //@}
+ ResolverProblemList problems() const;
+ void applySolutions( const ProblemSolutionList & solutions );
- ResolverProblemList problems (const bool ignoreValidSolution = false) const;
- void applySolutions (const ProblemSolutionList &solutions);
- // returns a string list of ResolverInfo of the LAST not valid solution
- std::list<std::string> problemDescription( void ) const;
+ // Return the Transaction computed by the last solver run.
+ sat::Transaction getTransaction();
// reset all SOLVER transaction in pool
- void undo(void);
+ void undo();
- // only for testsuite
- void reset (void);
+ void reset( bool keepExtras = false );
- Arch architecture() const { return _architecture; }
- void setArchitecture( const Arch & arch) { _architecture = arch; }
+ // Get more information about the solverrun
+ // Which item will be installed by another item or triggers an item for
+ // installation
+ ItemCapKindList isInstalledBy( const PoolItem & item );
+ ItemCapKindList installs( const PoolItem & item );
+ ItemCapKindList satifiedByInstalled (const PoolItem & item );
+ ItemCapKindList installedSatisfied( const PoolItem & item );
- bool testing(void) const { return _testing; }
- void setTesting( bool testing ) { _testing = testing; }
};
///////////////////////////////////////////////////////////////////