00001
00002
00003
00004
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
00039
00040
00041
00042
00043
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;
00052
00053
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;
00063
00064
00065 GetResolvablesToInsDel::PoolItemList undelayed;
00066
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
00073 for ( CapSet::iterator obs = obsoletes.begin();
00074 ! delayPkg && obs != obsoletes.end(); ++obs )
00075 {
00076
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
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
00096 deleteList_r.swap( undelayed );
00097 }
00098
00100
00101
00102
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
00145
00146
00147
00149 strip_obsoleted_to_delete( dellist_r, instlist_r );
00150
00151 if ( dellist_r.size() ) {
00153
00154
00155
00157 PoolItemSet delset( dellist_r.begin(), dellist_r.end() );
00158 PoolItemSet dummy;
00159
00160 InstallOrder order( pool_r, delset, dummy );
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
00175
00177 if ( instlist_r.empty() )
00178 return;
00179
00180 #warning Source Rank Priority ?
00181 #if 0
00182
00183
00185 typedef map<unsigned,unsigned> RankPriority;
00186
00187 RankPriority rankPriority;
00188 {
00189 InstSrcManager::ISrcIdList sourcerank( Y2PM::instSrcManager().instOrderSources() );
00190
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
00201
00203
00204
00205 PoolItemList instbackup_r;
00206 instbackup_r.swap( instlist_r );
00207
00208 PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() );
00209 PoolItemSet installed;
00210
00211 InstallOrder order( pool_r, insset, installed );
00212
00213 order.init();
00214 MIL << "order.init() done" << endl;
00215 order.printAdj( XXX, false );
00217
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
00234
00235
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
00259 last_list.push_back( *cit );
00260 continue;
00261 }
00262
00263 if ( last_list.empty() ) {
00264
00265
00266 if ( ! best_list.empty() ) {
00267
00268 if ( cobj->source().numericId() < best_prio ) {
00269 best_list.clear();
00270 } else if ( cobj->source().numericId() == best_prio ) {
00271 if ( cobj->sourceMediaNr() < best_medianum ) {
00272 best_list.clear();
00273 } else if ( cobj->sourceMediaNr() == best_medianum ) {
00274 best_list.push_back( *cit );
00275 continue;
00276 } else {
00277 continue;
00278 }
00279 } else {
00280 continue;
00281 }
00282 }
00283
00284 if ( best_list.empty() )
00285 {
00286
00287 best_list.push_back( *cit );
00288 best_prio = cobj->source().numericId();
00289 best_medianum = cobj->sourceMediaNr();
00290 continue;
00291 }
00292 }
00293
00294 }
00295
00297
00298
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
00318 instlist_r.splice( instlist_r.end(), take_list );
00319
00320 instlist_r.splice( instlist_r.end(), other_list );
00321
00322 }
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
00335
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 }
00350 }
00352