#include <solv/queue.h>
}
-#include "zypp/solver/detail/Helper.h"
+#define ZYPP_USE_RESOLVER_INTERNALS
+
#include "zypp/base/String.h"
#include "zypp/Product.h"
#include "zypp/Capability.h"
#include "zypp/sat/Pool.h"
#include "zypp/sat/WhatProvides.h"
#include "zypp/sat/WhatObsoletes.h"
+#include "zypp/solver/detail/Resolver.h"
#include "zypp/solver/detail/SATResolver.h"
#include "zypp/solver/detail/ProblemSolutionCombi.h"
#include "zypp/solver/detail/ProblemSolutionIgnore.h"
#include "zypp/solver/detail/SolverQueueItemInstall.h"
#include "zypp/solver/detail/SolverQueueItemDelete.h"
#include "zypp/solver/detail/SystemCheck.h"
+#include "zypp/solver/detail/SolutionAction.h"
+#include "zypp/solver/detail/SolverQueueItem.h"
#include "zypp/sat/Transaction.h"
#include "zypp/sat/Queue.h"
+#include "zypp/sat/detail/PoolImpl.h"
+
+#define XDEBUG(x) do { if (base::logger::isExcessive()) XXX << x << std::endl;} while (0)
+
/////////////////////////////////////////////////////////////////////////
namespace zypp
{ ///////////////////////////////////////////////////////////////////////
, _allowarchchange(false)
, _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
, _allowuninstall(false)
- , _dup_allowdowngrade( true )
- , _dup_allownamechange( true )
- , _dup_allowarchchange( true )
- , _dup_allowvendorchange( true )
, _updatesystem(false)
, _noupdateprovide(false)
, _dosplitprovides(true)
, _ignorealreadyrecommended(true)
, _distupgrade(false)
, _distupgrade_removeunsupported(false)
+ , _dup_allowdowngrade ( ZConfig::instance().solver_dupAllowDowngrade() )
+ , _dup_allownamechange ( ZConfig::instance().solver_dupAllowNameChange() )
+ , _dup_allowarchchange ( ZConfig::instance().solver_dupAllowArchChange() )
+ , _dup_allowvendorchange ( ZConfig::instance().solver_dupAllowVendorChange() )
, _solveSrcPackages(false)
, _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
{
return _pool;
}
-void
-SATResolver::resetItemTransaction (PoolItem item)
-{
- bool found = false;
- for (PoolItemList::const_iterator iter = _items_to_remove.begin();
- iter != _items_to_remove.end(); ++iter) {
- if (*iter == item) {
- _items_to_remove.remove(*iter);
- found = true;
- break;
- }
- }
- if (!found) {
- for (PoolItemList::const_iterator iter = _items_to_install.begin();
- iter != _items_to_install.end(); ++iter) {
- if (*iter == item) {
- _items_to_install.remove(*iter);
- found = true;
- break;
- }
- }
- }
- if (!found) {
- for (PoolItemList::const_iterator iter = _items_to_keep.begin();
- iter != _items_to_keep.end(); ++iter) {
- if (*iter == item) {
- _items_to_keep.remove(*iter);
- found = true;
- break;
- }
- }
- }
- if (!found) {
- for (PoolItemList::const_iterator iter = _items_to_lock.begin();
- iter != _items_to_lock.end(); ++iter) {
- if (*iter == item) {
- _items_to_lock.remove(*iter);
- found = true;
- break;
- }
- }
- }
-}
-
-
-void
-SATResolver::addPoolItemToInstall (PoolItem item)
-{
- resetItemTransaction (item);
- _items_to_install.push_back (item);
- _items_to_install.unique ();
-}
-
-
-void
-SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
-{
- for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- addPoolItemToInstall (*iter);
- }
-}
-
-
-void
-SATResolver::addPoolItemToRemove (PoolItem item)
-{
- resetItemTransaction (item);
- _items_to_remove.push_back (item);
- _items_to_remove.unique ();
-}
-
-
-void
-SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
-{
- for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- addPoolItemToRemove (*iter);
- }
-}
-
-void
-SATResolver::addPoolItemToLock (PoolItem item)
-{
- resetItemTransaction (item);
- _items_to_lock.push_back (item);
- _items_to_lock.unique ();
-}
-
-void
-SATResolver::addPoolItemToKeep (PoolItem item)
-{
- resetItemTransaction (item);
- _items_to_keep.push_back (item);
- _items_to_keep.unique ();
-}
-
//---------------------------------------------------------------------------
// copy marked item from solution back to pool
// installation/deletion
if (status.isToBeInstalled()) {
r = item.status().setToBeInstalled (causer);
- _XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
+ XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
}
else if (status.isToBeUninstalledDueToUpgrade()) {
r = item.status().setToBeUninstalledDueToUpgrade (causer);
- _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
+ XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
}
else if (status.isToBeUninstalled()) {
r = item.status().setToBeUninstalled (causer);
- _XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
+ XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
}
return;
// resolvePool
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-// Helper functions for the ZYPP-Pool
-//----------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------------------------------------
-// This function loops over the pool and grabs all items
-// It clears all previous bySolver() states also
-//
-// Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
-// Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
-//
-// Solver results must be written back to the pool.
-//------------------------------------------------------------------------------------------------------------
-
-
+/////////////////////////////////////////////////////////////////////////
+/// \class SATCollectTransact
+/// \brief Commit helper functor distributing PoolItem by status into lists
+///
+/// On the fly it clears all PoolItem bySolver/ByApplLow status.
+/// The lists are cleared in the Ctor, populated by \ref operator().
+/////////////////////////////////////////////////////////////////////////
struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
{
- SATResolver & resolver;
+ SATCollectTransact( PoolItemList & items_to_install_r,
+ PoolItemList & items_to_remove_r,
+ PoolItemList & items_to_lock_r,
+ PoolItemList & items_to_keep_r,
+ bool solveSrcPackages_r )
+ : _items_to_install( items_to_install_r )
+ , _items_to_remove( items_to_remove_r )
+ , _items_to_lock( items_to_lock_r )
+ , _items_to_keep( items_to_keep_r )
+ , _solveSrcPackages( solveSrcPackages_r )
+ {
+ _items_to_install.clear();
+ _items_to_remove.clear();
+ _items_to_lock.clear();
+ _items_to_keep.clear();
+ }
- SATCollectTransact (SATResolver & r)
- : resolver (r)
- { }
+ bool operator()( const PoolItem & item_r )
+ {
+
+ ResStatus & itemStatus( item_r.status() );
+ bool by_solver = ( itemStatus.isBySolver() || itemStatus.isByApplLow() );
- bool operator()( PoolItem item ) // only transacts() items go here
+ if ( by_solver )
{
- ResStatus status = item.status();
- bool by_solver = (status.isBySolver() || status.isByApplLow());
+ // Clear former solver/establish resultd
+ itemStatus.resetTransact( ResStatus::APPL_LOW );
+ return true; // -> back out here, don't re-queue former results
+ }
- if (by_solver) {
- item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
- return true; // back out here, dont re-queue former solver result
- }
+ if ( !_solveSrcPackages && item_r.isKind<SrcPackage>() )
+ {
+ // Later we may continue on a per source package base.
+ return true; // dont process this source package.
+ }
- if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() )
- {
- // Later we may continue on a per source package base.
- return true; // dont process this source package.
- }
+ switch ( itemStatus.getTransactValue() )
+ {
+ case ResStatus::TRANSACT:
+ itemStatus.isUninstalled() ? _items_to_install.push_back( item_r )
+ : _items_to_remove.push_back( item_r ); break;
+ case ResStatus::LOCKED: _items_to_lock.push_back( item_r ); break;
+ case ResStatus::KEEP_STATE: _items_to_keep.push_back( item_r ); break;
+ }
+ return true;
+ }
- if (status.isToBeInstalled()) {
- resolver.addPoolItemToInstall(item); // -> install!
- }
- else if (status.isToBeUninstalled()) {
- resolver.addPoolItemToRemove(item); // -> remove !
- }
- else if (status.isLocked()
- && !by_solver) {
- resolver.addPoolItemToLock (item);
- }
- else if (status.isKept()
- && !by_solver) {
- resolver.addPoolItemToKeep (item);
- }
+private:
+ PoolItemList & _items_to_install;
+ PoolItemList & _items_to_remove;
+ PoolItemList & _items_to_lock;
+ PoolItemList & _items_to_keep;
+ bool _solveSrcPackages;
- return true;
- }
};
+/////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
{
public:
bool is_updated;
- bool multiversion;
sat::Solvable _installed;
- CheckIfUpdate( sat::Solvable installed_r )
- : is_updated( false )
- , multiversion( installed_r.multiversionInstall() )
- , _installed( installed_r )
+ CheckIfUpdate( const sat::Solvable & installed_r )
+ : is_updated( false )
+ , _installed( installed_r )
{}
// check this item will be updated
- bool operator()( PoolItem item )
+ bool operator()( const PoolItem & item )
{
if ( item.status().isToBeInstalled() )
{
- if ( ! multiversion || sameNVRA( _installed, item ) )
+ if ( ! item.multiversionInstall() || sameNVRA( _installed, item ) )
{
is_updated = true;
return false;
HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,_dup_allowvendorchange );
#undef HACKENV
#endif
- sat::Pool::instance().prepareForSolving();
+ sat::Pool::instance().prepare();
// Solve !
MIL << "Starting solving...." << endl;
PoolItem poolItem( slv );
SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
- _result_items_to_install.push_back (poolItem);
+ _result_items_to_install.push_back( poolItem );
}
queue_free(&decisionq);
if (flags.elements[i] == -1) {
item.status().setNonRelevant();
- _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
+ XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
} else if (flags.elements[i] == 1) {
item.status().setSatisfied();
- _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
+ XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
} else if (flags.elements[i] == 0) {
item.status().setBroken();
- _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
+ XDEBUG("SATSolutionToPool(" << item << " ) broken !");
}
}
queue_free(&(solvableQueue));
void
SATResolver::solverInit(const PoolItemList & weakItems)
{
- SATCollectTransact info (*this);
MIL << "SATResolver::solverInit()" << endl;
// remove old stuff
solverEnd();
-
queue_init( &_jobQueue );
- _items_to_install.clear();
- _items_to_remove.clear();
- _items_to_lock.clear();
- _items_to_keep.clear();
- invokeOnEach ( _pool.begin(), _pool.end(),
- functor::functorRef<bool,PoolItem>(info) );
+ // clear and rebuild: _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep
+ {
+ SATCollectTransact collector( _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep, solveSrcPackages() );
+ invokeOnEach ( _pool.begin(), _pool.end(), functor::functorRef<bool,PoolItem>( collector ) );
+ }
for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
Id id = (*iter)->satSolvable().id();
queue_push( &(_jobQueue), id );
}
+ // Ad rules for changed requestedLocales
+ const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
+ for ( const auto & locale : trackedLocaleIds.added() )
+ {
+ queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
+ queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
+ }
+
+ for ( const auto & locale : trackedLocaleIds.removed() )
+ {
+ queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | SOLVER_CLEANDEPS ); // needs uncond. SOLVER_CLEANDEPS!
+ queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
+ }
+
// Add rules for parallel installable resolvables with different versions
- for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
+ for ( const sat::Solvable & solv : myPool().multiversionList() )
{
- queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
- queue_push( &(_jobQueue), it->id() );
+ queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
+ queue_push( &(_jobQueue), solv.id() );
}
::pool_add_userinstalled_jobs(_satPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
- sat::Pool::instance().prepareForSolving();
+ sat::Pool::instance().prepare();
// Solve !
MIL << "Starting solving for update...." << endl;
bool found = false;
for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
PoolItem provider2 = ResPool::instance().find( *iter2 );
- if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
+ if (compareByNVR (provider1,provider2) == 0
&& ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
|| (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
found = true;
}
if (providerlistUninstalled.size() > 0) {
if (detail.size() > 0)
+ // translators: 'uninstallable' == 'not installable'
detail += _("\nuninstallable providers: ");
else
+ // translators: 'uninstallable' == 'not installable'
detail = _("uninstallable providers: ");
for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
if (iter == providerlistUninstalled.begin())
solution = 0;
while ((solution = solver_next_solution(_satSolver, problem, solution)) != 0) {
element = 0;
- ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
+ ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi;
while ((element = solver_next_solutionelement(_satSolver, problem, solution, element, &p, &rp)) != 0) {
if (p == SOLVER_SOLUTION_JOB) {
/* job, rp is index into job queue */
if (ignoreId > 0) {
// There is a possibility to ignore this error by setting weak dependencies
PoolItem item = _pool.find (sat::Solvable(ignoreId));
- ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
+ ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(item);
resolverProblem->addSolution (problemSolution,
false); // Solutions will be shown at the end
MIL << "ignore some dependencies of " << item << endl;
return resolverProblems;
}
-void
-SATResolver::applySolutions (const ProblemSolutionList & solutions)
-{
- for (ProblemSolutionList::const_iterator iter = solutions.begin();
- iter != solutions.end(); ++iter) {
- ProblemSolution_Ptr solution = *iter;
- Resolver dummyResolver(_pool);
- if (!solution->apply (dummyResolver))
- break;
- }
-}
+void SATResolver::applySolutions( const ProblemSolutionList & solutions )
+{ Resolver( _pool ).applySolutions( solutions ); }
void SATResolver::setLocks()
{