libzypp  13.10.6
PoolImpl.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_POOL_POOLIMPL_H
13 #define ZYPP_POOL_POOLIMPL_H
14 
15 #include <iosfwd>
16 
17 #include "zypp/base/Easy.h"
18 #include "zypp/base/LogTools.h"
19 #include "zypp/base/SerialNumber.h"
20 #include "zypp/APIConfig.h"
21 
22 #include "zypp/pool/PoolTraits.h"
23 #include "zypp/ResPoolProxy.h"
24 #include "zypp/PoolQueryResult.h"
25 
26 #include "zypp/sat/Pool.h"
27 #include "zypp/Product.h"
28 
29 using std::endl;
30 
32 namespace zypp
33 {
34 
35  namespace resstatus
36  {
43  {
45  static void setLock( ResStatus & status_r, bool yesno_r )
46  {
47  status_r.setLock( yesno_r, ResStatus::USER );
48  status_r.setUserLockQueryMatch( yesno_r );
49  }
50 
52  static void reapplyLock( ResStatus & status_r, bool yesno_r )
53  {
54  if ( yesno_r && ! status_r.isUserLockQueryMatch() )
55  {
56  status_r.setLock( yesno_r, ResStatus::USER );
57  status_r.setUserLockQueryMatch( yesno_r );
58  }
59  }
60 
62  static int diffLock( const ResStatus & status_r )
63  {
64  bool userLock( status_r.isUserLocked() );
65  if ( userLock == status_r.isUserLockQueryMatch() )
66  return 0;
67  return userLock ? 1 : -1;
68  }
69 
70  };
71  }
72 
73  namespace
74  {
75  inline PoolQuery makeTrivialQuery( IdString ident_r )
76  {
77  sat::Solvable::SplitIdent ident( ident_r );
78 
79  PoolQuery q;
80  q.addAttribute( sat::SolvAttr::name, ident.name().asString() );
81  q.addKind( ident.kind() );
82  q.setMatchExact();
83  q.setCaseSensitive(true);
84  return q;
85  }
86 
87  inline bool hardLockQueriesRemove( pool::PoolTraits::HardLockQueries & activeLocks_r, IdString ident_r )
88  {
89  unsigned s( activeLocks_r.size() );
90  activeLocks_r.remove( makeTrivialQuery( ident_r ) );
91  return( activeLocks_r.size() != s );
92  }
93 
94  inline bool hardLockQueriesAdd( pool::PoolTraits::HardLockQueries & activeLocks_r, IdString ident_r )
95  {
96  PoolQuery q( makeTrivialQuery( ident_r ) );
97  for_( it, activeLocks_r.begin(), activeLocks_r.end() )
98  {
99  if ( *it == q )
100  return false;
101  }
102  activeLocks_r.push_back( q );
103  return true;
104  }
105  }
106 
108  namespace pool
109  {
110 
112  //
113  // CLASS NAME : PoolImpl
114  //
116  class PoolImpl
117  {
118  friend std::ostream & operator<<( std::ostream & str, const PoolImpl & obj );
119 
120  public:
126 
128 
130 
131  public:
133  PoolImpl();
135  ~PoolImpl();
136 
137  public:
139  const sat::Pool satpool() const
140  { return sat::Pool::instance(); }
141 
143  const SerialNumber & serial() const
144  { return satpool().serial(); }
145 
147  //
149  public:
151  bool empty() const
152  { return satpool().solvablesEmpty(); }
153 
155  size_type size() const
156  { return satpool().solvablesSize(); }
157 
159  { return make_filter_begin( pool::ByPoolItem(), store() ); }
160 
162  { return make_filter_end( pool::ByPoolItem(), store() ); }
163 
164  public:
170  PoolItem find( const sat::Solvable & slv_r ) const
171  {
172  const ContainerT & mystore( store() );
173  return( slv_r.id() < mystore.size() ? mystore[slv_r.id()] : PoolItem() );
174  }
175 
177  //
179  public:
182  void SaveState( const ResObject::Kind & kind_r );
183 
184  void RestoreState( const ResObject::Kind & kind_r );
186 
188  //
190  public:
191  ResPoolProxy proxy( ResPool self ) const
192  {
193  checkSerial();
194  if ( !_poolProxy )
195  {
196  _poolProxy.reset( new ResPoolProxy( self, *this ) );
197  }
198  return *_poolProxy;
199  }
200 
201  public:
204  { checkSerial(); return satpool().reposSize(); }
205 
207  { checkSerial(); return satpool().reposBegin(); }
208 
210  { checkSerial(); return satpool().reposEnd(); }
211 
212  Repository reposFind( const std::string & alias_r ) const
213  { checkSerial(); return satpool().reposFind( alias_r ); }
214 
216  //
218  public:
221 
223  { return _hardLockQueries; }
224 
225  void reapplyHardLocks() const
226  {
227  // It is assumed that reapplyHardLocks is called after new
228  // items were added to the pool, but the _hardLockQueries
229  // did not change since. Action is to be performed only on
230  // those items that gained the bit in the UserLockQueryField.
231  MIL << "Re-apply " << _hardLockQueries.size() << " HardLockQueries" << endl;
232  PoolQueryResult locked;
233  for_( it, _hardLockQueries.begin(), _hardLockQueries.end() )
234  {
235  locked += *it;
236  }
237  MIL << "HardLockQueries match " << locked.size() << " Solvables." << endl;
238  for_( it, begin(), end() )
239  {
240  resstatus::UserLockQueryManip::reapplyLock( it->status(), locked.contains( *it ) );
241  }
242  }
243 
244  void setHardLockQueries( const HardLockQueries & newLocks_r )
245  {
246  MIL << "Apply " << newLocks_r.size() << " HardLockQueries" << endl;
247  _hardLockQueries = newLocks_r;
248  // now adjust the pool status
249  PoolQueryResult locked;
250  for_( it, _hardLockQueries.begin(), _hardLockQueries.end() )
251  {
252  locked += *it;
253  }
254  MIL << "HardLockQueries match " << locked.size() << " Solvables." << endl;
255  for_( it, begin(), end() )
256  {
257  resstatus::UserLockQueryManip::setLock( it->status(), locked.contains( *it ) );
258  }
259  }
260 
261  bool getHardLockQueries( HardLockQueries & activeLocks_r )
262  {
263  activeLocks_r = _hardLockQueries; // current queries
264  // Now diff to the pool collecting names only.
265  // Thus added and removed locks are not necessarily
266  // disjoint. Added locks win.
267  typedef std::tr1::unordered_set<IdString> IdentSet;
268  IdentSet addedLocks;
269  IdentSet removedLocks;
270  for_( it, begin(), end() )
271  {
272  switch ( resstatus::UserLockQueryManip::diffLock( it->status() ) )
273  {
274  case 0: // unchanged
275  break;
276  case 1:
277  addedLocks.insert( it->satSolvable().ident() );
278  break;
279  case -1:
280  removedLocks.insert( it->satSolvable().ident() );
281  break;
282  }
283  }
284  // now the bad part - adjust the queries
285  bool setChanged = false;
286  for_( it, removedLocks.begin(), removedLocks.end() )
287  {
288  if ( addedLocks.find( *it ) != addedLocks.end() )
289  continue; // Added locks win
290  if ( hardLockQueriesRemove( activeLocks_r, *it ) && ! setChanged )
291  setChanged = true;
292  }
293  for_( it, addedLocks.begin(), addedLocks.end() )
294  {
295  if ( hardLockQueriesAdd( activeLocks_r, *it ) && ! setChanged )
296  setChanged = true;
297  }
298  return setChanged;
299  }
300 
301  public:
304 
305  const AutoSoftLocks & autoSoftLocks() const
306  { return _autoSoftLocks; }
307 
309  { return( _autoSoftLocks.find( solv_r.ident() ) != _autoSoftLocks.end() ); }
310 
311  void setAutoSoftLocks( const AutoSoftLocks & newLocks_r )
312  {
313  MIL << "Apply " << newLocks_r.size() << " AutoSoftLocks: " << newLocks_r << endl;
314  _autoSoftLocks = newLocks_r;
315  // now adjust the pool status
316  for_( it, begin(), end() )
317  {
318  if ( ! it->status().isKept() )
319  continue;
320 
321  if ( autoSoftLockAppliesTo( it->satSolvable() ) )
322  it->status().setSoftLock( ResStatus::USER );
323  else
324  it->status().resetTransact( ResStatus::USER );
325  }
326  }
327 
328  void getActiveSoftLocks( AutoSoftLocks & activeLocks_r )
329  {
330  activeLocks_r = _autoSoftLocks; // current soft-locks
331  AutoSoftLocks todel; // + names to be deleted
332  AutoSoftLocks toins; // - names to be installed
333 
334  for_( it, begin(), end() )
335  {
336  ResStatus & status( it->status() );
337  if ( ! ( status.isByUser() || status.isByApplLow() ) )
338  continue; // ignore non-user requests; ApplLow means selected
339  // by solver, but on behalf of a user request.
340 
341  switch ( status.getTransactValue() )
342  {
344  // Filter only items included in the last recommended set.
345  if ( status.isRecommended() )
346  activeLocks_r.insert( it->satSolvable().ident() );
347  break;
348  case ResStatus::LOCKED:
349  // NOOP
350  break;
351  case ResStatus::TRANSACT:
352  (status.isInstalled() ? todel : toins).insert( it->satSolvable().ident() );
353  break;
354  }
355  }
356  for_( it, todel.begin(), todel.end() )
357  {
358  activeLocks_r.insert( *it );
359  }
360  for_( it, toins.begin(), toins.end() )
361  {
362  activeLocks_r.erase( *it );
363  }
364  }
365 
366  public:
367  const ContainerT & store() const
368  {
369  checkSerial();
370  if ( _storeDirty )
371  {
372  sat::Pool pool( satpool() );
373  bool addedItems = false;
374  std::list<PoolItem> addedProducts;
375 
376  _store.resize( pool.capacity() );
377 
378  if ( pool.capacity() )
379  {
380  for ( sat::detail::SolvableIdType i = pool.capacity()-1; i != 0; --i )
381  {
382  sat::Solvable s( i );
383  PoolItem & pi( _store[i] );
384  if ( ! s && pi )
385  {
386  // the PoolItem got invalidated (e.g unloaded repo)
387  pi = PoolItem();
388  }
389  else if ( s && ! pi )
390  {
391  // new PoolItem to add
392  pi = PoolItem::makePoolItem( s ); // the only way to create a new one!
393  // remember products for buddy processing (requires clean store)
394  if ( s.isKind( ResKind::product ) )
395  addedProducts.push_back( pi );
396  // and on the fly check for weak locks...
397  if ( autoSoftLockAppliesTo( s ) )
398  {
400  }
401  if ( !addedItems )
402  addedItems = true;
403  }
404  }
405  }
406  _storeDirty = false;
407 
408  // Now, as the pool is adjusted, ....
409 
410  // .... we check for product buddies.
411  if ( ! addedProducts.empty() )
412  {
413  for_( it, addedProducts.begin(), addedProducts.end() )
414  {
415  it->setBuddy( asKind<Product>(*it)->referencePackage() );
416  }
417  }
418 
419  // .... we must reapply those query based hard locks.
420  if ( addedItems )
421  {
423  }
424  }
425  return _store;
426  }
427 
428  const Id2ItemT & id2item () const
429  {
430  checkSerial();
431  if ( _id2itemDirty )
432  {
433  store();
434  _id2item = Id2ItemT( size() );
435  for_( it, begin(), end() )
436  {
437  const sat::Solvable &s = (*it)->satSolvable();
438  sat::detail::IdType id = s.ident().id();
439  if ( s.isKind( ResKind::srcpackage ) )
440  id = -id;
441  _id2item.insert( std::make_pair( id, *it ) );
442  }
443  //INT << _id2item << endl;
444  _id2itemDirty = false;
445  }
446  return _id2item;
447  }
448 
450  //
452  private:
453  void checkSerial() const
454  {
455  if ( _watcher.remember( serial() ) )
456  invalidate();
457  satpool().prepare(); // always ajust dependencies.
458  }
459 
460  void invalidate() const
461  {
462  _storeDirty = true;
463  _id2itemDirty = true;
464  _id2item.clear();
465  _poolProxy.reset();
466  }
467 
468  private:
475 
476  private:
477  mutable shared_ptr<ResPoolProxy> _poolProxy;
478 
479  private:
484  };
486 
488  } // namespace pool
491 } // namespace zypp
493 #endif // ZYPP_POOL_POOLIMPL_H
#define MIL
Definition: Logger.h:47
Simple serial number watcher.
Definition: SerialNumber.h:122
ItemContainerT::size_type size_type
Definition: PoolTraits.h:75
int IdType
Generic Id type.
Definition: PoolMember.h:82
bool autoSoftLockAppliesTo(sat::Solvable solv_r) const
Definition: PoolImpl.h:308
A Solvable object within the sat Pool.
Definition: Solvable.h:55
sat::detail::SolvableIdType SolvableIdType
Definition: PoolImpl.h:129
bool contains(sat::Solvable result_r) const
Test whether some item is in the result set.
IdString ident() const
The identifier.
Definition: Solvable.cc:165
void SaveState(const ResObject::Kind &kind_r)
size_type reposSize() const
Number of repos in Pool.
Definition: Pool.cc:54
PoolTraits::HardLockQueries HardLockQueries
Definition: PoolImpl.h:219
static void setLock(ResStatus &status_r, bool yesno_r)
Set lock and UserLockQuery bit according to yesno_r.
Definition: PoolImpl.h:45
std::vector< PoolItem > ItemContainerT
pure items
Definition: PoolTraits.h:71
IdType id() const
Expert backdoor.
Definition: IdString.h:103
size_type size() const
Definition: PoolImpl.h:155
const_iterator end() const
Definition: PoolImpl.h:161
DefaultIntegral< bool, true > _storeDirty
Definition: PoolImpl.h:472
PoolTraits::autoSoftLocks_iterator autoSoftLocks_iterator
Definition: PoolImpl.h:303
size_type knownRepositoriesSize() const
Forward list of Repositories that contribute ResObjects from sat::Pool.
Definition: PoolImpl.h:203
unsigned SolvableIdType
Id type to connect Solvable and sat-solvable.
Definition: PoolMember.h:98
static const ResKind srcpackage
Definition: ResKind.h:47
PoolTraits::size_type size_type
Definition: PoolImpl.h:123
PoolTraits::Id2ItemT Id2ItemT
Definition: PoolImpl.h:125
SerialNumberWatcher _watcher
Watch sat pools serial number.
Definition: PoolImpl.h:470
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
Manipulator for ResStatus::UserLockQueryField.
Definition: PoolImpl.h:42
const ContainerT & store() const
Definition: PoolImpl.h:367
friend std::ostream & operator<<(std::ostream &str, const PoolImpl &obj)
filter_iterator< _Filter, typename _Container::const_iterator > make_filter_begin(_Filter f, const _Container &c)
Convenience to create filter_iterator from container::begin().
Definition: Iterator.h:99
std::list< PoolQuery > HardLockQueries
hard locks from etc/zypp/locks
Definition: PoolTraits.h:92
static int diffLock(const ResStatus &status_r)
Test whether the lock status differs from the remembered UserLockQuery bit.
Definition: PoolImpl.h:62
PoolTraits::const_iterator const_iterator
Definition: PoolImpl.h:124
ResPool::instance().proxy();.
Definition: ResPoolProxy.h:34
void setAutoSoftLocks(const AutoSoftLocks &newLocks_r)
Definition: PoolImpl.h:311
const SerialNumber & serial() const
Housekeeping data serial number.
Definition: Pool.cc:42
size_type solvablesSize() const
Number of solvables in Pool.
Definition: Pool.cc:84
DefaultIntegral< bool, true > _id2itemDirty
Definition: PoolImpl.h:474
const AutoSoftLocks & autoSoftLocks() const
Definition: PoolImpl.h:305
RepositoryIterator reposEnd() const
Iterator behind the last Repository.
Definition: Pool.cc:68
bool setSoftLock(TransactByValue causer_r)
Definition: ResStatus.h:461
size_type capacity() const
Internal array size for stats only.
Definition: Pool.cc:39
const_iterator begin() const
Definition: PoolImpl.h:158
bool empty() const
Definition: PoolImpl.h:151
PoolImpl()
Default ctor.
Definition: PoolImpl.cc:38
void invalidate() const
Definition: PoolImpl.h:460
static Pool instance()
Singleton ctor.
Definition: Pool.h:51
AutoSoftLocks _autoSoftLocks
Set of solvable idents that should be soft locked per default.
Definition: PoolImpl.h:481
void checkSerial() const
Definition: PoolImpl.h:453
std::string asString() const
Definition: IdStringType.h:106
Provides API related macros.
PoolTraits::ItemContainerT ContainerT
Definition: PoolImpl.h:122
Repository reposFind(const std::string &alias_r) const
Find a Repository named alias_r.
Definition: Pool.cc:123
PoolItem find(const sat::Solvable &slv_r) const
Return the corresponding PoolItem.
Definition: PoolImpl.h:170
RepositoryIterator reposBegin() const
Iterator to the first Repository.
Definition: Pool.cc:57
ResStatus & status() const
Returns the current status.
Definition: PoolItem.cc:241
static PoolItem makePoolItem(const sat::Solvable &solvable_r)
PoolItem generator for pool::PoolImpl.
Definition: PoolItem.cc:214
bool isUserLocked() const
Definition: ResStatus.h:255
bool setLock(bool toLock_r, TransactByValue causer_r)
Apply a lock (prevent transaction).
Definition: ResStatus.h:376
static const SolvAttr name
Definition: SolvAttr.h:52
shared_ptr< ResPoolProxy > _poolProxy
Definition: PoolImpl.h:477
filter_iterator< ByPoolItem, ItemContainerT::const_iterator > const_iterator
Definition: PoolTraits.h:74
Simple serial number provider.
Definition: SerialNumber.h:44
const sat::Pool satpool() const
convenience.
Definition: PoolImpl.h:139
PoolTraits::repository_iterator repository_iterator
Definition: PoolImpl.h:127
void getActiveSoftLocks(AutoSoftLocks &activeLocks_r)
Definition: PoolImpl.h:328
void setUserLockQueryMatch(bool match_r)
Definition: ResStatus.h:327
Global ResObject pool.
Definition: ResPool.h:48
PoolTraits::AutoSoftLocks AutoSoftLocks
Definition: PoolImpl.h:302
void RestoreState(const ResObject::Kind &kind_r)
repository_iterator knownRepositoriesBegin() const
Definition: PoolImpl.h:206
std::tr1::unordered_set< IdString > AutoSoftLocks
soft locks
Definition: PoolTraits.h:88
repository_iterator knownRepositoriesEnd() const
Definition: PoolImpl.h:209
size_type size() const
The number of sat::Solvables.
void prepare() const
Update housekeeping data if necessary (e.g.
Definition: Pool.cc:45
Global sat-pool.
Definition: Pool.h:42
HardLockQueries::const_iterator hardLockQueries_iterator
Definition: PoolTraits.h:93
Status bitfield.
Definition: ResStatus.h:53
PoolTraits::hardLockQueries_iterator hardLockQueries_iterator
Definition: PoolImpl.h:220
HardLockQueries _hardLockQueries
Set of queries that define hardlocks.
Definition: PoolImpl.h:483
filter_iterator< _Filter, typename _Container::const_iterator > make_filter_end(_Filter f, const _Container &c)
Convenience to create filter_iterator from container::end().
Definition: Iterator.h:115
const HardLockQueries & hardLockQueries() const
Definition: PoolImpl.h:222
Reference to a PoolItem connecting ResObject and ResStatus.
Definition: PoolItem.h:50
IdType id() const
Expert backdoor.
Definition: Solvable.h:296
Repository reposFind(const std::string &alias_r) const
Definition: PoolImpl.h:212
ContainerT _store
Definition: PoolImpl.h:471
const Id2ItemT & id2item() const
Definition: PoolImpl.h:428
Helper class to collect (not only) PoolQuery results.
void setHardLockQueries(const HardLockQueries &newLocks_r)
Definition: PoolImpl.h:244
ResPoolProxy proxy(ResPool self) const
Definition: PoolImpl.h:191
bool isKind(const ResKind &kind_r) const
Test whether a Solvable is of a certain ResKind.
Definition: Solvable.cc:337
bool solvablesEmpty() const
Whether Pool contains solvables.
Definition: Pool.cc:71
static const ResKind product
Definition: ResKind.h:46
Pool internal filter skiping invalid/unwanted PoolItems.
Definition: PoolTraits.h:40
Resolvable kinds.
Definition: ResKind.h:35
std::tr1::unordered_multimap< sat::detail::IdType, PoolItem > Id2ItemT
ident index
Definition: PoolTraits.h:79
const SerialNumber & serial() const
Housekeeping data serial number.
Definition: PoolImpl.h:143
bool isUserLockQueryMatch() const
Definition: ResStatus.h:324
static void reapplyLock(ResStatus &status_r, bool yesno_r)
Update lock and UserLockQuery bit IFF the item gained the bit.
Definition: PoolImpl.h:52
bool remember(unsigned serial_r) const
Return isDirty, storing serial_r as new value.
Definition: SerialNumber.h:160
AutoSoftLocks::const_iterator autoSoftLocks_iterator
Definition: PoolTraits.h:89
void reapplyHardLocks() const
Definition: PoolImpl.h:225
bool getHardLockQueries(HardLockQueries &activeLocks_r)
Definition: PoolImpl.h:261