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