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