diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2025-02-04 18:22:35 +0100 |
|---|---|---|
| committer | Julian Andres Klode <julian.klode@canonical.com> | 2025-03-09 00:12:27 +0100 |
| commit | 71d3d399d7de75a96b2911677b74ce8b59579ee9 (patch) | |
| tree | dc83390da8358ea165392034262f87c4a3750780 /apt-pkg/depcache.cc | |
| parent | 1e7f123ea59d6ae3af74725d4dab846f81d122e8 (diff) | |
Introduce pkgDepCache::Transaction for transactional depcache updates
Diffstat (limited to 'apt-pkg/depcache.cc')
| -rw-r--r-- | apt-pkg/depcache.cc | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 970b4c01d..ec34d010b 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -2650,3 +2650,74 @@ unsigned long long pkgDepCache::BootSize(bool initrdOnly) return std::accumulate(sizes, sizes + MAX_ARTEFACT, off_t{0}) * BootCount * 110 / 100; } /*}}}*/ +// pkgDepCache::Transaction /*{{{*/ +struct pkgDepCache::Transaction::Private +{ + template <typename T> + static T *copyArray(T *array, size_t count) + { + auto out = new T[count]; + memcpy(&out[0], &array[0], sizeof(T) * count); + return out; + } + // State information + pkgDepCache &cache; + Behavior behavior; + std::unique_ptr<StateCache[]> PkgState{copyArray(cache.PkgState, cache.GetCache().Head().PackageCount)}; + std::unique_ptr<unsigned char[]> DepState{copyArray(cache.DepState, cache.GetCache().Head().DependsCount)}; + signed long long iUsrSize{cache.iUsrSize}; + unsigned long long iDownloadSize{cache.iDownloadSize}; + unsigned long iInstCount{cache.iInstCount}; + unsigned long iDelCount{cache.iDelCount}; + unsigned long iKeepCount{cache.iKeepCount}; + unsigned long iBrokenCount{cache.iBrokenCount}; + unsigned long iPolicyBrokenCount{cache.iPolicyBrokenCount}; + unsigned long iBadCount{cache.iBadCount}; + + void rollback() + { + memcpy(&cache.PkgState[0], &PkgState[0], sizeof(PkgState[0]) * cache.GetCache().Head().PackageCount); + memcpy(&cache.DepState[0], &DepState[0], sizeof(DepState[0]) * cache.GetCache().Head().DependsCount); + + cache.iUsrSize = iUsrSize; + cache.iDownloadSize = iDownloadSize; + cache.iInstCount = iInstCount; + cache.iDelCount = iDelCount; + cache.iKeepCount = iKeepCount; + cache.iBrokenCount = iBrokenCount; + cache.iPolicyBrokenCount = iPolicyBrokenCount; + cache.iBadCount = iBadCount; + } +}; + +pkgDepCache::Transaction::Transaction(pkgDepCache &cache, Behavior behavior) : d(new Private{cache, behavior}) {} + +void pkgDepCache::Transaction::temporaryRollback() +{ + d->rollback(); +} + +void pkgDepCache::Transaction::commit() +{ + d.reset(); +} + +void pkgDepCache::Transaction::rollback() +{ + if (d == nullptr) + return; + + temporaryRollback(); + d.reset(); +} + +pkgDepCache::Transaction::~Transaction() +{ + if (not d) + return; + if (d->behavior == Behavior::ROLLBACK || (d->behavior == Behavior::AUTO && d->cache.iBrokenCount > d->iBrokenCount)) + rollback(); + else + commit(); +} + /*}}}*/ |
