libzypp: zypp/ng/sat/pool.cc Source File

libzypp 17.38.11

pool.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9#include "pool.h"
10#include "stringpool.h"
11#include "preparedpool.h"
12
13#include <zypp-core/base/LogTools.h>
14#include <zypp-core/base/dtorreset.h>
15#include <zypp-core/ng/base/precondition.h>
16#include <zypp/ng/sat/capability.h>
17
18extern "C"
19{
20#include <solv/repo_helix.h>
21#include <solv/testcase.h>
22}
23
24
25#undef ZYPP_BASE_LOGGER_LOGGROUP
26#define ZYPP_BASE_LOGGER_LOGGROUP "zyppng::satpool"
27
28
29namespace zyppng::sat {
30
31 namespace env {
32 inline int LIBSOLV_DEBUGMASK() {
33 const char * envp = getenv("LIBSOLV_DEBUGMASK");
34 return envp ? zypp::str::strtonum<int>( envp ) : 0;
35 }
36 } // namespace env
37
38
39 namespace detail {
40 // Compile-time checks for satlib constants we redefine to avoid
41 // includes and defines.
42 static_assert( noId == STRID_NULL );
43 static_assert( emptyId == STRID_EMPTY );
44
45 static_assert( noSolvableId == ID_NULL );
46 static_assert( systemSolvableId == SYSTEMSOLVABLE );
47
48 static_assert( solvablePrereqMarker == SOLVABLE_PREREQMARKER );
49 static_assert( solvableFileMarker == SOLVABLE_FILEMARKER );
50
51 static_assert( Capability::CAP_AND == REL_AND );
52 static_assert( Capability::CAP_OR == REL_OR );
53 static_assert( Capability::CAP_COND == REL_COND );
54 static_assert( Capability::CAP_UNLESS == REL_UNLESS );
55 static_assert( Capability::CAP_ELSE == REL_ELSE );
56 static_assert( Capability::CAP_WITH == REL_WITH );
57 static_assert( Capability::CAP_WITHOUT == REL_WITHOUT );
58 static_assert( Capability::CAP_NAMESPACE == REL_NAMESPACE );
59 static_assert( Capability::CAP_ARCH == REL_ARCH );
60
61 static_assert( namespaceModalias == NAMESPACE_MODALIAS );
62 static_assert( namespaceLanguage == NAMESPACE_LANGUAGE );
63 static_assert( namespaceFilesystem == NAMESPACE_FILESYSTEM );
64
65
66 static void logSat( CPool *, void *data, int type, const char *logString )
67 {
68 if ( 0 == strncmp( logString, "job: drop orphaned", 18 ) )
69 return;
70 if ( 0 == strncmp( logString, "job: user installed", 19 ) )
71 return;
72 if ( 0 == strncmp( logString, "job: multiversion", 17 ) )
73 return;
74 if ( 0 == strncmp( logString, " - no rule created", 19 ) )
75 return;
76 if ( 0 == strncmp( logString, " next rules: 0 0", 19 ) )
77 return;
78
79 if ( type & (SOLV_FATAL|SOLV_ERROR) ) {
80 L_ERR("libsolv") << logString;
81 } else if ( type & SOLV_DEBUG_STATS ) {
82 L_DBG("libsolv") << logString;
83 } else {
84 L_MIL("libsolv") << logString;
85 }
86 }
87 }
88
89 Pool::Pool()
90 : _pool( StringPool::instance().getPool() )
91 {
92 ZYPP_PRECONDITION( _pool->appdata == nullptr, "Only one zyppng::sat::Pool instance per CPool is permitted" );
93 _pool->appdata = this;
94 // TODO add logging functions
95 }
96
97 Pool::~Pool()
98 {
99 clear();
100 _pool->appdata = nullptr;
101 }
102
103 detail::size_type Pool::capacity() const
104 { return _pool->nsolvables; }
105
106 PreparedPool Pool::prepare()
107 {
108 // Pass 1: let components probe external state.
109 // setDirty() is legal here — onInvalidate() fires synchronously,
110 // so all components see a consistent state before prepare starts.
111 _componentsSet.notifyCheckDirty( *this );
112
113#ifndef NDEBUG
114 zypp::DtorReset preparingReset( _preparing, false );
115 _preparing = true;
116#endif
117
118 // Pass 2: pre-index component work — only if data changed.
119 const bool serialDirty = _watcher.remember( _serial );
120 if ( serialDirty )
121 _componentsSet.notifyPrepare( *this );
122
123 // Pass 3: rebuild index if cleared (independent of serial — can be
124 // invalidated by onInvalidate(Dependency) without a data change).
125 const bool indexRebuilt = ( _pool->whatprovides == nullptr );
126 if ( indexRebuilt ) {
127 MIL << "pool_createwhatprovides..." << std::endl;
128 ::pool_addfileprovides( _pool );
129 ::pool_createwhatprovides( _pool );
130 }
131
132 // Early exit — nothing changed and index is valid.
133 if ( !serialDirty && !indexRebuilt )
134 return PreparedPool( *this );
135
136 // Pass 4: post-index component work — serial changed or index was rebuilt.
137 PreparedPool pp( *this );
138 _componentsSet.notifyPrepareWithIndex( pp );
139
140 return pp;
141 }
142
143 void Pool::clear()
144 {
145 _componentsSet.notifyReset( *this );
146 ::pool_freewhatprovides( _pool );
147 ::pool_freeallrepos( _pool, /*resusePoolIDs*/true );
148 _serialIDs.setDirty();
149 _serial.setDirty();
150 }
151
152 void Pool::setDirty( PoolInvalidation invalidation, std::initializer_list<std::string_view> reasons )
153 {
154#ifndef NDEBUG
155 ZYPP_PRECONDITION( !_preparing, "setDirty() called during prepare() — only legal in checkDirty()" );
156#endif
157 if ( reasons.size() ) {
158 bool first = true;
159 for ( std::string_view r : reasons ) {
160 if ( first )
161 MIL << r;
162 else
163 MIL << " " << r;
164 first = false;
165 }
166 MIL << std::endl;
167 }
168
169 // Notify components so they can clear their caches
170 _componentsSet.notifyInvalidate( *this, invalidation );
171
172 if ( invalidation == PoolInvalidation::Data )
173 _serial.setDirty ();
174
175 ::pool_freewhatprovides( _pool );
176 }
177
178 const std::string &Pool::systemRepoAlias()
179 {
180 static const std::string _val( "@System" );
181 return _val;
182 }
183
184 Repository Pool::reposFind( const std::string & alias_r ) const
185 {
186 for( const auto &repo : repos() )
187 {
188 if ( alias_r == repo.alias() )
189 return repo;
190 }
191 return Repository();
192 }
193
194 Repository Pool::reposInsert( const std::string & alias_r )
195 {
196 Repository res( reposFind( alias_r ) );
197 if ( ! res )
198 res = Repository( _createRepo( alias_r ) );
199 return res;
200 }
201
202 bool Pool::reposEmpty() const
203 { return _pool->urepos == 0; }
204
205 detail::size_type Pool::reposSize() const
206 { return _pool->urepos; }
207
208 Pool::RepositoryIterable Pool::repos() const
209 {
210 detail::RepositoryIterator start, end = detail::RepositoryIterator( _pool->repos + _pool->nrepos );
211 if ( _pool->urepos )
212 { // repos[0] == NULL
213 for( auto it = _pool->repos+1; it != _pool->repos+_pool->nrepos; it++ )
214 if ( *it ) {
215 start = detail::RepositoryIterator( it );
216 break;
217 }
218 }
219 return RepositoryIterable( start, end );
220 }
221
222 Repository Pool::findSystemRepo() const
223 { return Repository( _pool->installed ); }
224
225 Repository Pool::systemRepo()
226 {
227 if ( ! _pool->installed )
228 _createRepo( systemRepoAlias() );
229 return Repository( _pool->installed );
230 }
231
232 bool Pool::solvablesEmpty() const
233 {
234 // Do not return get()->nsolvables;
235 // nsolvables is the array size including
236 // invalid Solvables.
237 for( const auto &repo : repos() )
238 {
239 if ( ! repo.solvablesEmpty() )
240 return false;
241 }
242 return true;
243 }
244
245 detail::size_type Pool::solvablesSize() const
246 {
247 // Do not return get()->nsolvables;
248 // nsolvables is the array size including
249 // invalid Solvables.
250 detail::size_type ret = 0;
251 for( const auto &repo : repos() )
252 {
253 ret += repo.solvablesSize();
254 }
255 return ret;
256 }
257
258 Pool::SolvableIterable Pool::solvables() const
259 {
260 return Pool::SolvableIterable(
261 detail::SolvableIterator( getFirstId() ),
262 detail::SolvableIterator()
263 );
264 }
265
266 detail::CRepo *Pool::_createRepo(const std::string &name_r)
267 {
268 setDirty( PoolInvalidation::Data, { __FUNCTION__, name_r } );
269 detail::CRepo * ret = ::repo_create( _pool, name_r.c_str() );
270 if ( ret && name_r == systemRepoAlias() )
271 ::pool_set_installed( _pool, ret );
272 if ( ret )
273 _postRepoAdd( ret );
274 return ret;
275 }
276
277 void Pool::_deleteRepo(detail::CRepo *repo_r)
278 {
279 setDirty( PoolInvalidation::Data, { __FUNCTION__, repo_r->name } );
280
281 _componentsSet.notifyRepoRemoved( *this, repo_r );
282
283 ::repo_free( repo_r, /*resusePoolIDs*/false );
284 if ( !_pool->urepos )
285 {
286 _serialIDs.setDirty();
287 ::pool_freeallrepos( _pool, /*resusePoolIDs*/true );
288 }
289 }
290
291 int Pool::_addSolv(detail::CRepo *repo_r, FILE *file_r)
292 {
293 setDirty( PoolInvalidation::Data, { __FUNCTION__, repo_r->name } );
294 int ret = ::repo_add_solv( repo_r, file_r, 0 );
295 if ( ret == 0 )
296 _postRepoAdd( repo_r );
297 return ret;
298 }
299
300 int Pool::_addHelix(detail::CRepo *repo_r, FILE *file_r)
301 {
302 setDirty( PoolInvalidation::Data, { __FUNCTION__, repo_r->name } );
303 int ret = ::repo_add_helix( repo_r, file_r, 0 );
304 if ( ret == 0 )
305 _postRepoAdd( repo_r );
306 return ret;
307 }
308
309 int Pool::_addTesttags(detail::CRepo *repo_r, FILE *file_r)
310 {
311 setDirty( PoolInvalidation::Data, { __FUNCTION__, repo_r->name } );
312 int ret = ::testcase_add_testtags( repo_r, file_r, 0 );
313 if ( ret == 0 )
314 _postRepoAdd( repo_r );
315 return ret;
316 }
317
318 detail::SolvableIdType Pool::_addSolvables(detail::CRepo *repo_r, unsigned int count_r)
319 {
320 setDirty( PoolInvalidation::Data, { __FUNCTION__, repo_r->name } );
321 return ::repo_add_solvable_block( repo_r, count_r );
322 }
323
324 void Pool::_postRepoAdd( detail::CRepo * repo_r )
325 {
326 _componentsSet.notifyRepoAdded( *this, repo_r );
327 }
328
329} // namespace zyppng::sat
LogTools.h
L_ERR
#define L_ERR(GROUP)
Definition Logger.h:114
MIL
#define MIL
Definition Logger.h:103
L_MIL
#define L_MIL(GROUP)
Definition Logger.h:112
L_DBG
#define L_DBG(GROUP)
Definition Logger.h:111
zypp::Capability::CAP_OR
@ CAP_OR
or
Definition Capability.h:154
zypp::Capability::CAP_WITH
@ CAP_WITH
with
Definition Capability.h:160
zypp::Capability::CAP_WITHOUT
@ CAP_WITHOUT
without
Definition Capability.h:161
zypp::Capability::CAP_COND
@ CAP_COND
if
Definition Capability.h:156
zypp::Capability::CAP_ELSE
@ CAP_ELSE
else
Definition Capability.h:158
zypp::Capability::CAP_ARCH
@ CAP_ARCH
Used internally.
Definition Capability.h:164
zypp::Capability::CAP_UNLESS
@ CAP_UNLESS
unless
Definition Capability.h:157
zypp::Capability::CAP_NAMESPACE
@ CAP_NAMESPACE
Definition Capability.h:163
zypp::Capability::CAP_AND
@ CAP_AND
and
Definition Capability.h:153
zypp::DtorReset
Assign a vaiable a certain value when going out of scope.
Definition dtorreset.h:50
zypp::sat::Pool::reposSize
size_type reposSize() const
Number of repos in Pool.
Definition Pool.cc:73
zypp::sat::Pool::repos
Iterable< RepositoryIterator > repos() const
Iterate the repositories.
Definition Pool.h:95
zypp::sat::Pool::Pool
Pool()
Default ctor.
Definition Pool.h:286
zypp::sat::Pool::solvablesEmpty
bool solvablesEmpty() const
Whether Pool contains solvables.
Definition Pool.cc:90
zypp::sat::Pool::findSystemRepo
Repository findSystemRepo() const
Return the system repository if it is on the pool.
Definition Pool.cc:173
zypp::sat::Pool::capacity
size_type capacity() const
Internal array size for stats only.
Definition Pool.cc:52
zypp::sat::Pool::solvables
Iterable< SolvableIterator > solvables() const
Iterate the solvables.
Definition Pool.h:175
zypp::sat::Pool::reposFind
Repository reposFind(const std::string &alias_r) const
Find a Repository named alias_r.
Definition Pool.cc:163
zypp::sat::Pool::solvablesSize
size_type solvablesSize() const
Number of solvables in Pool.
Definition Pool.cc:103
zypp::sat::Pool::systemRepoAlias
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
Definition Pool.cc:46
zypp::sat::Pool::reposInsert
Repository reposInsert(const std::string &alias_r)
Return a Repository named alias_r.
Definition Pool.cc:143
zypp::sat::Pool::prepare
void prepare() const
Update housekeeping data if necessary (e.g.
Definition Pool.cc:61
zypp::sat::Pool::systemRepo
Repository systemRepo()
Return the system repository, create it if missing.
Definition Pool.cc:178
zypp::sat::Pool::reposEmpty
bool reposEmpty() const
Whether Pool contains repos.
Definition Pool.cc:70
zyppng::sat::Pool::~Pool
~Pool()
Dtor.
Definition pool.cc:97
zyppng::sat::Pool::_postRepoAdd
void _postRepoAdd(detail::CRepo *repo_r)
Helper postprocessing the repo after adding solv or helix files.
Definition pool.cc:324
zyppng::sat::Pool::_preparing
bool _preparing
True while prepare() is running — setDirty() is illegal in this window.
Definition pool.h:285
zyppng::sat::Pool::_createRepo
detail::CRepo * _createRepo(const std::string &name_r)
Creating a new repo named name_r.
Definition pool.cc:266
zyppng::sat::Pool::_deleteRepo
void _deleteRepo(detail::CRepo *repo_r)
Delete repo repo_r from pool.
Definition pool.cc:277
zyppng::sat::Pool::_serialIDs
SerialNumber _serialIDs
Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate its PoolIt...
Definition pool.h:278
zyppng::sat::Pool::RepositoryIterable
zypp::Iterable< detail::RepositoryIterator > RepositoryIterable
Definition pool.h:42
zyppng::sat::Pool::_addTesttags
int _addTesttags(detail::CRepo *repo_r, FILE *file_r)
Adding testtags file to a repo.
Definition pool.cc:309
zyppng::sat::Pool::SolvableIterable
zypp::Iterable< detail::SolvableIterator > SolvableIterable
Definition pool.h:43
zyppng::sat::Pool::_watcher
SerialNumberWatcher _watcher
Watch serial number.
Definition pool.h:280
zyppng::sat::Pool::clear
void clear()
Reset the pool by removing all repositories and solvables.
Definition pool.cc:143
zyppng::sat::Pool::_addHelix
int _addHelix(detail::CRepo *repo_r, FILE *file_r)
Adding helix file to a repo.
Definition pool.cc:300
zyppng::sat::Pool::_componentsSet
PoolComponentSet _componentsSet
Component set managing modular pool logic.
Definition pool.h:282
zyppng::sat::Pool::getFirstId
detail::SolvableIdType getFirstId() const
Get id of the first valid Solvable.
Definition pool.h:242
zyppng::sat::Pool::reposFind
Repository reposFind(const std::string &alias_r) const
Find a Repository named alias_r.
Definition pool.cc:184
zyppng::sat::Pool::_addSolv
int _addSolv(detail::CRepo *repo_r, FILE *file_r)
Adding solv file to a repo.
Definition pool.cc:291
zyppng::sat::Pool::setDirty
void setDirty(PoolInvalidation invalidation, std::initializer_list< std::string_view > reasons)
Invalidate everything.
Definition pool.cc:152
zyppng::sat::Pool::getPool
detail::CPool * getPool() const
Definition pool.h:217
zyppng::sat::Pool::_pool
detail::CPool * _pool
sat-pool.
Definition pool.h:274
zyppng::sat::Pool::Repository
friend class Repository
Definition pool.h:38
zyppng::sat::Pool::_serial
SerialNumber _serial
Serial number - changes with each Pool content change.
Definition pool.h:276
zyppng::sat::Pool::repos
RepositoryIterable repos() const
Iteratable to the repositories.
Definition pool.cc:208
zyppng::sat::Pool::systemRepoAlias
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
Definition pool.cc:178
zyppng::sat::Pool::_addSolvables
detail::SolvableIdType _addSolvables(detail::CRepo *repo_r, unsigned count_r)
Adding Solvables to a repo.
Definition pool.cc:318
zyppng::sat::PreparedPool
A move-only, non-owning view of a Pool that guarantees the whatprovides index is valid.
Definition preparedpool.h:51
zyppng::sat::StringPool
Singleton manager for the underlying libsolv string pool.
Definition stringpool.h:35
zyppng::sat::detail::RepositoryIterator
Definition repository.h:476
zyppng::sat::detail::SolvableIterator
Iterate over valid Solvables in the pool.
Definition solvable.h:415
dtorreset.h
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
zyppng::detail
Definition reporthelper.h:31
zyppng::repo
Definition downloader.cc:22
zyppng::sat::detail::namespaceLanguage
static const IdType namespaceLanguage(20)
zyppng::sat::detail::solvablePrereqMarker
static const IdType solvablePrereqMarker(15)
Internal ids satlib includes in dependencies.
zyppng::sat::detail::logSat
static void logSat(CPool *, void *data, int type, const char *logString)
Definition pool.cc:66
zyppng::sat::detail::solvableFileMarker
static const IdType solvableFileMarker(16)
zyppng::sat::detail::CPool
zypp::sat::detail::CPool CPool
Definition poolconstants.h:36
zyppng::sat::detail::emptyId
static const IdType emptyId(1)
zyppng::sat::detail::SolvableIdType
zypp::sat::detail::SolvableIdType SolvableIdType
Definition poolconstants.h:44
zyppng::sat::detail::namespaceModalias
static const IdType namespaceModalias(18)
zyppng::sat::detail::namespaceFilesystem
static const IdType namespaceFilesystem(21)
zyppng::sat::detail::noId
static const IdType noId(0)
zyppng::sat::detail::noSolvableId
static const SolvableIdType noSolvableId(0)
Id to denote Solvable::noSolvable.
zyppng::sat::detail::systemSolvableId
static const SolvableIdType systemSolvableId(1)
Id to denote the usually hidden Solvable::systemSolvable.
zyppng::sat::detail::CRepo
zypp::sat::detail::CRepo CRepo
Definition poolconstants.h:38
zyppng::sat::detail::size_type
SolvableIdType size_type
Definition poolconstants.h:59
zyppng::sat::env
Definition pool.cc:31
zyppng::sat::env::LIBSOLV_DEBUGMASK
int LIBSOLV_DEBUGMASK()
Definition pool.cc:32
zyppng::sat
This file contains private API, this might break at any time between releases.
Definition capabilities.h:22
zyppng::sat::PoolInvalidation
PoolInvalidation
Defines the scope of an invalidation request for the Pool.
Definition poolconstants.h:66
zyppng::sat::PoolInvalidation::Data
@ Data
Structural or data change (e.g., Rootfs, Arch, or Repo content).
Definition poolconstants.h:76
pool.h
precondition.h
Always-on precondition checking for NG code.
ZYPP_PRECONDITION
#define ZYPP_PRECONDITION(EXPR,...)
Always-on precondition check — fires in debug AND release builds.
Definition precondition.h:42
preparedpool.h
capability.h
repo_add_helix
int repo_add_helix(::Repo *repo, FILE *fp, int flags)
testcase_add_testtags
int testcase_add_testtags(Repo *repo, FILE *fp, int flags)
stringpool.h