GetResolvablesToInsDel.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <set>
00014 
00015 #include "zypp/base/Logger.h"
00016 
00017 #include "zypp/pool/GetResolvablesToInsDel.h"
00018 #include "zypp/pool/PoolStats.h"
00019 
00020 #include "zypp/solver/detail/InstallOrder.h"
00021 
00022 using std::endl;
00023 using zypp::solver::detail::InstallOrder;
00024 
00025 #undef  ZYPP_BASE_LOGGER_LOGGROUP
00026 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::GetResolvablesToInsDel"
00027 
00028 
00030 namespace zypp
00031 { 
00032 
00033   namespace pool
00034   { 
00035 
00036     /******************************************************************
00037      **
00038      ** FUNCTION NAME : strip_obsoleted_to_delete
00039      ** FUNCTION TYPE : void
00040      **
00041      ** strip packages to_delete which get obsoleted by
00042      ** to_install (i.e. delay deletion in case the
00043      ** obsoleting package likes to save whatever...
00044     */
00045 
00046     static void
00047     strip_obsoleted_to_delete( GetResolvablesToInsDel::PoolItemList & deleteList_r,
00048                                const GetResolvablesToInsDel::PoolItemList & instlist_r )
00049     {
00050       if ( deleteList_r.size() == 0 || instlist_r.size() == 0 )
00051         return; // ---> nothing to do
00052 
00053       // build obsoletes from instlist_r
00054       CapSet obsoletes;
00055       for ( GetResolvablesToInsDel::PoolItemList::const_iterator it = instlist_r.begin();
00056             it != instlist_r.end(); ++it )
00057         {
00058           PoolItem_Ref item( *it );
00059           obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
00060         }
00061       if ( obsoletes.size() == 0 )
00062         return; // ---> nothing to do
00063 
00064       // match them... ;(
00065       GetResolvablesToInsDel::PoolItemList undelayed;
00066       // forall applDelete Packages...
00067       for ( GetResolvablesToInsDel::PoolItemList::iterator it = deleteList_r.begin();
00068             it != deleteList_r.end(); ++it )
00069         {
00070           PoolItem_Ref ipkg( *it );
00071           bool delayPkg = false;
00072           // ...check whether an obsoletes....
00073           for ( CapSet::iterator obs = obsoletes.begin();
00074                 ! delayPkg && obs != obsoletes.end(); ++obs )
00075             {
00076               // ...matches anything provided by the package?
00077               for ( CapSet::const_iterator prov = ipkg->dep(Dep::PROVIDES).begin();
00078                     prov != ipkg->dep(Dep::PROVIDES).end(); ++prov )
00079                 {
00080                   if ( obs->matches( *prov ) == CapMatch::yes )
00081                     {
00082                       // if so, delay package deletion
00083                       DBG << "Ignore appl_delete (should be obsoleted): " << ipkg << endl;
00084                       delayPkg = true;
00085                       ipkg.status().resetTransact( ResStatus::USER );
00086                       break;
00087                     }
00088                 }
00089             }
00090           if ( ! delayPkg ) {
00091             DBG << "undelayed " << ipkg << endl;
00092             undelayed.push_back( ipkg );
00093           }
00094         }
00095       // Puhh...
00096       deleteList_r.swap( undelayed );
00097     }
00098 
00100     //
00101     //  METHOD NAME : GetResolvablesToInsDel::GetResolvablesToInsDel
00102     //  METHOD TYPE : Ctor
00103     //
00104     GetResolvablesToInsDel::GetResolvablesToInsDel( ResPool pool_r )
00105     {
00106       typedef std::set<PoolItem_Ref> PoolItemSet;
00107 
00108       PoolItemList & dellist_r( _toDelete );
00109       PoolItemList & instlist_r( _toInstall );
00110       PoolItemList & srclist_r( _toSrcinstall );
00111 
00112       for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
00113         {
00114           if (it->status().isToBeInstalled())
00115             {
00116               if ((*it)->kind() == ResTraits<SrcPackage>::kind) {
00117                 srclist_r.push_back( *it );
00118               }
00119               else
00120                 instlist_r.push_back( *it );
00121             }
00122           else if (it->status().isToBeUninstalled())
00123             {
00124               if ( it->status().isToBeUninstalledDueToObsolete() )
00125                 {
00126                   DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl;
00127                 }
00128               else if ( it->status().isToBeUninstalledDueToUpgrade() )
00129                 {
00130                   DBG << "Ignore auto_delete (should be upgraded): " << *it << endl;
00131                 }
00132               else {
00133                 dellist_r.push_back( *it );
00134               }
00135             }
00136         }
00137 
00138       MIL << "ResolvablesToInsDel: delete " << dellist_r.size()
00139       << ", install " << instlist_r.size()
00140       << ", srcinstall " << srclist_r.size() << endl;
00141 
00143       //
00144       // strip packages to_delete which get obsoleted by
00145       // to_install (i.e. delay deletion in case the
00146       // obsoleting package likes to save whatever...
00147       //
00149       strip_obsoleted_to_delete( dellist_r, instlist_r );
00150 
00151       if ( dellist_r.size() ) {
00153         //
00154         // sort delete list...
00155         //
00157         PoolItemSet delset( dellist_r.begin(), dellist_r.end() );  // for delete order
00158         PoolItemSet dummy; // dummy, empty, should contain already installed
00159 
00160         InstallOrder order( pool_r, delset, dummy ); // sort according top prereq
00161         order.init();
00162         const PoolItemList dsorted( order.getTopSorted() );
00163 
00164         dellist_r.clear();
00165         for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
00166               cit != dsorted.rend(); ++cit )
00167           {
00168             dellist_r.push_back( *cit );
00169           }
00170       }
00171 
00173       //
00174       // sort installed list...
00175       //
00177       if ( instlist_r.empty() )
00178         return;
00179 
00180 #warning Source Rank Priority ?
00181 #if 0
00182 
00183       // Get desired order of InstSrc'es to install from.
00185       typedef map<unsigned,unsigned> RankPriority;
00186 
00187       RankPriority rankPriority;
00188       {
00189         InstSrcManager::ISrcIdList sourcerank( Y2PM::instSrcManager().instOrderSources() );
00190         // map InstSrc rank to install priority
00191         unsigned prio = 0;
00192         for ( InstSrcManager::ISrcIdList::const_iterator it = sourcerank.begin();
00193               it != sourcerank.end(); ++it, ++prio ) {
00194           rankPriority[(*it)->descr()->default_rank()] = prio;
00195         }
00196       }
00197 #endif
00198 
00200       // Compute install order according to packages prereq.
00201       // Try to group packages with respect to the desired install order
00203       // backup list for debug purpose.
00204       // You can as well build the set, clear the list and rebuild it in install order.
00205       PoolItemList instbackup_r;
00206       instbackup_r.swap( instlist_r );
00207 
00208       PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() ); // for install order
00209       PoolItemSet installed; // dummy, empty, should contain already installed
00210 
00211       InstallOrder order( pool_r, insset, installed );
00212       // start recursive depth-first-search
00213       order.init();
00214       MIL << "order.init() done" << endl;
00215       order.printAdj( XXX, false );
00217       // build install list in install order
00219       PoolItemList best_list;
00220       unsigned best_prio     = 0;
00221       unsigned best_medianum = 0;
00222 
00223       PoolItemList last_list;
00224       unsigned last_prio     = 0;
00225       unsigned last_medianum = 0;
00226 
00227       PoolItemList other_list;
00228 
00229       for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
00230         {
00231           MIL << "order.computeNextSet: " << items.size() << " resolvables" << endl;
00233           // items contains all objects we could install now. Pick all objects
00234           // from current media, or best media if none for current. Alwayys pick
00235           // objects that do not require media access.
00237 
00238           best_list.clear();
00239           last_list.clear();
00240           other_list.clear();
00241 
00242           for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
00243             {
00244               ResObject::constPtr cobj( cit->resolvable() );
00245               if (!cobj)
00246                 continue;
00247 
00248               if ( ! cobj->sourceMediaNr() ) {
00249                 XXX << "No media access required for " << *cit << endl;
00250                 order.setInstalled( *cit );
00251                 other_list.push_back( *cit );
00252                 continue;
00253               }
00254 
00255               XXX << "Package " << *cobj << ", media " << cobj->sourceMediaNr() << " last_medianum " << last_medianum << " best_medianum " << best_medianum << endl;
00256               if ( cobj->source().numericId() == last_prio &&
00257                    cobj->sourceMediaNr() == last_medianum ) {
00258                 // prefer packages on current media.
00259                 last_list.push_back( *cit );
00260                 continue;
00261               }
00262 
00263               if ( last_list.empty() ) {
00264                 // check for best media as long as there are no packages for current media.
00265 
00266                 if ( ! best_list.empty() ) {
00267 
00268                   if ( cobj->source().numericId() < best_prio ) {
00269                     best_list.clear(); // new best
00270                   } else if ( cobj->source().numericId() == best_prio ) {
00271                     if ( cobj->sourceMediaNr() < best_medianum ) {
00272                       best_list.clear(); // new best
00273                     } else if ( cobj->sourceMediaNr() == best_medianum ) {
00274                       best_list.push_back( *cit ); // same as best -> add
00275                       continue;
00276                     } else {
00277                       continue; // worse
00278                     }
00279                   } else {
00280                     continue; // worse
00281                   }
00282                 }
00283 
00284                 if ( best_list.empty() )
00285                   {
00286                     // first package or new best
00287                     best_list.push_back( *cit );
00288                     best_prio     = cobj->source().numericId();
00289                     best_medianum = cobj->sourceMediaNr();
00290                     continue;
00291                   }
00292               }
00293 
00294             } // for all objects in current set
00295 
00297           // remove objects picked from install order and append them to
00298           // install list.
00300           PoolItemList & take_list( last_list.empty() ? best_list : last_list );
00301           if ( last_list.empty() )
00302             {
00303               MIL << "SET NEW media " << best_medianum << endl;
00304               last_prio     = best_prio;
00305               last_medianum = best_medianum;
00306             }
00307           else
00308             {
00309               MIL << "SET CONTINUE" << endl;
00310             }
00311 
00312           for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
00313             {
00314               order.setInstalled( *it );
00315               XXX << "SET isrc " << (*it)->source().numericId() << " -> " << (*it) << endl;
00316             }
00317           // move everthing from take_list to the end of instlist_r, clean take_list
00318           instlist_r.splice( instlist_r.end(), take_list );
00319           // same for other_list
00320           instlist_r.splice( instlist_r.end(), other_list );
00321 
00322         } // for all sets computed
00323 
00324 
00325       if ( instbackup_r.size() != instlist_r.size() )
00326         {
00327           ERR << "***************** Lost packages in InstallOrder sort." << endl;
00328         }
00329 
00330     }
00331 
00332     /******************************************************************
00333      **
00334      ** FUNCTION NAME : operator<<
00335      ** FUNCTION TYPE : std::ostream &
00336     */
00337     std::ostream & operator<<( std::ostream & str, const GetResolvablesToInsDel & obj )
00338     {
00339       dumpPoolStats( str << "toInstall: " << endl,
00340                      obj._toInstall.begin(), obj._toInstall.end() ) << endl;
00341       dumpPoolStats( str << "toDelete: " << endl,
00342                      obj._toDelete.begin(), obj._toDelete.end() ) << endl;
00343       return str;
00344     }
00345 
00347   } // namespace pool
00350 } // namespace zypp
00352 

Generated on Mon Jun 5 19:10:34 2006 for zypp by  doxygen 1.4.6