From 71d3d399d7de75a96b2911677b74ce8b59579ee9 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 4 Feb 2025 18:22:35 +0100 Subject: Introduce pkgDepCache::Transaction for transactional depcache updates --- apt-pkg/depcache.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'apt-pkg/depcache.cc') 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 + 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 PkgState{copyArray(cache.PkgState, cache.GetCache().Head().PackageCount)}; + std::unique_ptr 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(); +} + /*}}}*/ -- cgit v1.2.3-70-g09d2