From: Stefan Schubert Date: Fri, 16 May 2008 14:45:32 +0000 (+0000) Subject: - Added new calls : isInstalledBy (const PoolItem item); X-Git-Tag: BASE-SuSE-Linux-11_0-Branch~67 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=25805a0913daeabdc350ba9095b767811fe6eb73;p=platform%2Fupstream%2Flibzypp.git - Added new calls : isInstalledBy (const PoolItem item); installs (const PoolItem item); --- diff --git a/VERSION.cmake b/VERSION.cmake index 3588388..80ea36e 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -45,6 +45,6 @@ # SET(LIBZYPP_MAJOR "4") -SET(LIBZYPP_MINOR "22") +SET(LIBZYPP_MINOR "23") SET(LIBZYPP_COMPATMINOR "21") SET(LIBZYPP_PATCH "0") diff --git a/zypp/Resolver.cc b/zypp/Resolver.cc index 5140453..4f893fa 100644 --- a/zypp/Resolver.cc +++ b/zypp/Resolver.cc @@ -109,6 +109,10 @@ namespace zypp bool Resolver::createSolverTestcase (const std::string & dumpPath) { solver::detail::Testcase testcase (dumpPath); return testcase.createTestcase(*_pimpl);} + const solver::detail::ItemCapKindList Resolver::isInstalledBy (const PoolItem item) + { return _pimpl->isInstalledBy (item); } + const solver::detail::ItemCapKindList Resolver::installs (const PoolItem item) + { return _pimpl->installs (item); } ///////////////////////////////////////////////////////////////// diff --git a/zypp/Resolver.h b/zypp/Resolver.h index 3421af1..1f7eca9 100644 --- a/zypp/Resolver.h +++ b/zypp/Resolver.h @@ -216,8 +216,33 @@ namespace zypp */ bool createSolverTestcase (const std::string & dumpPath = "/var/log/YaST2/solverTestcase"); + /** + * Gives information about WHO has pused an installation of an given item. + * + * \param item Evaluate additional information for this resolvable. + * \return A list of structures which contains: + * item Item which has triggered the installation of the given param item. + * cap Capability which has triggerd this installation + * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) + * + * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. + * + */ + const solver::detail::ItemCapKindList isInstalledBy (const PoolItem item); - protected: + /** + * Gives information about WHICH additional items will be installed due the installation of an item. + * + * \param item Evaluate additional information for this resolvable. + * \return A list of structures which contains: + * item Item which will be installed due to the installation of the given param item too. + * cap Capability which causes the installation + * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... ) + * + * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid. + * + */ + const solver::detail::ItemCapKindList installs (const PoolItem item); private: solver::detail::Resolver_Ptr _pimpl; diff --git a/zypp/solver/detail/Resolver.cc b/zypp/solver/detail/Resolver.cc index cc59968..a3e9fab 100644 --- a/zypp/solver/detail/Resolver.cc +++ b/zypp/solver/detail/Resolver.cc @@ -102,6 +102,9 @@ Resolver::reset (bool keepExtras ) _extra_requires.clear(); _extra_conflicts.clear(); } + + _isInstalledBy.clear(); + _installs.clear(); } void @@ -288,6 +291,11 @@ Resolver::solverInit() if (_verifying) _satResolver->setFixsystem(true); + + // Resetting additional solver information + _isInstalledBy.clear(); + _installs.clear(); + } bool @@ -420,6 +428,165 @@ bool Resolver::checkUnmaintainedItems () { } +//---------------------------------------------------------------------------- +// Getting more information about the solve results + + +void +Resolver::collectResolverInfo(void) +{ + if ( _satResolver + && _isInstalledBy.empty() + && _installs.empty()) { + + // generating new + PoolItemList itemsToInstall = _satResolver->resultItemsToInstall(); + + for (PoolItemList::const_iterator instIter = itemsToInstall.begin(); + instIter != itemsToInstall.end(); instIter++) { + + // Requires + for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::REQUIRES).begin(); capIt != (*instIter)->dep (Dep::REQUIRES).end(); ++capIt) + { + sat::WhatProvides possibleProviders(*capIt); + for_( iter, possibleProviders.begin(), possibleProviders.end() ) { + PoolItem provider = ResPool::instance().find( *iter ); + + // searching if this provider will already be installed + bool found = false; + bool alreadySetForInstallation = false; + ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider); + while (pos != _isInstalledBy.end() + && pos->first == provider + && !found) { + alreadySetForInstallation = true; + ItemCapKind capKind = pos->second; + if (capKind.item == *instIter) found = true; + pos++; + } + + if (!found + && provider.status().isToBeInstalled()) { + if (provider.status().isBySolver()) { + ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, !alreadySetForInstallation ); + _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy)); + } else { + // no initial installation cause it has been set be e.g. user + ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, false ); + _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy)); + } + ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, !alreadySetForInstallation ); + _installs.insert (make_pair( *instIter, capKindisInstalledBy)); + } + } + } + + //Recommends + for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt) + { + sat::WhatProvides possibleProviders(*capIt); + for_( iter, possibleProviders.begin(), possibleProviders.end() ) { + PoolItem provider = ResPool::instance().find( *iter ); + + // searching if this provider will already be installed + bool found = false; + bool alreadySetForInstallation = false; + ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider); + while (pos != _isInstalledBy.end() + && pos->first == provider + && !found) { + alreadySetForInstallation = true; + ItemCapKind capKind = pos->second; + if (capKind.item == *instIter) found = true; + pos++; + } + + if (!found + && provider.status().isToBeInstalled()) { + if (provider.status().isBySolver()) { + ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation ); + _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy)); + } else { + // no initial installation cause it has been set be e.g. user + ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, false ); + _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy)); + } + ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation ); + _installs.insert (make_pair( *instIter, capKindisInstalledBy)); + } + } + } + + //Suggests + for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUGGESTS).begin(); capIt != (*instIter)->dep (Dep::SUGGESTS).end(); ++capIt) + { + sat::WhatProvides possibleProviders(*capIt); + for_( iter, possibleProviders.begin(), possibleProviders.end() ) { + PoolItem provider = ResPool::instance().find( *iter ); + + // searching if this provider will already be installed + bool found = false; + bool alreadySetForInstallation = false; + ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider); + while (pos != _isInstalledBy.end() + && pos->first == provider + && !found) { + alreadySetForInstallation = true; + ItemCapKind capKind = pos->second; + if (capKind.item == *instIter) found = true; + pos++; + } + + if (!found) { + ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUGGESTS, !alreadySetForInstallation ); + _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy)); + } + } + } + } + } +} + + +const ItemCapKindList Resolver::isInstalledBy (const PoolItem item) { + ItemCapKindList ret; + collectResolverInfo(); + + for (ItemCapKindMap::const_iterator iter = _isInstalledBy.find(item); iter != _isInstalledBy.end();) { + ItemCapKind info = iter->second; + PoolItem iterItem = iter->first; + if (iterItem == item) { + ret.push_back(info); + iter++; + } else { + // exit + iter = _isInstalledBy.end(); + } + } + return ret; +} + +const ItemCapKindList Resolver::installs (const PoolItem item) { + ItemCapKindList ret; + collectResolverInfo(); + + for (ItemCapKindMap::const_iterator iter = _installs.find(item); iter != _installs.end();) { + ItemCapKind info = iter->second; + PoolItem iterItem = iter->first; + if (iterItem == item) { + ret.push_back(info); + iter++; + } else { + // exit + iter = _installs.end(); + } + } + return ret; +} + + + + /////////////////////////////////////////////////////////////////// };// namespace detail ///////////////////////////////////////////////////////////////////// diff --git a/zypp/solver/detail/Resolver.h b/zypp/solver/detail/Resolver.h index a965b82..ab27c8f 100644 --- a/zypp/solver/detail/Resolver.h +++ b/zypp/solver/detail/Resolver.h @@ -58,6 +58,32 @@ namespace zypp 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("FRESHENS") {} + ItemCapKind( PoolItem i, Capability c, Dep k, bool initial) + : cap( c ) + , capKind( k ) + , item( i ) + , initialInstallation( initial ) + { } + }; + typedef std::multimap ItemCapKindMap; + typedef std::list ItemCapKindList; + + /////////////////////////////////////////////////////////////////// // // CLASS NAME : Resolver @@ -94,11 +120,16 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable { // 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; + solver::detail::SolverQueueItemList _added_queue_items; + + // Additional information about the solverrun + ItemCapKindMap _isInstalledBy; + ItemCapKindMap _installs; // helpers bool doesObsoleteCapability (PoolItem candidate, const Capability & cap); bool doesObsoleteItem (PoolItem candidate, PoolItem installed); + void collectResolverInfo (void); // Unmaintained packages which does not fit to the updated system // (broken dependencies) will be deleted. @@ -160,7 +191,14 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable { void reset (bool keepExtras = false ); bool testing(void) const { return _testing; } - void setTesting( bool testing ) { _testing = testing; } + void setTesting( bool testing ) { _testing = testing; } + + // Get more information about the solverrun + // Which item will be installed by another item or triggers an item for + // installation + const ItemCapKindList isInstalledBy (const PoolItem item); + const ItemCapKindList installs (const PoolItem item); + }; diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index cddfbe2..1c0870b 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -444,12 +444,8 @@ SATResolver::solving() // copying solution back to zypp pool //----------------------------------------- - - if (_solv->problems.count > 0 ) - { - ERR << "Solverrun finished with an ERROR" << endl; - return false; - } + _result_items_to_install.clear(); + _result_items_to_remove.clear(); /* solvables to be installed */ for (int i = 0; i < _solv->decisionq.count; i++) @@ -464,6 +460,7 @@ SATResolver::solving() PoolItem poolItem = _pool.find (sat::Solvable(p)); if (poolItem) { SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER); + _result_items_to_install.push_back (poolItem); } else { ERR << "id " << p << " not found in ZYPP pool." << endl; } @@ -489,6 +486,7 @@ SATResolver::solving() } else { SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER); } + _result_items_to_remove.push_back (poolItem); } else { ERR << "id " << i << " not found in ZYPP pool." << endl; } @@ -557,6 +555,13 @@ SATResolver::solving() _XDEBUG("SATSolutionToPool(" << item << " ) broken !"); } } + + if (_solv->problems.count > 0 ) + { + ERR << "Solverrun finished with an ERROR" << endl; + return false; + } + map_free(&installedmap); queue_free(&(solvableQueue)); queue_free(&flags); diff --git a/zypp/solver/detail/SATResolver.h b/zypp/solver/detail/SATResolver.h index 36a4319..7386347 100644 --- a/zypp/solver/detail/SATResolver.h +++ b/zypp/solver/detail/SATResolver.h @@ -69,7 +69,11 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable { PoolItemList _items_to_install; PoolItemList _items_to_remove; PoolItemList _items_to_lock; - PoolItemList _items_to_keep; + PoolItemList _items_to_keep; + + // solve results + PoolItemList _result_items_to_install; + PoolItemList _result_items_to_remove; bool _fixsystem; // repair errors in rpm dependency graph bool _allowdowngrade; // allow to downgrade installed solvable @@ -160,6 +164,10 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable { void setOnlyRequires ( const bool onlyRequires) { _onlyRequires = onlyRequires;} bool doesObsoleteItem (PoolItem candidate, PoolItem installed); + + PoolItemList resultItemsToInstall () { return _result_items_to_install; } + PoolItemList resultItemsToRemove () { return _result_items_to_remove; } + }; ///////////////////////////////////////////////////////////////////