From: Klaus Kaempf Date: Wed, 8 Feb 2006 12:47:44 +0000 (+0000) Subject: extend commit() X-Git-Tag: 6.6.0~5143 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb14a3c95f2c324d74657c748fcb9132d9103111;p=platform%2Fupstream%2Flibzypp.git extend commit() --- diff --git a/zypp/target/TargetImpl.cc b/zypp/target/TargetImpl.cc index 58dc7ac6f..33143cbd6 100644 --- a/zypp/target/TargetImpl.cc +++ b/zypp/target/TargetImpl.cc @@ -11,8 +11,15 @@ */ #include #include +#include +#include + #include "zypp/base/Logger.h" #include "zypp/base/Exception.h" +#include "zypp/PoolItem.h" +#include "zypp/Resolvable.h" +#include "zypp/ResObject.h" +#include "zypp/Package.h" #include "zypp/target/TargetImpl.h" #include "zypp/target/TargetCallbackReceiver.h" @@ -80,6 +87,7 @@ namespace zypp // TODO objects from the XML store return _store; } + Pathname TargetImpl::getRpmFile(Package::constPtr package) { @@ -96,9 +104,10 @@ namespace zypp return file; } - void TargetImpl::commit(ResPool pool_r) + + void TargetImpl::commit(ResPool pool_r, int medianr, PoolItemList & errors_r, PoolItemList & remaining_r, PoolItemList & srcremaining_r) { - MIL << "TargetImpl::commit()" << endl; + MIL << "TargetImpl::commit(, " << medianr << ")" << endl; PoolItemList to_uninstall; PoolItemList to_install; @@ -145,6 +154,7 @@ namespace zypp commit(installorder); } + void TargetImpl::commit(const PoolItemList & items_r) { MIL << "TargetImpl::commit()" << endl; @@ -245,14 +255,290 @@ namespace zypp return NULL; } +//----------------------------------------------------------------------------- +/****************************************************************** +** +** +** FUNCTION NAME : strip_obsoleted_to_delete +** FUNCTION TYPE : void +** +** strip packages to_delete which get obsoleted by +** to_install (i.e. delay deletion in case the +** obsoleting package likes to save whatever... +*/ +static void +strip_obsoleted_to_delete( PoolItemList & deleteList_r, + const PoolItemList & instlist_r ) +{ + if ( deleteList_r.size() == 0 || instlist_r.size() == 0 ) + return; // ---> nothing to do + + // build obsoletes from instlist_r + CapSet obsoletes; + for ( PoolItemList::const_iterator it = instlist_r.begin(); + it != instlist_r.end(); ++it ) + { + PoolItem_Ref item( *it ); + obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() ); + } + if ( obsoletes.size() == 0 ) + return; // ---> nothing to do + + // match them... ;( + PoolItemList undelayed; + // forall applDelete Packages... + for ( PoolItemList::iterator it = deleteList_r.begin(); + it != deleteList_r.end(); ++it ) + { + PoolItem_Ref ipkg( *it ); + bool delayPkg = false; + // ...check whether an obsolets.... + for ( CapSet::iterator obs = obsoletes.begin(); + ! delayPkg && obs != obsoletes.end(); ++obs ) + { + // ...matches anything provided by the package? + for ( CapSet::const_iterator prov = ipkg->dep(Dep::PROVIDES).begin(); + prov != ipkg->dep(Dep::PROVIDES).end(); ++prov ) + { + if ( obs->matches( *prov ) == CapMatch::yes ) + { + // if so, delay package deletion + DBG << "Ignore appl_delete (should be obsoleted): " << ipkg << endl; + delayPkg = true; + break; + } + } + } + if ( ! delayPkg ) { +MIL << "undelayed " << ipkg << endl; + undelayed.push_back( ipkg ); + } + } + // Puhh... + deleteList_r.swap( undelayed ); +} + + void -TargetImpl::getResolvablesToInsDel ( ResPool pool_r, +TargetImpl::getResolvablesToInsDel ( const ResPool pool_r, PoolItemList & dellist_r, PoolItemList & instlist_r, PoolItemList & srclist_r ) { + dellist_r.clear(); + instlist_r.clear(); + srclist_r.clear(); + + for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it ) + { + if (it->status().isToBeInstalled()) + { + if (it->resolvable()->arch() == Arch_src) + srclist_r.push_back( *it ); + else + instlist_r.push_back( *it ); + } + else if (it->status().isToBeUninstalled()) + { + if ( it->status().isToBeUninstalledDueToObsolete() ) + { + DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl; + } else { + dellist_r.push_back( *it ); + } + } + } + + MIL << "PackagesToInsDel: delete " << dellist_r.size() + << ", install " << instlist_r.size() + << ", srcinstall " << srclist_r.size() << endl; + + /////////////////////////////////////////////////////////////////// + // + // strip packages to_delete which get obsoleted by + // to_install (i.e. delay deletion in case the + // obsoleting package likes to save whatever... + // + /////////////////////////////////////////////////////////////////// + strip_obsoleted_to_delete( dellist_r, instlist_r ); + + if ( dellist_r.size() ) { + /////////////////////////////////////////////////////////////////// + // + // sort delete list... + // + /////////////////////////////////////////////////////////////////// + PoolItemList dlist; // for delete order + PoolItemList dummy; // dummy, empty, should contain already installed + for ( PoolItemList::iterator pkgIt = dellist_r.begin(); + pkgIt != dellist_r.end(); ++pkgIt ) + { + dlist.push_back( *pkgIt ); + } + + InstallOrder order( pool_r, dlist, dummy ); // sort according top prereq + order.init(); + const PoolItemList dsorted( order.getTopSorted() ); + + dellist_r.clear(); + for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin(); + cit != dsorted.rend(); ++cit ) + { + dellist_r.push_back( *cit ); + } + } + + /////////////////////////////////////////////////////////////////// + // + // sort installed list... + // + /////////////////////////////////////////////////////////////////// + if ( instlist_r.empty() ) { + return; + } +#warning Source Rank Priority ? +#if 0 + /////////////////////////////////////////////////////////////////// + // Get desired order of InstSrc'es to install from. + /////////////////////////////////////////////////////////////////// + typedef map RankPriority; + + RankPriority rankPriority; + { + InstSrcManager::ISrcIdList sourcerank( Y2PM::instSrcManager().instOrderSources() ); + // map InstSrc rank to install priority + unsigned prio = 0; + for ( InstSrcManager::ISrcIdList::const_iterator it = sourcerank.begin(); + it != sourcerank.end(); ++it, ++prio ) { + rankPriority[(*it)->descr()->default_rank()] = prio; + } + } +#endif + + /////////////////////////////////////////////////////////////////// + // Compute install order according to packages prereq. + // Try to group packages with respect to the desired install order + /////////////////////////////////////////////////////////////////// + // backup list for debug purpose. + // You can as well build the set, clear the list and rebuild it in install order. + PoolItemList instbackup_r; + instbackup_r.swap( instlist_r ); + + PoolItemList ilist; // for install order + PoolItemList installed; // dummy, empty, should contain already installed + for ( PoolItemList::iterator pkgIt = instbackup_r.begin(); pkgIt != instbackup_r.end(); ++pkgIt ) { + ilist.push_back( *pkgIt ); + } + InstallOrder order( pool_r, ilist, installed ); + // start recursive depth-first-search + order.startrdfs(); + + /////////////////////////////////////////////////////////////////// + // build install list in install order + /////////////////////////////////////////////////////////////////// + PoolItemList best_list; +// unsigned best_prio = 0; + unsigned best_medianum = 0; + + PoolItemList last_list; +// unsigned last_prio = 0; + unsigned last_medianum = 0; + + for ( PoolItemList pkgs = order.computeNextSet(); ! pkgs.empty(); pkgs = order.computeNextSet() ) + { +MIL << "order.computeNextSet: " << pkgs.size() << " packages" << endl; + /////////////////////////////////////////////////////////////////// + // pkgs contains all packages we could install now. Pick all packages + // from current media, or best media if none for current. + /////////////////////////////////////////////////////////////////// + + best_list.clear(); + last_list.clear(); + + for ( PoolItemList::iterator cit = pkgs.begin(); cit != pkgs.end(); ++cit ) + { + Resolvable::constPtr res( cit->resolvable() ); + Package::constPtr cpkg( asKind(res) ); + +MIL << "Packge " << cpkg << ", media " << cpkg->mediaId() << endl; + if ( // rankPriority[cpkg->instSrcRank()] == last_prio && + cpkg->mediaId() == last_medianum ) { + // prefer packages on current media. + last_list.push_back( *cit ); + continue; + } + + if ( last_list.empty() ) { + // check for best media as long as there are no packages for current media. + + if ( ! best_list.empty() ) { + +#if 0 + if ( rankPriority[cpkg->instSrcRank()] < best_prio ) { + best_list.clear(); // new best + } else if ( rankPriority[cpkg->instSrcRank()] == best_prio ) { +#endif + + if ( cpkg->mediaId() < best_medianum ) { + best_list.clear(); // new best + } else if ( cpkg->mediaId() == best_medianum ) { + best_list.push_back( *cit ); // same as best -> add + continue; + } else { + continue; // worse + } +#if 0 + } else { + continue; // worse + } +#endif + } + + if ( best_list.empty() ) + { + // first package or new best + best_list.push_back( *cit ); +// best_prio = rankPriority[cpkg->instSrcRank()]; + best_medianum = cpkg->mediaId(); + continue; + } + } + + } // for all packages in current set + + /////////////////////////////////////////////////////////////////// + // remove packages picked from install order and append them to + // install list. + /////////////////////////////////////////////////////////////////// + PoolItemList & take_list( last_list.empty() ? best_list : last_list ); + if ( last_list.empty() ) + { + MIL << "SET NEW media " << best_medianum << endl; +// last_prio = best_prio; + last_medianum = best_medianum; + } + else + { + MIL << "SET CONTINUE" << endl; + } + + for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it ) + { + order.setInstalled( *it ); + MIL << "SET isrc " << (*it) << endl; + } + instlist_r.splice( instlist_r.end(), take_list ); + + } // for all sets computed + + + if ( instbackup_r.size() != instlist_r.size() ) + { + INT << "Lost packages in InstallOrder sort." << endl; + } + } diff --git a/zypp/target/TargetImpl.h b/zypp/target/TargetImpl.h index f9e620cfd..d5d5fe626 100644 --- a/zypp/target/TargetImpl.h +++ b/zypp/target/TargetImpl.h @@ -47,6 +47,14 @@ namespace zypp { friend std::ostream & operator<<( std::ostream & str, const TargetImpl & obj ); + private: + /** Sort according to prereqs and media numbers */ + void getResolvablesToInsDel ( const ResPool pool_r, + PoolItemList & dellist_r, + PoolItemList & instlist_r, + PoolItemList & srclist_r ); + + public: /** Ctor. */ TargetImpl(const Pathname & root_r = "/"); @@ -61,18 +69,13 @@ namespace zypp /** All resolvables in the target. */ const ResStore & resolvables(); - /** Sort according to prereqs and media numbers */ - void getResolvablesToInsDel ( ResPool pool_r, - PoolItemList & dellist_r, - PoolItemList & instlist_r, - PoolItemList & srclist_r ); - - /** Commit changes in the pool */ -#warning Add support for multiple medias - eg. limit only to CD1 - void commit(ResPool pool_r); + /** Commit changes in the pool + media = 0 means any/all medias + media > 0 means limit commits to this media */ + void commit( ResPool pool_r, int medianr, PoolItemList & errors_r, PoolItemList & remaining_r, PoolItemList & srcremaining_r ); /** Commit ordered changes */ - void commit(const PoolItemList & items_r); + void commit( const PoolItemList & items_r ); /** Overload to realize stream output. */ virtual std::ostream & dumpOn( std::ostream & str ) const