Simplify commit package cache.
authorMichael Andres <ma@suse.de>
Fri, 18 Oct 2013 09:08:05 +0000 (11:08 +0200)
committerMichael Andres <ma@suse.de>
Fri, 24 Jan 2014 07:24:32 +0000 (08:24 +0100)
zypp/target/CommitPackageCache.h
zypp/target/CommitPackageCacheImpl.h
zypp/target/CommitPackageCacheReadAhead.cc
zypp/target/CommitPackageCacheReadAhead.h
zypp/target/TargetImpl.cc

index c1c57972df9d3538cb0b54ba1eee5789ac1235dd..426f7452c3f522b7ee7863e82ba48a018ad87a7a 100644 (file)
@@ -39,7 +39,7 @@ namespace zypp
       friend std::ostream & operator<<( std::ostream & str, const CommitPackageCache & obj );
 
     public:
-      typedef function<ManagedFile( const PoolItem & pi )> PackageProvider;
+      typedef function<ManagedFile( const PoolItem & pi, bool fromCache_r )> PackageProvider;
 
     public:
       /** Ctor */
@@ -59,6 +59,9 @@ namespace zypp
 
       /** Provide a package. */
       ManagedFile get( const PoolItem & citem_r );
+      /** \overload */
+      ManagedFile get( sat::Solvable citem_r )
+      { return get( PoolItem(citem_r) ); }
 
     public:
       /** Implementation. */
index 41f8c1eb8aec1e2b72e6754a6842d8cae63463bc..3718e8b238d5bd6dfd583a3b23caebecfebc80f8 100644 (file)
@@ -61,6 +61,9 @@ namespace zypp
       void setCommitList( std::vector<sat::Solvable> commitList_r )
       { _commitList = commitList_r; }
 
+      const std::vector<sat::Solvable> & commitList() const
+      { return _commitList; }
+
     protected:
       /** Let the Source provide the package. */
       virtual ManagedFile sourceProvidePackage( const PoolItem & pi ) const
@@ -70,7 +73,7 @@ namespace zypp
             ZYPP_THROW( Exception("No package provider configured.") );
           }
 
-        ManagedFile ret( _packageProvider( pi ) );
+        ManagedFile ret( _packageProvider( pi, /*cached only*/false ) );
         if ( ret.value().empty() )
           {
             ZYPP_THROW( Exception("Package provider failed.") );
@@ -79,10 +82,19 @@ namespace zypp
         return ret;
       }
 
-    protected:
-      std::vector<sat::Solvable> _commitList;
+      /** Let the Source provide an already cached package. */
+      virtual ManagedFile sourceProvideCachedPackage( const PoolItem & pi ) const
+      {
+        if ( ! _packageProvider )
+          {
+            ZYPP_THROW( Exception("No package provider configured.") );
+          }
+
+        return _packageProvider( pi, /*cached only*/true );
+      }
 
     private:
+      std::vector<sat::Solvable> _commitList;
       PackageProvider _packageProvider;
     };
     ///////////////////////////////////////////////////////////////////
index e55c082e598e54df49c2b257531342ce74670e7a..d9c5c922a39a349432c906f36aedd12299df0c64 100644 (file)
@@ -15,6 +15,7 @@
 #include "zypp/base/Exception.h"
 #include "zypp/PathInfo.h"
 #include "zypp/RepoInfo.h"
+#include "zypp/Package.h"
 #include "zypp/target/CommitPackageCacheReadAhead.h"
 
 using std::endl;
@@ -49,10 +50,10 @@ namespace zypp
     // METHOD NAME : CommitPackageCacheReadAhead::CommitPackageCacheReadAhead
     // METHOD TYPE : Ctor
     //
