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/LogTools.h"
00016 #include "zypp/sat/Solvable.h"
00017 #include "zypp/sat/WhatObsoletes.h"
00018 #include "zypp/pool/GetResolvablesToInsDel.h"
00019 #include "zypp/pool/PoolStats.h"
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 
00029 namespace zypp
00030 { 
00031 
00032   namespace pool
00033   { 
00034 
00035     /******************************************************************
00036      **
00037      ** FUNCTION NAME : strip_obsoleted_to_delete
00038      ** FUNCTION TYPE : void
00039      **
00040      ** strip packages to_delete which get obsoleted by
00041      ** to_install (i.e. delay deletion in case the
00042      ** obsoleting package likes to save whatever...
00043     */
00044 
00045     static void
00046     strip_obsoleted_to_delete( GetResolvablesToInsDel::PoolItemList & deleteList_r,
00047                                const GetResolvablesToInsDel::PoolItemList & instlist_r )
00048     {
00049       if ( deleteList_r.size() == 0 || instlist_r.size() == 0 )
00050         return; // ---> nothing to do
00051 
00052       // These are all installed packages obsoleted by any package to be installed.
00053       // Actually we expect all of them to appear in the deleteList_r, and we want
00054       // to kick them out. Rpm will delete them when the obsoleter gets installed.
00055       sat::WhatObsoletes obsoleted( instlist_r.begin(), instlist_r.end() );
00056       for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
00057       {
00058         DBG << "Ignore appl_delete (should be obsoleted): " << *it << endl;
00059         deleteList_r.remove( *it );
00060       }
00061 
00062       MIL << "Undelayed deletes: " << deleteList_r << endl;
00063     }
00064 
00066     //
00067     //  METHOD NAME : GetResolvablesToInsDel::GetResolvablesToInsDel
00068     //  METHOD TYPE : Ctor
00069     //
00070     GetResolvablesToInsDel::GetResolvablesToInsDel( ResPool pool_r, Order order_r )
00071     {
00072       typedef std::set<PoolItem> PoolItemSet;
00073 
00074       PoolItemList & dellist_r( _toDelete );
00075       PoolItemList & instlist_r( _toInstall );
00076       PoolItemList & srclist_r( _toSrcinstall );
00077 
00078       for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
00079         {
00080           if (it->status().isToBeInstalled())
00081             {
00082               if ((*it)->kind() == ResKind::srcpackage) {
00083                 srclist_r.push_back( *it );
00084               }
00085               else
00086                 instlist_r.push_back( *it );
00087             }
00088           else if (it->status().isToBeUninstalled())
00089             {
00090               if ( it->status().isToBeUninstalledDueToObsolete() )
00091                 {
00092                   DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl;
00093                 }
00094               else if ( it->status().isToBeUninstalledDueToUpgrade() )
00095                 {
00096                   DBG << "Ignore auto_delete (should be upgraded): " << *it << endl;
00097                 }
00098               else {
00099                 dellist_r.push_back( *it );
00100               }
00101             }
00102         }
00103 
00104       MIL << "ResolvablesToInsDel: delete " << dellist_r.size()
00105       << ", install " << instlist_r.size()
00106       << ", srcinstall " << srclist_r.size() << endl;
00107 
00109       //
00110       // strip packages to_delete which get obsoleted by
00111       // to_install (i.e. delay deletion in case the
00112       // obsoleting package likes to save whatever...
00113       //
00115       strip_obsoleted_to_delete( dellist_r, instlist_r );
00116 
00117       if ( dellist_r.size() ) {
00119         //
00120         // sort delete list...
00121         //
00123         PoolItemSet delset( dellist_r.begin(), dellist_r.end() );  // for delete order
00124         PoolItemSet dummy; // dummy, empty, should contain already installed
00125 
00126         InstallOrder order( pool_r, delset, dummy ); // sort according top prereq
00127         order.init();
00128         const PoolItemList dsorted( order.getTopSorted() );
00129 
00130         dellist_r.clear();
00131         for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
00132               cit != dsorted.rend(); ++cit )
00133           {
00134             dellist_r.push_back( *cit );
00135           }
00136       }
00137 
00139       //
00140       // sort installed list...
00141       //
00143       if ( instlist_r.empty() )
00144         return;
00145 
00147       // Compute install order according to packages prereq.
00148       // Try to group packages with respect to the desired install order
00150       // backup list for debug purpose.
00151       // You can as well build the set, clear the list and rebuild it in install order.
00152       PoolItemList instbackup_r;
00153       instbackup_r.swap( instlist_r );
00154 
00155       PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() ); // for install order
00156       PoolItemSet installed; // dummy, empty, should contain already installed
00157 
00158       InstallOrder order( pool_r, insset, installed );
00159       // start recursive depth-first-search
00160       order.init();
00161       MIL << "order.init() done" << endl;
00162       order.printAdj( XXX, false );
00164       // build install list in install order
00166       PoolItemList best_list;
00167       sat::detail::RepoIdType best_prio     = 0;
00168       unsigned best_medianum = 0;
00169 
00170       PoolItemList last_list;
00171       sat::detail::RepoIdType last_prio     = 0;
00172       unsigned last_medianum = 0;
00173 
00174       PoolItemList other_list;
00175 
00176       for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
00177         {
00178           XXX << "order.computeNextSet: " << items.size() << " resolvables" << endl;
00180           // items contains all objects we could install now. Pick all objects
00181           // from current media, or best media if none for current. Alwayys pick
00182           // objects that do not require media access.
00184 
00185           best_list.clear();
00186           last_list.clear();
00187           other_list.clear();
00188 
00189           for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
00190             {
00191               ResObject::constPtr cobj( cit->resolvable() );
00192               if (!cobj)
00193                 continue;
00194 
00195               if ( ! cobj->mediaNr() ) {
00196                 XXX << "No media access required for " << *cit << endl;
00197                 order.setInstalled( *cit );
00198                 other_list.push_back( *cit );
00199                 continue;
00200               }
00201 
00202               if ( cobj->satSolvable().repository().id() == last_prio &&
00203                    cobj->mediaNr() == last_medianum ) {
00204                 // prefer packages on current media.
00205                 XXX << "Stay with current media " << *cit << endl;
00206                 last_list.push_back( *cit );
00207                 continue;
00208               }
00209 
00210               if ( last_list.empty() ) {
00211                 // check for best media as long as there are no packages for current media.
00212 
00213                 if ( ! best_list.empty() ) {
00214 
00215                   if ( order_r == ORDER_BY_MEDIANR )
00216                     {
00217                       if ( cobj->mediaNr() < best_medianum ) {
00218                         best_list.clear(); // new best
00219                       } else if ( cobj->mediaNr() == best_medianum ) {
00220                         if ( cobj->satSolvable().repository().id() < best_prio ) {
00221                           best_list.clear(); // new best
00222                         } else if ( cobj->satSolvable().repository().id() == best_prio ) {
00223                           XXX << "Add to best list " << *cit << endl;
00224                           best_list.push_back( *cit ); // same as best -> add
00225                           continue;
00226                         } else {
00227                           continue; // worse
00228                         }
00229                       } else {
00230                         continue; // worse
00231                       }
00232                     }
00233                   else // default: ORDER_BY_SOURCE
00234                     {
00235                       if ( cobj->satSolvable().repository().id() < best_prio ) {
00236                         best_list.clear(); // new best
00237                       } else if ( cobj->satSolvable().repository().id() == best_prio ) {
00238                         if ( cobj->mediaNr() < best_medianum ) {
00239                           best_list.clear(); // new best
00240                         } else if ( cobj->mediaNr() == best_medianum ) {
00241                           XXX << "Add to best list " << *cit << endl;
00242                           best_list.push_back( *cit ); // same as best -> add
00243                           continue;
00244                         } else {
00245                           continue; // worse
00246                         }
00247                       } else {
00248                         continue; // worse
00249                       }
00250                     }
00251                 }
00252 
00253                 if ( best_list.empty() )
00254                   {
00255                     XXX << "NEW BEST LIST [S" << cobj->satSolvable().repository().id() << ":" << cobj->mediaNr()
00256                         << "] (last [S" << best_prio << ":" << best_medianum << "])" << endl;
00257                     best_prio     = cobj->satSolvable().repository().id();
00258                     best_medianum = cobj->mediaNr();
00259                     // first package or new best
00260                     XXX << "Add to best list " << *cit << endl;
00261                     best_list.push_back( *cit );
00262                     continue;
00263                   }
00264               }
00265 
00266             } // for all objects in current set
00267 
00269           // remove objects picked from install order and append them to
00270           // install list.
00272           PoolItemList & take_list( last_list.empty() ? best_list : last_list );
00273           if ( last_list.empty() )
00274             {
00275               MIL << "SET NEW media [S" << best_prio << ":" << best_medianum << "]" << endl;
00276               last_prio     = best_prio;
00277               last_medianum = best_medianum;
00278             }
00279           else
00280             {
00281               XXX << "SET CONTINUE [S" << best_prio << ":" << best_medianum << "]" << endl;
00282             }
00283 
00284           for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
00285             {
00286               order.setInstalled( *it );
00287               XXX << "SET collect " << (*it) << endl;
00288             }
00289           // move everthing from take_list to the end of instlist_r, clean take_list
00290           instlist_r.splice( instlist_r.end(), take_list );
00291           // same for other_list
00292           instlist_r.splice( instlist_r.end(), other_list );
00293 
00294         } // for all sets computed
00295 
00296 
00297       MIL << "order done" << endl;
00298       if ( instbackup_r.size() != instlist_r.size() )
00299         {
00300           ERR << "***************** Lost packages in InstallOrder sort." << endl;
00301         }
00302 
00303     }
00304 
00305     /******************************************************************
00306      **
00307      ** FUNCTION NAME : operator<<
00308      ** FUNCTION TYPE : std::ostream &
00309     */
00310     std::ostream & operator<<( std::ostream & str, const GetResolvablesToInsDel & obj )
00311     {
00312       dumpPoolStats( str << "toInstall: " << endl,
00313                      obj._toInstall.begin(), obj._toInstall.end() ) << endl;
00314       dumpPoolStats( str << "toDelete: " << endl,
00315                      obj._toDelete.begin(), obj._toDelete.end() ) << endl;
00316       return str;
00317     }
00318 
00320   } // namespace pool
00323 } // namespace zypp
00325 

doxygen