libzypp 8.13.6
|
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