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
00029 namespace zypp
00030 {
00031
00032 namespace pool
00033 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
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;
00051
00052
00053 CapSet obsoletes;
00054 for ( GetResolvablesToInsDel::PoolItemList::const_iterator it = instlist_r.begin();
00055 it != instlist_r.end(); ++it )
00056 {
00057 PoolItem_Ref item( *it );
00058 obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
00059 }
00060 if ( obsoletes.size() == 0 )
00061 return;
00062
00063
00064 GetResolvablesToInsDel::PoolItemList undelayed;
00065
00066 for ( GetResolvablesToInsDel::PoolItemList::iterator it = deleteList_r.begin();
00067 it != deleteList_r.end(); ++it )
00068 {
00069 PoolItem_Ref ipkg( *it );
00070 bool delayPkg = false;
00071
00072 for ( CapSet::iterator obs = obsoletes.begin();
00073 ! delayPkg && obs != obsoletes.end(); ++obs )
00074 {
00075
00076 for ( CapSet::const_iterator prov = ipkg->dep(Dep::PROVIDES).begin();
00077 prov != ipkg->dep(Dep::PROVIDES).end(); ++prov )
00078 {
00079 if ( obs->matches( *prov ) == CapMatch::yes )
00080 {
00081
00082 DBG << "Ignore appl_delete (should be obsoleted): " << ipkg << endl;
00083 delayPkg = true;
00084 ipkg.status().resetTransact( ResStatus::USER );
00085 break;
00086 }
00087 }
00088 }
00089 if ( ! delayPkg ) {
00090 DBG << "undelayed " << ipkg << endl;
00091 undelayed.push_back( ipkg );
00092 }
00093 }
00094
00095 deleteList_r.swap( undelayed );
00096 }
00097
00099
00100
00101
00102
00103 GetResolvablesToInsDel::GetResolvablesToInsDel( ResPool pool_r, Order order_r )
00104 {
00105 typedef std::set<PoolItem_Ref> PoolItemSet;
00106
00107 PoolItemList & dellist_r( _toDelete );
00108 PoolItemList & instlist_r( _toInstall );
00109 PoolItemList & srclist_r( _toSrcinstall );
00110
00111 for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
00112 {
00113 if (it->status().isToBeInstalled())
00114 {
00115 if ((*it)->kind() == ResTraits<SrcPackage>::kind) {
00116 srclist_r.push_back( *it );
00117 }
00118 else
00119 instlist_r.push_back( *it );
00120 }
00121 else if (it->status().isToBeUninstalled())
00122 {
00123 if ( it->status().isToBeUninstalledDueToObsolete() )
00124 {
00125 DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl;
00126 }
00127 else if ( it->status().isToBeUninstalledDueToUpgrade() )
00128 {
00129 DBG << "Ignore auto_delete (should be upgraded): " << *it << endl;
00130 }
00131 else {
00132 dellist_r.push_back( *it );
00133 }
00134 }
00135 }
00136
00137 MIL << "ResolvablesToInsDel: delete " << dellist_r.size()
00138 << ", install " << instlist_r.size()
00139 << ", srcinstall " << srclist_r.size() << endl;
00140
00142
00143
00144
00145
00146
00148 strip_obsoleted_to_delete( dellist_r, instlist_r );
00149
00150 if ( dellist_r.size() ) {
00152
00153
00154
00156 PoolItemSet delset( dellist_r.begin(), dellist_r.end() );
00157 PoolItemSet dummy;
00158
00159 InstallOrder order( pool_r, delset, dummy );
00160 order.init();
00161 const PoolItemList dsorted( order.getTopSorted() );
00162
00163 dellist_r.clear();
00164 for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
00165 cit != dsorted.rend(); ++cit )
00166 {
00167 dellist_r.push_back( *cit );
00168 }
00169 }
00170
00172
00173
00174
00176 if ( instlist_r.empty() )
00177 return;
00178
00180
00181
00183
00184
00185 PoolItemList instbackup_r;
00186 instbackup_r.swap( instlist_r );
00187
00188 PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() );
00189 PoolItemSet installed;
00190
00191 InstallOrder order( pool_r, insset, installed );
00192
00193 order.init();
00194 MIL << "order.init() done" << endl;
00195 order.printAdj( XXX, false );
00197
00199 PoolItemList best_list;
00200 unsigned best_prio = 0;
00201 unsigned best_medianum = 0;
00202
00203 PoolItemList last_list;
00204 unsigned last_prio = 0;
00205 unsigned last_medianum = 0;
00206
00207 PoolItemList other_list;
00208
00209 for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
00210 {
00211 MIL << "order.computeNextSet: " << items.size() << " resolvables" << endl;
00213
00214
00215
00217
00218 best_list.clear();
00219 last_list.clear();
00220 other_list.clear();
00221
00222 for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
00223 {
00224 ResObject::constPtr cobj( cit->resolvable() );
00225 if (!cobj)
00226 continue;
00227
00228 if ( ! cobj->sourceMediaNr() ) {
00229 XXX << "No media access required for " << *cit << endl;
00230 order.setInstalled( *cit );
00231 other_list.push_back( *cit );
00232 continue;
00233 }
00234
00235 if ( cobj->source().numericId() == last_prio &&
00236 cobj->sourceMediaNr() == last_medianum ) {
00237
00238 XXX << "Stay with current media " << *cit << endl;
00239 last_list.push_back( *cit );
00240 continue;
00241 }
00242
00243 if ( last_list.empty() ) {
00244
00245
00246 if ( ! best_list.empty() ) {
00247
00248 if ( order_r == ORDER_BY_MEDIANR )
00249 {
00250 if ( cobj->sourceMediaNr() < best_medianum ) {
00251 best_list.clear();
00252 } else if ( cobj->sourceMediaNr() == best_medianum ) {
00253 if ( cobj->source().numericId() < best_prio ) {
00254 best_list.clear();
00255 } else if ( cobj->source().numericId() == best_prio ) {
00256 XXX << "Add to best list " << *cit << endl;
00257 best_list.push_back( *cit );
00258 continue;
00259 } else {
00260 continue;
00261 }
00262 } else {
00263 continue;
00264 }
00265 }
00266 else
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 XXX << "Add to best list " << *cit << endl;
00275 best_list.push_back( *cit );
00276 continue;
00277 } else {
00278 continue;
00279 }
00280 } else {
00281 continue;
00282 }
00283 }
00284 }
00285
00286 if ( best_list.empty() )
00287 {
00288 XXX << "NEW BEST LIST [S" << cobj->source().numericId() << ":" << cobj->sourceMediaNr()
00289 << "] (last [S" << best_prio << ":" << best_medianum << "])" << endl;
00290 best_prio = cobj->source().numericId();
00291 best_medianum = cobj->sourceMediaNr();
00292
00293 XXX << "Add to best list " << *cit << endl;
00294 best_list.push_back( *cit );
00295 continue;
00296 }
00297 }
00298
00299 }
00300
00302
00303
00305 PoolItemList & take_list( last_list.empty() ? best_list : last_list );
00306 if ( last_list.empty() )
00307 {
00308 MIL << "SET NEW media [S" << best_prio << ":" << best_medianum << "]" << endl;
00309 last_prio = best_prio;
00310 last_medianum = best_medianum;
00311 }
00312 else
00313 {
00314 MIL << "SET CONTINUE [S" << best_prio << ":" << best_medianum << "]" << endl;
00315 }
00316
00317 for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
00318 {
00319 order.setInstalled( *it );
00320 XXX << "SET collect " << (*it) << endl;
00321 }
00322
00323 instlist_r.splice( instlist_r.end(), take_list );
00324
00325 instlist_r.splice( instlist_r.end(), other_list );
00326
00327 }
00328
00329
00330 if ( instbackup_r.size() != instlist_r.size() )
00331 {
00332 ERR << "***************** Lost packages in InstallOrder sort." << endl;
00333 }
00334
00335 }
00336
00337
00338
00339
00340
00341
00342 std::ostream & operator<<( std::ostream & str, const GetResolvablesToInsDel & obj )
00343 {
00344 dumpPoolStats( str << "toInstall: " << endl,
00345 obj._toInstall.begin(), obj._toInstall.end() ) << endl;
00346 dumpPoolStats( str << "toDelete: " << endl,
00347 obj._toDelete.begin(), obj._toDelete.end() ) << endl;
00348 return str;
00349 }
00350
00352 }
00355 }
00357