libzypp  11.13.5
GetResolvablesToInsDel.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <set>
14 
15 #include "zypp/base/LogTools.h"
16 #include "zypp/base/LogControl.h"
17 #include "zypp/sat/Solvable.h"
18 #include "zypp/sat/WhatObsoletes.h"
20 #include "zypp/pool/PoolStats.h"
22 
23 #include "zypp/Resolver.h"
24 #include "zypp/sat/Transaction.h"
25 
26 using std::endl;
28 
29 #undef ZYPP_BASE_LOGGER_LOGGROUP
30 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::GetResolvablesToInsDel"
31 
33 namespace zypp
34 {
35 
36  namespace pool
37  {
38 
39  /******************************************************************
40  **
41  ** FUNCTION NAME : strip_obsoleted_to_delete
42  ** FUNCTION TYPE : void
43  **
44  ** strip packages to_delete which get obsoleted by
45  ** to_install (i.e. delay deletion in case the
46  ** obsoleting package likes to save whatever...
47  */
48 
49  static void
51  const GetResolvablesToInsDel::PoolItemList & instlist_r )
52  {
53  if ( deleteList_r.size() == 0 || instlist_r.size() == 0 )
54  return; // ---> nothing to do
55 
56  // These are all installed packages obsoleted by any package to be installed.
57  // Actually we expect all of them to appear in the deleteList_r, and we want
58  // to kick them out. Rpm will delete them when the obsoleter gets installed.
59  sat::WhatObsoletes obsoleted( instlist_r.begin(), instlist_r.end() );
60  for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
61  {
62  DBG << "Ignore appl_delete (should be obsoleted): " << *it << endl;
63  deleteList_r.remove( *it );
64  }
65 
66  MIL << "Undelayed deletes: " << deleteList_r << endl;
67  }
68 
70  //
71  // METHOD NAME : GetResolvablesToInsDel::GetResolvablesToInsDel
72  // METHOD TYPE : Ctor
73  //
75  {
77  typedef std::set<PoolItem> PoolItemSet;
78 
79  PoolItemList & dellist_r( _toDelete );
80  PoolItemList & instlist_r( _toInstall );
81  PoolItemList & srclist_r( _toSrcinstall );
82 
83  for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
84  {
85  if (it->status().isToBeInstalled())
86  {
87  if ((*it)->kind() == ResKind::srcpackage) {
88  srclist_r.push_back( *it );
89  }
90  else
91  instlist_r.push_back( *it );
92  }
93  else if (it->status().isToBeUninstalled())
94  {
95  if ( it->status().isToBeUninstalledDueToObsolete() )
96  {
97  DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl;
98  }
99  else if ( it->status().isToBeUninstalledDueToUpgrade() )
100  {
101  DBG << "Ignore auto_delete (should be upgraded): " << *it << endl;
102  }
103  else {
104  dellist_r.push_back( *it );
105  }
106  }
107  }
108 
109  MIL << "ResolvablesToInsDel: delete " << dellist_r.size()
110  << ", install " << instlist_r.size()
111  << ", srcinstall " << srclist_r.size() << endl;
112 
114  //
115  // strip packages to_delete which get obsoleted by
116  // to_install (i.e. delay deletion in case the
117  // obsoleting package likes to save whatever...
118  //
120  strip_obsoleted_to_delete( dellist_r, instlist_r );
121 
122  if ( dellist_r.size() ) {
124  //
125  // sort delete list...
126  //
128  PoolItemSet delset( dellist_r.begin(), dellist_r.end() ); // for delete order
129  PoolItemSet dummy; // dummy, empty, should contain already installed
130 
131  InstallOrder order( pool_r, delset, dummy ); // sort according top prereq
132  order.init();
133  const PoolItemList dsorted( order.getTopSorted() );
134 
135  dellist_r.clear();
136  for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
137  cit != dsorted.rend(); ++cit )
138  {
139  dellist_r.push_back( *cit );
140  }
141  }
142 
144  //
145  // sort installed list...
146  //
148  if ( instlist_r.empty() )
149  return;
150 
152  // Compute install order according to packages prereq.
153  // Try to group packages with respect to the desired install order
155  // backup list for debug purpose.
156  // You can as well build the set, clear the list and rebuild it in install order.
157  PoolItemList instbackup_r;
158  instbackup_r.swap( instlist_r );
159 
160  PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() ); // for install order
161  PoolItemSet installed; // dummy, empty, should contain already installed
162 
163  InstallOrder order( pool_r, insset, installed );
164  // start recursive depth-first-search
165  order.init();
166  MIL << "order.init() done" << endl;
167  order.printAdj( XXX, false );
169  // build install list in install order
171  PoolItemList best_list;
172  sat::detail::RepoIdType best_prio = 0;
173  unsigned best_medianum = 0;
174 
175  PoolItemList last_list;
176  sat::detail::RepoIdType last_prio = 0;
177  unsigned last_medianum = 0;
178 
179  PoolItemList other_list;
180 
181  for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
182  {
183  XXX << "order.computeNextSet: " << items.size() << " resolvables" << endl;
185  // items contains all objects we could install now. Pick all objects
186  // from current media, or best media if none for current. Alwayys pick
187  // objects that do not require media access.
189 
190  best_list.clear();
191  last_list.clear();
192  other_list.clear();
193 
194  for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
195  {
196  ResObject::constPtr cobj( cit->resolvable() );
197  if (!cobj)
198  continue;
199 
200  if ( ! cobj->mediaNr() ) {
201  XXX << "No media access required for " << *cit << endl;
202  order.setInstalled( *cit );
203  other_list.push_back( *cit );
204  continue;
205  }
206 
207  if ( cobj->satSolvable().repository().id() == last_prio &&
208  cobj->mediaNr() == last_medianum ) {
209  // prefer packages on current media.
210  XXX << "Stay with current media " << *cit << endl;
211  last_list.push_back( *cit );
212  continue;
213  }
214 
215  if ( last_list.empty() ) {
216  // check for best media as long as there are no packages for current media.
217 
218  if ( ! best_list.empty() ) {
219 
220  if ( order_r == ORDER_BY_MEDIANR )
221  {
222  if ( cobj->mediaNr() < best_medianum ) {
223  best_list.clear(); // new best
224  } else if ( cobj->mediaNr() == best_medianum ) {
225  if ( cobj->satSolvable().repository().id() < best_prio ) {
226  best_list.clear(); // new best
227  } else if ( cobj->satSolvable().repository().id() == best_prio ) {
228  XXX << "Add to best list " << *cit << endl;
229  best_list.push_back( *cit ); // same as best -> add
230  continue;
231  } else {
232  continue; // worse
233  }
234  } else {
235  continue; // worse
236  }
237  }
238  else // default: ORDER_BY_SOURCE
239  {
240  if ( cobj->satSolvable().repository().id() < best_prio ) {
241  best_list.clear(); // new best
242  } else if ( cobj->satSolvable().repository().id() == best_prio ) {
243  if ( cobj->mediaNr() < best_medianum ) {
244  best_list.clear(); // new best
245  } else if ( cobj->mediaNr() == best_medianum ) {
246  XXX << "Add to best list " << *cit << endl;
247  best_list.push_back( *cit ); // same as best -> add
248  continue;
249  } else {
250  continue; // worse
251  }
252  } else {
253  continue; // worse
254  }
255  }
256  }
257 
258  if ( best_list.empty() )
259  {
260  XXX << "NEW BEST LIST [S" << cobj->satSolvable().repository().id() << ":" << cobj->mediaNr()
261  << "] (last [S" << best_prio << ":" << best_medianum << "])" << endl;
262  best_prio = cobj->satSolvable().repository().id();
263  best_medianum = cobj->mediaNr();
264  // first package or new best
265  XXX << "Add to best list " << *cit << endl;
266  best_list.push_back( *cit );
267  continue;
268  }
269  }
270 
271  } // for all objects in current set
272 
274  // remove objects picked from install order and append them to
275  // install list.
277  PoolItemList & take_list( last_list.empty() ? best_list : last_list );
278  if ( last_list.empty() )
279  {
280  MIL << "SET NEW media [S" << best_prio << ":" << best_medianum << "]" << endl;
281  last_prio = best_prio;
282  last_medianum = best_medianum;
283  }
284  else
285  {
286  XXX << "SET CONTINUE [S" << best_prio << ":" << best_medianum << "]" << endl;
287  }
288 
289  for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
290  {
291  order.setInstalled( *it );
292  XXX << "SET collect " << (*it) << endl;
293  }
294  // move everthing from take_list to the end of instlist_r, clean take_list
295  instlist_r.splice( instlist_r.end(), take_list );
296  // same for other_list
297  instlist_r.splice( instlist_r.end(), other_list );
298 
299  } // for all sets computed
300 
301 
302  MIL << "order done" << endl;
303  if ( instbackup_r.size() != instlist_r.size() )
304  {
305  ERR << "***************** Lost packages in InstallOrder sort." << endl;
306  }
307 
308  }
309 
311  {
312  SEC << "START debugDiffTransaction" << endl;
313  sat::Transaction trans( ResPool::instance().resolver().getTransaction() );
314 
315  {
316  const PoolItemList & clist( _toDelete );
317  for_( it, clist.begin(), clist.end() )
318  {
319  sat::Transaction::const_iterator ci( trans.find( *it ) );
320  if ( ci == trans.end() )
321  ERR << "Missing to del in NEW trans: " << *it << endl;
322  }
323  }
324  {
325  const PoolItemList & clist( _toInstall );
326  for_( it, clist.begin(), clist.end() )
327  {
328  sat::Transaction::const_iterator ci( trans.find( *it ) );
329  if ( ci == trans.end() )
330  ERR << "Missing to ins in NEW trans: " << *it << endl;
331  }
332  }
333  {
334  const PoolItemList & clist( _toSrcinstall );
335  for_( it, clist.begin(), clist.end() )
336  {
337  sat::Transaction::const_iterator ci( trans.find( *it ) );
338  if ( ci == trans.end() )
339  ERR << "Missing srcins in NEW trans: " << *it << endl;
340  }
341  }
342 
343  SEC << "END debugDiffTransaction" << endl;
344  }
345 
346  /******************************************************************
347  **
348  ** FUNCTION NAME : operator<<
349  ** FUNCTION TYPE : std::ostream &
350  */
351  std::ostream & operator<<( std::ostream & str, const GetResolvablesToInsDel & obj )
352  {
353  dumpPoolStats( str << "toInstall: " << endl,
354  obj._toInstall.begin(), obj._toInstall.end() ) << endl;
355  dumpPoolStats( str << "toDelete: " << endl,
356  obj._toDelete.begin(), obj._toDelete.end() ) << endl;
357  return str;
358  }
359 
361  } // namespace pool
364 } // namespace zypp
366