-    CommitPackageCacheReadAhead::CommitPackageCacheReadAhead( const Pathname &        rootDir_r,
+    CommitPackageCacheReadAhead::CommitPackageCacheReadAhead( const Pathname &        /*rootDir_r*/,
                                                               const PackageProvider & packageProvider_r )
     : CommitPackageCache::Impl( packageProvider_r )
-    , _rootDir( rootDir_r )
+    //, _rootDir( rootDir_r )
     {}
 
     ///////////////////////////////////////////////////////////////////
@@ -96,91 +97,40 @@ namespace zypp
     //
     void CommitPackageCacheReadAhead::doCacheLastInteractive( const PoolItem & citem_r )
     {
-      CacheMap  addToCache;
-      ByteCount addSize;
+      unsigned  addToCache = 0;
+      bool      sawCitem = false;
 
       // Collect all remaining packages to install from
       // _lastInteractive media. (just the PoolItem data)
-      for_( it,_commitList.begin(), _commitList.end() )
-        {
-         PoolItem pi( *it );
-          if ( IMediaKey( pi ) == _lastInteractive
-               && isKind<Package>(pi.resolvable())
-               && pi.status().isToBeInstalled() )
-            {
-              if ( _cacheMap.find( pi ) == _cacheMap.end() )
-                {
-                  addToCache[pi];
-                  addSize += pi->downloadSize();
-                }
-            }
-        }
-
-      if ( addToCache.empty() )
-        return;
-      MIL << "could cache " << _lastInteractive << ": " << addToCache.size() << " items: " <<  addSize << endl;
-
-      // Check whether we can afford caching the items. We cache them all or
-      // nothing. It does not make sense to cache only some packages, if a
-      // CD change can't be avoided.
-      if ( ! _cacheDir )
-        {
-          _cacheDir.reset( new filesystem::TmpDir( _rootDir, "commitCache." ) );
-          PathInfo pi( _cacheDir->path() );
-          if ( ! pi.isDir() )
-            {
-              ERR << "Can not initialize cache dir " << pi << endl;
-              return;
-            }
-        }
-
-      // In case someone removes cacheDir behind our back, df will be
-      // -1, so we won't cache.
-      ByteCount df( filesystem::df( _cacheDir->path() ) );
-      MIL << "available disk space in " << _cacheDir->path() << ": " << df << endl;
-
-      if ( df / 10 < addSize )
-        {
-          WAR << "cache would require more than 10% of the available " << df << " disk space " << endl;
-          WAR << "not caching " << _lastInteractive << endl;
-          return;
-        }
-
-      // Get all files to cache from the Source and copy them to
-      // the cache.
-      // NOTE: All files copied to the cache directory are stored in addToCache,
-      // which is a local variable. If we throw on error, addToCache will be
-      // deleted and all the ManagedFiles stored so far will delete themself.
-      // THIS IS EXACTLY WHAT WE WANT.
-      for ( CacheMap::iterator it = addToCache.begin(); it != addToCache.end(); ++it )
-        {
-          // let the source provide the file
-          ManagedFile fromSource( sourceProvidePackage( it->first ) );
-
-          // copy it to the cachedir
-          std::string destName( str::form( "S%p_%u_%s",
-                                           it->first->repository().id(),
-                                           it->first->mediaNr(),
-                                           fromSource.value().basename().c_str() ) );
-
-          ManagedFile fileInCache( _cacheDir->path() / destName,
-                                   filesystem::unlink );
-
-          if ( filesystem::copy( fromSource.value(), fileInCache ) != 0 )
-            {
-              // copy to cache failed.
-              ERR << "Copy to cache failed on " << fromSource.value() << endl;
-              ZYPP_THROW( Exception("Copy to cache failed.") );
-            }
-
-          // remember the cached file.
-          it->second = fileInCache;
-        }
-
-      // Here: All files are sucessfully copied to the cache.
-      // Update the real cache map.
-      _cacheMap.insert( addToCache.begin(), addToCache.end() );
-      return;
+      for_( it, commitList().begin(), commitList().end() )
+      {
+       PoolItem pi( *it );
+       if ( ! sawCitem )
+       {
+         if ( pi == citem_r )
+           sawCitem = true;
+         continue;
+       }
+       if ( IMediaKey( pi ) == _lastInteractive
+         && pi.status().isToBeInstalled()
+         && isKind<Package>(pi.resolvable()) )
+       {
+         if ( ! pi->asKind<Package>()->isCached() )
+         {
+           ManagedFile fromSource( sourceProvidePackage( pi ) );
+           if ( fromSource->empty() )
+           {
+             ERR << "Copy to cache failed on " << fromSource << endl;
+             ZYPP_THROW( Exception("Copy to cache failed.") );
+           }
+           fromSource.resetDispose(); // keep the package file in the cache
+           ++addToCache;
+         }
+       }
+      }
+
+      if ( addToCache )
+       MIL << "Cached " << _lastInteractive << ": " << addToCache << " items." << endl;
     }
 
     ///////////////////////////////////////////////////////////////////
@@ -192,47 +142,26 @@ namespace zypp
     {
       // Non CD/DVD media provide their packages without cache.
       if ( ! onInteractiveMedia( citem_r ) )
-        {
-          return sourceProvidePackage( citem_r );
-        }
+      {
+       return sourceProvidePackage( citem_r );
+      }
 
       // Check whether it's cached.
-      CacheMap::iterator it = _cacheMap.find( citem_r );
-      if ( it != _cacheMap.end() )
-        {
-          // ManagedFile delivered to the application is removed
-          // from the cache. So if the application releases the
-          // file, it actually gets deleted from disk.
-          ManagedFile cacheHit( it->second );
-          _cacheMap.erase( it );
-
-          // safety check whether the file still exists
-          PathInfo pi( cacheHit.value() );
-          if ( pi.isFile() )
-            {
-              MIL << "Cache package provide " << cacheHit << endl;
-              return cacheHit;
-            }
-
-          WAR << "Cached file vanished: " << pi << endl;
-        }
+      ManagedFile ret( sourceProvideCachedPackage( citem_r ) );
+      if ( ! ret->empty() )
+       return ret;
 
-      // HERE: It's not in the cache.
-      // In case we have to change the media to provide the requested
-      // file, try to cache files from the current media, that are
-      // required later.
       IMediaKey current( citem_r );
       if ( current != _lastInteractive )
-        {
-          if ( _lastInteractive != IMediaKey() )
-            {
-              cacheLastInteractive( citem_r );
-            }
-
-          DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive
-          << " to " << current << endl;
-          _lastInteractive = current;
-        }
+      {
+       if ( _lastInteractive != IMediaKey() )
+       {
+         cacheLastInteractive( citem_r );
+       }
+
+       DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive << " to " << current << endl;
+       _lastInteractive = current;
+      }
 
       // Provide and return the file from media.
       return sourceProvidePackage( citem_r );
index 007951beb032ab53fa7d9e63b41af59133c93547..9ba707aae908bdbb52a69e76216d1cf1298f1b13 100644 (file)
@@ -82,10 +82,8 @@ namespace zypp
     /** */
     class CommitPackageCacheReadAhead : public CommitPackageCache::Impl
     {
-      typedef std::map<PoolItem,ManagedFile>     CacheMap;
-
     public:
-      CommitPackageCacheReadAhead( const Pathname &        rootDir_r,
+      CommitPackageCacheReadAhead( const Pathname &        /*rootDir_r*/,
                                    const PackageProvider & packageProvider_r );
 
     public:
@@ -109,12 +107,8 @@ namespace zypp
 
     private:
       DefaultIntegral<unsigned,0> _dbgChanges;
-
-      IMediaKey                      _lastInteractive;
-
-      Pathname                       _rootDir;
-      shared_ptr<filesystem::TmpDir> _cacheDir;
-      CacheMap                       _cacheMap;
+      IMediaKey                   _lastInteractive;
+      //Pathname                    _rootDir;
     };
     ///////////////////////////////////////////////////////////////////
 
index 38730df8e94ba8ad9bb87756e7cbf613eeb3ce1d..b7fcee13f3d404faf7f8fa3c4baf31dfbe4473a8 100644 (file)
@@ -770,30 +770,30 @@ namespace zypp
     */
     struct RepoProvidePackage
     {
-      ResPool _pool;
       repo::RepoMediaAccess &_access;
+      std::list<Repository> _repos;
+      repo::PackageProviderPolicy _packageProviderPolicy;
 
       RepoProvidePackage( repo::RepoMediaAccess &access, ResPool pool_r )
-        : _pool(pool_r), _access(access)
-      {}
-
-      ManagedFile operator()( const PoolItem & pi )
+      : _access(access), _repos( pool_r.knownRepositoriesBegin(), pool_r.knownRepositoriesEnd() )
       {
-        // Redirect PackageProvider queries for installed editions
-        // (in case of patch/delta rpm processing) to rpmDb.
-        repo::PackageProviderPolicy packageProviderPolicy;
-        packageProviderPolicy.queryInstalledCB( QueryInstalledEditionHelper() );
+       _packageProviderPolicy.queryInstalledCB( QueryInstalledEditionHelper() );
+      }
 
+      ManagedFile operator()( const PoolItem & pi, bool fromCache_r )
+      {
         Package::constPtr p = asKind<Package>(pi.resolvable());
-
-        // Build a repository list for repos
-        // contributing to the pool
-        std::list<Repository> repos( _pool.knownRepositoriesBegin(), _pool.knownRepositoriesEnd() );
-        repo::DeltaCandidates deltas(repos, p->name());
-        repo::PackageProvider pkgProvider( _access, p, deltas, packageProviderPolicy );
-
-        ManagedFile ret( pkgProvider.providePackage() );
-        return ret;
+       if ( fromCache_r )
+       {
+         repo::PackageProvider pkgProvider( _access, p, repo::DeltaCandidates(), _packageProviderPolicy );
+         return pkgProvider.providePackageFromCache();
+       }
+       else
+       {
+         repo::DeltaCandidates deltas( _repos, p->name() );
+         repo::PackageProvider pkgProvider( _access, p, deltas, _packageProviderPolicy );
+         return pkgProvider.providePackage();
+       }
       }
     };
     ///////////////////////////////////////////////////////////////////
@@ -1353,7 +1353,7 @@ namespace zypp
        // Prepare the package cache. Pass all items requiring download.
         repo::RepoMediaAccess access;
         RepoProvidePackage repoProvidePackage( access, pool_r );
-        CommitPackageCache packageCache( root() / "tmp", repoProvidePackage );
+        CommitPackageCache packageCache( root(), repoProvidePackage );
        packageCache.setCommitList( steps.begin(), steps.end() );
 
         bool miss = false;