Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / sat / detail / PoolImpl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/detail/PoolImpl.h
10  *
11 */
12 #ifndef ZYPP_SAT_DETAIL_POOLIMPL_H
13 #define ZYPP_SAT_DETAIL_POOLIMPL_H
14 extern "C"
15 {
16 #include <solv/pool.h>
17 #include <solv/repo.h>
18 #include <solv/solvable.h>
19 #include <solv/poolarch.h>
20 #include <solv/repo_solv.h>
21 }
22 #include <iosfwd>
23
24 #include "zypp/base/Hash.h"
25 #include "zypp/base/NonCopyable.h"
26 #include "zypp/base/SerialNumber.h"
27 #include "zypp/base/SetTracker.h"
28 #include "zypp/sat/detail/PoolMember.h"
29 #include "zypp/sat/Queue.h"
30 #include "zypp/RepoInfo.h"
31 #include "zypp/Locale.h"
32 #include "zypp/Capability.h"
33 #include "zypp/IdString.h"
34
35 ///////////////////////////////////////////////////////////////////
36 namespace zypp
37 { /////////////////////////////////////////////////////////////////
38   ///////////////////////////////////////////////////////////////////
39   namespace sat
40   { /////////////////////////////////////////////////////////////////
41     class SolvableSet;
42     ///////////////////////////////////////////////////////////////////
43     namespace detail
44     { /////////////////////////////////////////////////////////////////
45
46       ///////////////////////////////////////////////////////////////////
47       //
48       //        CLASS NAME : PoolImpl
49       //
50       /** */
51       class PoolImpl : private base::NonCopyable
52       {
53         public:
54           /** Default ctor */
55           PoolImpl();
56
57           /** Dtor */
58           ~PoolImpl();
59
60           /** Pointer style access forwarded to sat-pool. */
61           CPool * operator->()
62           { return _pool; }
63
64         public:
65           /** Serial number changing whenever the content changes. */
66           const SerialNumber & serial() const
67           { return _serial; }
68
69           /** Update housekeeping data (e.g. whatprovides).
70            * \todo actually requires a watcher.
71            */
72           void prepare() const;
73
74         private:
75           /** Invalidate housekeeping data (e.g. whatprovides) if the
76            *  pools content changed.
77            */
78           void setDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
79
80           /** Invalidate locale related housekeeping data.
81            */
82           void localeSetDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
83
84           /** Invalidate housekeeping data (e.g. whatprovides) if dependencies changed.
85            */
86           void depSetDirty( const char * a1 = 0, const char * a2 = 0, const char * a3 = 0 );
87
88           /** Callback to resolve namespace dependencies (language, modalias, filesystem, etc.). */
89           static detail::IdType nsCallback( CPool *, void * data, detail::IdType lhs, detail::IdType rhs );
90
91         public:
92           /** Reserved system repository alias \c @System. */
93           static const std::string & systemRepoAlias();
94
95           bool isSystemRepo( CRepo * repo_r ) const
96           { return repo_r && _pool->installed == repo_r; }
97
98           CRepo * systemRepo() const
99           { return _pool->installed; }
100
101           /** Get rootdir (for file conflicts check) */
102           Pathname rootDir() const
103           {
104             const char * rd = ::pool_get_rootdir( _pool );
105             return( rd ? rd : "/" );
106           }
107
108           /** Set rootdir (for file conflicts check) */
109           void rootDir( const Pathname & root_r )
110           {
111             if ( root_r.empty() || root_r == "/" )
112               ::pool_set_rootdir( _pool, nullptr );
113             else
114               ::pool_set_rootdir( _pool, root_r.c_str() );
115           }
116
117         public:
118           /** \name Actions invalidating housekeeping data.
119            *
120            * All methods expect valid arguments being passed.
121            */
122           //@{
123           /** Creating a new repo named \a name_r. */
124           CRepo * _createRepo( const std::string & name_r );
125
126           /** Delete repo \a repo_r from pool. */
127           void _deleteRepo( CRepo * repo_r );
128
129           /** Adding solv file to a repo.
130            * Except for \c isSystemRepo_r, solvables of incompatible architecture
131            * are filtered out.
132           */
133           int _addSolv( CRepo * repo_r, FILE * file_r );
134
135           /** Adding helix file to a repo.
136            * Except for \c isSystemRepo_r, solvables of incompatible architecture
137            * are filtered out.
138           */
139           int _addHelix( CRepo * repo_r, FILE * file_r );
140
141           /** Adding Solvables to a repo. */
142           detail::SolvableIdType _addSolvables( CRepo * repo_r, unsigned count_r );
143           //@}
144
145           /** Helper postprocessing the repo after adding solv or helix files. */
146           void _postRepoAdd( CRepo * repo_r );
147
148         public:
149           /** a \c valid \ref Solvable has a non NULL repo pointer. */
150           bool validSolvable( const CSolvable & slv_r ) const
151           { return slv_r.repo; }
152           /** \overload Check also for id_r being in range of _pool->solvables. */
153           bool validSolvable( SolvableIdType id_r ) const
154           { return id_r < unsigned(_pool->nsolvables) && validSolvable( _pool->solvables[id_r] ); }
155           /** \overload Check also for slv_r being in range of _pool->solvables. */
156           bool validSolvable( const CSolvable * slv_r ) const
157           { return _pool->solvables <= slv_r && slv_r <= _pool->solvables+_pool->nsolvables && validSolvable( *slv_r ); }
158
159         public:
160           CPool * getPool() const
161           { return _pool; }
162
163           /** \todo a quick check whether the repo was meanwhile deleted. */
164           CRepo * getRepo( RepoIdType id_r ) const
165           { return id_r; }
166
167           /** Return pointer to the sat-solvable or NULL if it is not valid.
168            * \see \ref validSolvable.
169            */
170           CSolvable * getSolvable( SolvableIdType id_r ) const
171           {
172             if ( validSolvable( id_r ) )
173               return &_pool->solvables[id_r];
174             return 0;
175           }
176
177         public:
178           /** Get id of the first valid \ref Solvable.
179            * This is the next valid after the system solvable.
180            */
181           SolvableIdType getFirstId()  const
182           { return getNextId( 1 ); }
183
184           /** Get id of the next valid \ref Solvable.
185            * This goes round robbin. At the end it returns \ref noSolvableId.
186            * Passing \ref noSolvableId it returns the 1st valid  \ref Solvable.
187            * \see \ref validSolvable.
188            */
189           SolvableIdType getNextId( SolvableIdType id_r ) const
190           {
191             for( ++id_r; id_r < unsigned(_pool->nsolvables); ++id_r )
192             {
193               if ( validSolvable( _pool->solvables[id_r] ) )
194                 return id_r;
195             }
196             return noSolvableId;
197           }
198
199         public:
200           /** */
201           const RepoInfo & repoInfo( RepoIdType id_r )
202           { return _repoinfos[id_r]; }
203           /** Also adjust repo priority and subpriority accordingly. */
204           void setRepoInfo( RepoIdType id_r, const RepoInfo & info_r );
205           /** */
206           void eraseRepoInfo( RepoIdType id_r )
207           { _repoinfos.erase( id_r ); }
208
209         public:
210           /** Returns the id stored at \c offset_r in the internal
211            * whatprovidesdata array.
212           */
213           const sat::detail::IdType whatProvidesData( unsigned offset_r )
214           { return _pool->whatprovidesdata[offset_r]; }
215
216           /** Returns offset into the internal whatprovidesdata array.
217            * Use \ref whatProvidesData to get the stored Id.
218           */
219           unsigned whatProvides( Capability cap_r )
220           { prepare(); return ::pool_whatprovides( _pool, cap_r.id() ); }
221
222         public:
223           /// \name Requested locales.
224           /// The requested LocaleSets managed in _requestedLocalesTracker
225           /// are unexpanded; i.e. they contain just the pure user selection.
226           /// The resolver however uses expanded sets ('de_DE' will also
227           /// include its fallback locales 'de', (en); here in the namespace:
228           /// callback and in the Resolver itself).
229           //@{
230           /** */
231           void setTextLocale( const Locale & locale_r );
232
233
234           /** Start tracking changes based on this \a locales_r.
235            * Usually called on TargetInit.
236            */
237           void initRequestedLocales( const LocaleSet & locales_r );
238
239           /** Added since last initRequestedLocales. */
240           const LocaleSet & getAddedRequestedLocales() const
241           { return _requestedLocalesTracker.added(); }
242
243           /** Removed since last initRequestedLocales. */
244           const LocaleSet & getRemovedRequestedLocales() const
245           { return _requestedLocalesTracker.removed(); }
246
247           /** Current set of requested Locales. */
248           const LocaleSet & getRequestedLocales() const
249           { return _requestedLocalesTracker.current(); }
250
251           bool isRequestedLocale( const Locale & locale_r ) const
252           { return _requestedLocalesTracker.contains( locale_r ); }
253
254           /** User change (tracked). */
255           void setRequestedLocales( const LocaleSet & locales_r );
256           /** User change (tracked). */
257           bool addRequestedLocale( const Locale & locale_r );
258           /** User change (tracked). */
259           bool eraseRequestedLocale( const Locale & locale_r );
260
261           /** All Locales occurring in any repo. */
262           const LocaleSet & getAvailableLocales() const;
263
264           bool isAvailableLocale( const Locale & locale_r ) const
265           {
266             const LocaleSet & avl( getAvailableLocales() );
267             LocaleSet::const_iterator it( avl.find( locale_r ) );
268             return it != avl.end();
269           }
270
271           typedef base::SetTracker<IdStringSet> TrackedLocaleIds;
272
273           /** Expanded _requestedLocalesTracker for solver.*/
274           const TrackedLocaleIds & trackedLocaleIds() const;
275           //@}
276
277         public:
278           /** \name Multiversion install. */
279           //@{
280           typedef SolvableSet MultiversionList;
281
282           const MultiversionList & multiversionList() const;
283
284           bool isMultiversion( const Solvable & solv_r ) const;
285
286           void multiversionSpecChanged();
287           //@}
288
289         public:
290           /** \name Installed on behalf of a user request hint. */
291           //@{
292           /** Get ident list of all autoinstalled solvables. */
293           StringQueue autoInstalled() const
294           { return _autoinstalled; }
295
296           /** Set ident list of all autoinstalled solvables. */
297           void setAutoInstalled( const StringQueue & autoInstalled_r )
298           { _autoinstalled = autoInstalled_r; }
299
300           bool isOnSystemByUser( IdString ident_r ) const
301           { return !_autoinstalled.contains( ident_r.id() ); }
302           //@}
303
304         public:
305           /** accessor for etc/sysconfig/storage reading file on demand */
306           const std::set<std::string> & requiredFilesystems() const;
307
308         private:
309           /** sat-pool. */
310           CPool * _pool;
311           /** Serial number. */
312           SerialNumber _serial;
313           /** Watch serial number. */
314           SerialNumberWatcher _watcher;
315           /** Additional \ref RepoInfo. */
316           std::map<RepoIdType,RepoInfo> _repoinfos;
317
318           /**  */
319           base::SetTracker<LocaleSet> _requestedLocalesTracker;
320           mutable scoped_ptr<TrackedLocaleIds> _trackedLocaleIdsPtr;
321
322           mutable scoped_ptr<LocaleSet> _availableLocalesPtr;
323
324           /**  */
325           void multiversionListInit() const;
326           mutable scoped_ptr<MultiversionList> _multiversionListPtr;
327
328           /**  */
329           sat::StringQueue _autoinstalled;
330
331           /** filesystems mentioned in /etc/sysconfig/storage */
332           mutable scoped_ptr<std::set<std::string> > _requiredFilesystemsPtr;
333       };
334       ///////////////////////////////////////////////////////////////////
335
336       /////////////////////////////////////////////////////////////////
337     } // namespace detail
338     ///////////////////////////////////////////////////////////////////
339     /////////////////////////////////////////////////////////////////
340   } // namespace sat
341   ///////////////////////////////////////////////////////////////////
342   /////////////////////////////////////////////////////////////////
343 } // namespace zypp
344 ///////////////////////////////////////////////////////////////////
345 #define POOL_SETDIRTY
346 #endif // ZYPP_SAT_DETAIL_POOLIMPL_H