libzypp  17.36.1
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 #include <utility>
17 
18 #include <zypp/base/Easy.h>
19 #include <zypp/base/LogTools.h>
20 #include <zypp/base/SerialNumber.h>
21 #include <zypp-core/Globals.h>
22 
23 #include <zypp/pool/PoolTraits.h>
24 #include <zypp/ResPoolProxy.h>
25 #include <zypp/PoolQueryResult.h>
26 
27 #include <zypp/sat/Pool.h>
28 #include <zypp/Product.h>
29 
30 using std::endl;
31 
33 namespace zypp
34 {
35 
36  namespace resstatus
37  {
44  {
46  static void setLock( ResStatus & status_r, bool yesno_r )
47  {
48  status_r.setLock( yesno_r, ResStatus::USER );
49  status_r.setUserLockQueryMatch( yesno_r );
50  }
51 
53  static void reapplyLock( ResStatus & status_r, bool yesno_r )
54  {
55  if ( yesno_r && ! status_r.isUserLockQueryMatch() )
56  {
57  status_r.setLock( yesno_r, ResStatus::USER );
58  status_r.setUserLockQueryMatch( yesno_r );
59  }
60  }
61 
63  static int diffLock( const ResStatus & status_r )
64  {
65  bool userLock( status_r.isUserLocked() );
66  if ( userLock == status_r.isUserLockQueryMatch() )
67  return 0;
68  return userLock ? 1 : -1;
69  }
70 
71  };
72  }
73 
74  namespace
75  {
76  inline PoolQuery makeTrivialQuery( IdString ident_r )
77  {
78  sat::Solvable::SplitIdent ident( ident_r );
79 
80  PoolQuery q;
81  q.addAttribute( sat::SolvAttr::name, ident.name().asString() );
82  q.addKind( ident.kind() );
83  q.setMatchExact();
84  q.setCaseSensitive(true);
85  return q;
86  }
87 
88  inline bool hardLockQueriesRemove( pool::PoolTraits::HardLockQueries & activeLocks_r, IdString ident_r )
89  {
90  unsigned s( activeLocks_r.size() );
91  activeLocks_r.remove( makeTrivialQuery( ident_r ) );
92  return( activeLocks_r.size() != s );
93  }
94 
95  inline bool hardLockQueriesAdd( pool::PoolTraits::HardLockQueries & activeLocks_r, IdString ident_r )
96  {
97  PoolQuery q( makeTrivialQuery( ident_r ) );
98  for_( it, activeLocks_r.begin(), activeLocks_r.end() )
99  {
100  if ( *it == q )
101  return false;
102  }
103  activeLocks_r.push_back( q );
104  return true;
105  }
106  }
107 
109  namespace solver {
110  namespace detail {
111  void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r ); // in solver/detail/SATResolver.cc
112  }
113  }
118  {
119  public:
122 
125  {
127 
128  if ( ! _pseudoItems.empty() )
129  {
130  for ( sat::Queue::size_type i = 0; i < _pseudoItems.size(); ++i )
131  {
134  if ( pi.status().validate() != vorig )
135  ret[pi] = vorig;
136  }
137  }
138  return ret;
139  }
140 
141  private:
143  {
145  switch ( _pseudoFlags[i] )
146  {
147  case 0: ret = ResStatus::BROKEN /*2*/; break;
148  case 1: ret = ResStatus::SATISFIED /*4*/; break;
149  case -1: ret = ResStatus::NONRELEVANT /*6*/; break;
150  }
151  return ret;
152  }
153 
154  private:
157  };
158 
160  namespace pool
161  {
162 
164  //
165  // CLASS NAME : PoolImpl
166  //
168  class PoolImpl
169  {
170  friend std::ostream & operator<<( std::ostream & str, const PoolImpl & obj );
171 
172  public:
178 
180 
182 
184 
185  public:
187  PoolImpl();
189  ~PoolImpl();
190 
191  public:
193  const sat::Pool satpool() const
194  { return sat::Pool::instance(); }
195 
197  const SerialNumber & serial() const
198  { return satpool().serial(); }
199 
201  //
203  public:
205  bool empty() const
206  { return satpool().solvablesEmpty(); }
207 
209  size_type size() const
210  { return satpool().solvablesSize(); }
211 
213  { return make_filter_begin( pool::ByPoolItem(), store() ); }
214 
216  { return make_filter_end( pool::ByPoolItem(), store() ); }
217 
218  public:
224  PoolItem find( const sat::Solvable & slv_r ) const
225  {
226  const ContainerT & mystore( store() );
227  return( slv_r.id() < mystore.size() ? mystore[slv_r.id()] : PoolItem() );
228  }
229 
231  //
233  public:
236  void SaveState( const ResKind & kind_r );
237 
238  void RestoreState( const ResKind & kind_r );
240 
242  //
244  public:
245  ResPoolProxy proxy( ResPool self ) const
246  {
247  checkSerial();
248  if ( !_poolProxy )
249  {
250  _poolProxy.reset( new ResPoolProxy( std::move(self), *this ) );
251  }
252  return *_poolProxy;
253  }
254 
262 
263  public:
266  { checkSerial(); return satpool().reposSize(); }
267 
269  { checkSerial(); return satpool().reposBegin(); }
270 
272  { checkSerial(); return satpool().reposEnd(); }
273 
274  Repository reposFind( const std::string & alias_r ) const
275  { checkSerial(); return satpool().reposFind( alias_r ); }
276 
278  //
280  public:
283 
285  { return _hardLockQueries; }
286 
287  void reapplyHardLocks() const
288  {
289  // It is assumed that reapplyHardLocks is called after new
290  // items were added to the pool, but the _hardLockQueries
291  // did not change since. Action is to be performed only on
292  // those items that gained the bit in the UserLockQueryField.
293  MIL << "Re-apply " << _hardLockQueries.size() << " HardLockQueries" << endl;
294  PoolQueryResult locked;
295  for_( it, _hardLockQueries.begin(), _hardLockQueries.end() )
296  {
297  locked += *it;
298  }
299  MIL << "HardLockQueries match " << locked.size() << " Solvables." << endl;
300  for_( it, begin(), end() )
301  {
302  // NOTE bsc#1225267: While reapplyLock sets but never unsets a lock,
303  // we don't need to care about buddies like in setHardLockQueries.
304  resstatus::UserLockQueryManip::reapplyLock( it->status(), locked.contains( *it ) );
305  }
306  }
307 
308  void setHardLockQueries( const HardLockQueries & newLocks_r )
309  {
310  MIL << "Apply " << newLocks_r.size() << " HardLockQueries" << endl;
311  _hardLockQueries = newLocks_r;
312  // now adjust the pool status
313  PoolQueryResult locked;
314  for_( it, _hardLockQueries.begin(), _hardLockQueries.end() )
315  {
316  locked += *it;
317  }
318  MIL << "HardLockQueries match " << locked.size() << " Solvables." << endl;
319  for_( it, begin(), end() )
320  {
321  // NOTE bsc#1225267: If the item has a buddy (a shared ResStatus), we lock if
322  // the item or the buddy is locked. Otherwise the item occurring later in the
323  // pool would dictate the status (unsetting a previously set lock).
324  bool yesno = locked.contains( *it ) || ( it->buddy() && locked.contains( PoolItem(it->buddy()) ) );
325  resstatus::UserLockQueryManip::setLock( it->status(), yesno );
326  }
327  }
328 
329  bool getHardLockQueries( HardLockQueries & activeLocks_r )
330  {
331  activeLocks_r = _hardLockQueries; // current queries
332  // Now diff to the pool collecting names only.
333  // Thus added and removed locks are not necessarily
334  // disjoint. Added locks win.
335  typedef std::unordered_set<IdString> IdentSet;
336  IdentSet addedLocks;
337  IdentSet removedLocks;
338  for_( it, begin(), end() )
339  {
340  switch ( resstatus::UserLockQueryManip::diffLock( it->status() ) )
341  {
342  case 0: // unchanged
343  break;
344  case 1:
345  addedLocks.insert( it->satSolvable().ident() );
346  break;
347  case -1:
348  removedLocks.insert( it->satSolvable().ident() );
349  break;
350  }
351  }
352  // now the bad part - adjust the queries
353  bool setChanged = false;
354  for_( it, removedLocks.begin(), removedLocks.end() )
355  {
356  if ( addedLocks.find( *it ) != addedLocks.end() )
357  continue; // Added locks win
358  if ( hardLockQueriesRemove( activeLocks_r, *it ) && ! setChanged )
359  setChanged = true;
360  }
361  for_( it, addedLocks.begin(), addedLocks.end() )
362  {
363  if ( hardLockQueriesAdd( activeLocks_r, *it ) && ! setChanged )
364  setChanged = true;
365  }
366  return setChanged;
367  }
368 
369  public:
370  const ContainerT & store() const
371  {
372  checkSerial();
373  if ( _storeDirty )
374  {
375  sat::Pool pool( satpool() );
376  bool addedItems = false;
377  bool reusedIDs = _watcherIDs.remember( pool.serialIDs() );
378  std::list<PoolItem> addedProducts;
379 
380  _store.resize( pool.capacity() );
381 
382  if ( pool.capacity() )
383  {
384  for ( sat::detail::SolvableIdType i = pool.capacity()-1; i != 0; --i )
385  {
386  sat::Solvable s( i );
387  PoolItem & pi( _store[i] );
388  if ( ! s && pi )
389  {
390  // the PoolItem got invalidated (e.g unloaded repo)
391  pi = PoolItem();
392  }
393  else if ( reusedIDs || (s && ! pi) )
394  {
395  // new PoolItem to add
396  pi = PoolItem::makePoolItem( s ); // the only way to create a new one!
397  // remember products for buddy processing (requires clean store)
398  if ( s.isKind( ResKind::product ) )
399  addedProducts.push_back( pi );
400  if ( !addedItems )
401  addedItems = true;
402  }
403  }
404  }
405  _storeDirty = false;
406 
407  // Now, as the pool is adjusted, ....
408 
409  // .... we check for product buddies.
410  if ( ! addedProducts.empty() )
411  {
412  for_( it, addedProducts.begin(), addedProducts.end() )
413  {
414  it->setBuddy( asKind<Product>(*it)->referencePackage() );
415  }
416  }
417 
418  // .... we must reapply those query based hard locks.
419  if ( addedItems )
420  {
422  }
423 
424  // Compute the initial status of Patches etc.
425  if ( !_establishedStates )
427  }
428  return _store;
429  }
430 
431  const Id2ItemT & id2item () const
432  {
433  checkSerial();
434  if ( _id2itemDirty )
435  {
436  store();
437  _id2item = Id2ItemT( size() );
438  for_( it, begin(), end() )
439  {
440  const sat::Solvable &s = (*it)->satSolvable();
441  sat::detail::IdType id = s.ident().id();
442  if ( s.isKind( ResKind::srcpackage ) )
443  id = -id;
444  _id2item.insert( std::make_pair( id, *it ) );
445  }
446  //INT << _id2item << endl;
447  _id2itemDirty = false;
448  }
449  return _id2item;
450  }
451 
453  //
455  private:
456  void checkSerial() const
457  {
458  if ( _watcher.remember( serial() ) )
459  invalidate();
460  satpool().prepare(); // always ajust dependencies.
461  }
462 
463  void invalidate() const
464  {
465  _storeDirty = true;
466  _id2itemDirty = true;
467  _id2item.clear();
468  _poolProxy.reset();
469  _establishedStates.reset();
470  }
471 
472  private:
481 
482  private:
483  mutable shared_ptr<ResPoolProxy> _poolProxy;
484  mutable shared_ptr<EstablishedStatesImpl> _establishedStates;
485 
486  private:
489  };
491 
493  } // namespace pool
496 } // namespace zypp
498 #endif // ZYPP_POOL_POOLIMPL_H
size_type knownRepositoriesSize() const
Forward list of Repositories that contribute ResObjects from sat::Pool.
Definition: PoolImpl.h:265
bool empty() const
Definition: Queue.cc:46
Repository reposFind(const std::string &alias_r) const
Definition: PoolImpl.h:274
#define MIL
Definition: Logger.h:100
Simple serial number watcher.
Definition: SerialNumber.h:122
A Solvable object within the sat Pool.
Definition: Solvable.h:53
A copy of the Pools initial ValidateValues of pseudo installed items.
Definition: ResPool.h:314
filter_iterator< ByPoolItem, ItemContainerT::const_iterator > const_iterator
Definition: PoolTraits.h:73
IdType id() const
Expert backdoor.
Definition: Solvable.h:444
PoolTraits::HardLockQueries HardLockQueries
Definition: PoolImpl.h:281
SerialNumberWatcher _watcherIDs
Watch sat pools Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also inval...
Definition: PoolImpl.h:476
void RestoreState(const ResKind &kind_r)
bool remember(unsigned serial_r) const
Return isDirty, storing serial_r as new value.
Definition: SerialNumber.h:160
shared_ptr< EstablishedStatesImpl > _establishedStates
Definition: PoolImpl.h:484
ResPool::EstablishedStates::ChangedPseudoInstalled changedPseudoInstalled() const
Return all pseudo installed items whose current state differs from their initial one.
Definition: PoolImpl.h:124
PoolItem find(const sat::Solvable &slv_r) const
Return the corresponding PoolItem.
Definition: PoolImpl.h:224
static void setLock(ResStatus &status_r, bool yesno_r)
Set lock and UserLockQuery bit according to yesno_r.
Definition: PoolImpl.h:46
sat::detail::SolvableIdType SolvableIdType
Definition: PoolImpl.h:181
PoolTraits::ItemContainerT ContainerT
Definition: PoolImpl.h:174
PoolTraits::hardLockQueries_iterator hardLockQueries_iterator
Definition: PoolImpl.h:282
IdType id() const
Expert backdoor.
Definition: IdString.h:133
DefaultIntegral< bool, true > _storeDirty
Definition: PoolImpl.h:478
repository_iterator knownRepositoriesBegin() const
Definition: PoolImpl.h:268
void SaveState(const ResKind &kind_r)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
RepositoryIterator reposEnd() const
Iterator behind the last Repository.
Definition: Pool.cc:87
sat::Pool::RepositoryIterator repository_iterator
list of known Repositories
Definition: PoolTraits.h:82
const HardLockQueries & hardLockQueries() const
Definition: PoolImpl.h:284
String related utilities and Regular expression matching.
bool isKind(const ResKind &kind_r) const
Test whether a Solvable is of a certain ResKind.
Definition: Solvable.cc:303
int IdType
Generic Id type.
Definition: PoolMember.h:104
static const ResKind srcpackage
Definition: ResKind.h:44
SerialNumberWatcher _watcher
Watch sat pools serial number.
Definition: PoolImpl.h:474
std::vector< PoolItem > ItemContainerT
pure items
Definition: PoolTraits.h:71
void reapplyHardLocks() const
Definition: PoolImpl.h:287
Manipulator for ResStatus::UserLockQueryField.
Definition: PoolImpl.h:43
Provides API related macros.
HardLockQueries::const_iterator hardLockQueries_iterator
Definition: PoolTraits.h:86
friend std::ostream & operator<<(std::ostream &str, const PoolImpl &obj)
size_type capacity() const
Internal array size for stats only.
Definition: Pool.cc:52
static int diffLock(const ResStatus &status_r)
Test whether the lock status differs from the remembered UserLockQuery bit.
Definition: PoolImpl.h:63
filter_iterator< TFilter, typename TContainer::const_iterator > make_filter_end(TFilter f, const TContainer &c)
Convenience to create filter_iterator from container::end().
Definition: Iterator.h:117
ResPool::instance().proxy();.
Definition: ResPoolProxy.h:35
size_type reposSize() const
Number of repos in Pool.
Definition: Pool.cc:73
DefaultIntegral< bool, true > _id2itemDirty
Definition: PoolImpl.h:480
ResPool::EstablishedStates establishedStates() const
True factory for ResPool::EstablishedStates.
Definition: PoolImpl.h:260
void prepare() const
Update housekeeping data if necessary (e.g.
Definition: Pool.cc:61
PoolImpl()
Default ctor.
Definition: PoolImpl.cc:44
void establish(sat::Queue &pseudoItems_r, sat::Queue &pseudoFlags_r)
ResPool helper to compute the initial status of Patches etc.
Definition: SATResolver.cc:188
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
size_type size() const
The number of sat::Solvables.
unsigned int size_type
Definition: Queue.h:38
std::string asString() const
Definition: IdStringType.h:108
const SerialNumber & serial() const
Housekeeping data serial number.
Definition: PoolImpl.h:197
bool isUserLockQueryMatch() const
Definition: ResStatus.h:345
const sat::Pool satpool() const
convenience.
Definition: PoolImpl.h:193
PoolTraits::size_type size_type
Definition: PoolImpl.h:175
std::unordered_multimap< sat::detail::IdType, PoolItem > Id2ItemT
ident index
Definition: PoolTraits.h:77
const SerialNumber & serial() const
Housekeeping data serial number.
Definition: Pool.cc:55
static PoolItem makePoolItem(const sat::Solvable &solvable_r)
PoolItem generator for pool::PoolImpl.
Definition: PoolItem.cc:200
bool setLock(bool toLock_r, TransactByValue causer_r)
Apply a lock (prevent transaction).
Definition: ResStatus.h:393
static const SolvAttr name
Definition: SolvAttr.h:52
shared_ptr< ResPoolProxy > _poolProxy
Definition: PoolImpl.h:483
size_type solvablesSize() const
Number of solvables in Pool.
Definition: Pool.cc:103
bool empty() const
Definition: PoolImpl.h:205
RepositoryIterator reposBegin() const
Iterator to the first Repository.
Definition: Pool.cc:76
bool solvablesEmpty() const
Whether Pool contains solvables.
Definition: Pool.cc:90
std::map< PoolItem, ResStatus::ValidateValue > ChangedPseudoInstalled
Map holding pseudo installed items where current and established status differ.
Definition: ResPool.h:319
size_type size() const
Definition: Queue.cc:49
Simple serial number provider.
Definition: SerialNumber.h:44
repository_iterator knownRepositoriesEnd() const
Definition: PoolImpl.h:271
void setUserLockQueryMatch(bool match_r)
Definition: ResStatus.h:341
bool contains(sat::Solvable result_r) const
Test whether some item is in the result set.
Libsolv Id queue wrapper.
Definition: Queue.h:35
Global ResObject pool.
Definition: ResPool.h:61
Repository reposFind(const std::string &alias_r) const
Find a Repository named alias_r.
Definition: Pool.cc:163
ResStatus::ValidateValue validateValue(sat::Queue::size_type i) const
Definition: PoolImpl.h:142
const_iterator begin() const
Definition: PoolImpl.h:212
ItemContainerT::size_type size_type
Definition: PoolTraits.h:74
std::list< PoolQuery > HardLockQueries
hard locks from etc/zypp/locks
Definition: PoolTraits.h:85
Store initial establish status of pseudo installed items.
Definition: PoolImpl.h:117
const ContainerT & store() const
Definition: PoolImpl.h:370
void checkSerial() const
Definition: PoolImpl.h:456
Global sat-pool.
Definition: Pool.h:46
Status bitfield.
Definition: ResStatus.h:54
HardLockQueries _hardLockQueries
Set of queries that define hardlocks.
Definition: PoolImpl.h:488
const SerialNumber & serialIDs() const
Serial number changing whenever resusePoolIDs==true was used.
Definition: Pool.cc:58
unsigned int SolvableIdType
Id type to connect Solvable and sat-solvable.
Definition: PoolMember.h:125
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:50
filter_iterator< TFilter, typename TContainer::const_iterator > make_filter_begin(TFilter f, const TContainer &c)
Convenience to create filter_iterator from container::begin().
Definition: Iterator.h:101
bool isUserLocked() const
Definition: ResStatus.h:273
ContainerT _store
Definition: PoolImpl.h:477
const Id2ItemT & id2item() const
Definition: PoolImpl.h:431
Helper class to collect (not only) PoolQuery results.
void setHardLockQueries(const HardLockQueries &newLocks_r)
Definition: PoolImpl.h:308
static const ResKind product
Definition: ResKind.h:43
Pool internal filter skiping invalid/unwanted PoolItems.
Definition: PoolTraits.h:40
Resolvable kinds.
Definition: ResKind.h:32
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
const_iterator end() const
Definition: PoolImpl.h:215
zypp::IdString IdString
Definition: idstring.h:16
void invalidate() const
Definition: PoolImpl.h:463
size_type size() const
Definition: PoolImpl.h:209
ResPoolProxy proxy(ResPool self) const
Definition: PoolImpl.h:245
IdString ident() const
The identifier.
Definition: Solvable.cc:270
static void reapplyLock(ResStatus &status_r, bool yesno_r)
Update lock and UserLockQuery bit IFF the item gained the bit.
Definition: PoolImpl.h:53
PoolTraits::Id2ItemT Id2ItemT
Definition: PoolImpl.h:177
PoolTraits::const_iterator const_iterator
Definition: PoolImpl.h:176
bool getHardLockQueries(HardLockQueries &activeLocks_r)
Definition: PoolImpl.h:329