CommitPackageCacheReadAhead.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Exception.h"
00016 #include "zypp/PathInfo.h"
00017 #include "zypp/RepoInfo.h"
00018 #include "zypp/target/CommitPackageCacheReadAhead.h"
00019
00020 using std::endl;
00021
00023 namespace zypp
00024 {
00025
00026 namespace target
00027 {
00028
00030
00031
00032
00034
00035 std::ostream & operator<<( std::ostream & str, const IMediaKey & obj )
00036 {
00037 return str << "[S" << obj._repo.id() << ":" << obj._mediaNr << "]"
00038 << " " << obj._repo.info().alias();
00039 }
00040
00042
00043
00044
00046
00048
00049
00050
00051
00052 CommitPackageCacheReadAhead::CommitPackageCacheReadAhead( const_iterator begin_r,
00053 const_iterator end_r,
00054 const Pathname & rootDir_r,
00055 const PackageProvider & packageProvider_r )
00056 : CommitPackageCache::Impl( packageProvider_r )
00057 , _commitListEnd( end_r )
00058 , _rootDir( rootDir_r )
00059 {}
00060
00062
00063
00064
00065
00066 bool CommitPackageCacheReadAhead::onInteractiveMedia( const PoolItem & pi ) const
00067 {
00068 if ( pi->mediaNr() == 0 )
00069 return false;
00070 if ( pi->repoInfo().baseUrlsEmpty() )
00071 return false;
00072 std::string scheme( pi->repoInfo().baseUrlsBegin()->getScheme() );
00073 return ( scheme == "dvd" || scheme == "cd" );
00074 }
00075
00077
00078
00079
00080
00081 void CommitPackageCacheReadAhead::cacheLastInteractive( const_iterator citem_r )
00082 {
00083
00084 try
00085 {
00086 doCacheLastInteractive( citem_r );
00087 }
00088 catch ( const Exception & excpt_r )
00089 {
00090 ZYPP_CAUGHT( excpt_r );
00091 WAR << "Failed to cache " << _lastInteractive << endl;
00092 }
00093 }
00094
00096
00097
00098
00099
00100 void CommitPackageCacheReadAhead::doCacheLastInteractive( const_iterator citem_r )
00101 {
00102 CacheMap addToCache;
00103 ByteCount addSize;
00104
00105
00106
00107 for ( const_iterator it = citem_r; it != _commitListEnd; ++it )
00108 {
00109 if ( IMediaKey( *it ) == _lastInteractive
00110 && isKind<Package>(it->resolvable())
00111 && it->status().isToBeInstalled() )
00112 {
00113 if ( _cacheMap.find( *it ) == _cacheMap.end() )
00114 {
00115 addToCache[*it];
00116 addSize += it->resolvable()->downloadSize();
00117 }
00118 }
00119 }
00120
00121 if ( addToCache.empty() )
00122 return;
00123 MIL << "could cache " << _lastInteractive << ": " << addToCache.size() << " items: " << addSize << endl;
00124
00125
00126
00127
00128 if ( ! _cacheDir )
00129 {
00130 _cacheDir.reset( new filesystem::TmpDir( _rootDir, "commitCache." ) );
00131 PathInfo pi( _cacheDir->path() );
00132 if ( ! pi.isDir() )
00133 {
00134 ERR << "Can not initialize cache dir " << pi << endl;
00135 return;
00136 }
00137 }
00138
00139
00140
00141 ByteCount df( filesystem::df( _cacheDir->path() ) );
00142 MIL << "available disk space in " << _cacheDir->path() << ": " << df << endl;
00143
00144 if ( df / 10 < addSize )
00145 {
00146 WAR << "cache would require more than 10% of the available " << df << " disk space " << endl;
00147 WAR << "not caching " << _lastInteractive << endl;
00148 return;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 for ( CacheMap::iterator it = addToCache.begin(); it != addToCache.end(); ++it )
00158 {
00159
00160 ManagedFile fromSource( sourceProvidePackage( it->first ) );
00161
00162
00163 std::string destName( str::form( "S%p_%u_%s",
00164 it->first->repository().id(),
00165 it->first->mediaNr(),
00166 fromSource.value().basename().c_str() ) );
00167
00168 ManagedFile fileInCache( _cacheDir->path() / destName,
00169 filesystem::unlink );
00170
00171 if ( filesystem::copy( fromSource.value(), fileInCache ) != 0 )
00172 {
00173
00174 ERR << "Copy to cache failed on " << fromSource.value() << endl;
00175 ZYPP_THROW( Exception("Copy to cache failed.") );
00176 }
00177
00178
00179 it->second = fileInCache;
00180 }
00181
00182
00183
00184 _cacheMap.insert( addToCache.begin(), addToCache.end() );
00185 return;
00186 }
00187
00189
00190
00191
00192
00193 ManagedFile CommitPackageCacheReadAhead::get( const_iterator citem_r )
00194 {
00195
00196 if ( ! onInteractiveMedia( *citem_r ) )
00197 {
00198 return sourceProvidePackage( *citem_r );
00199 }
00200
00201
00202 CacheMap::iterator it = _cacheMap.find( *citem_r );
00203 if ( it != _cacheMap.end() )
00204 {
00205
00206
00207
00208 ManagedFile cacheHit( it->second );
00209 _cacheMap.erase( it );
00210
00211
00212 PathInfo pi( cacheHit.value() );
00213 if ( pi.isFile() )
00214 {
00215 MIL << "Cache package provide " << cacheHit << endl;
00216 return cacheHit;
00217 }
00218
00219 WAR << "Cached file vanished: " << pi << endl;
00220 }
00221
00222
00223
00224
00225
00226 IMediaKey current( *citem_r );
00227 if ( current != _lastInteractive )
00228 {
00229 if ( _lastInteractive != IMediaKey() )
00230 {
00231 cacheLastInteractive( citem_r );
00232 }
00233
00234 DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive
00235 << " to " << current << endl;
00236 _lastInteractive = current;
00237 }
00238
00239
00240 return sourceProvidePackage( *citem_r );
00241 }
00242
00243
00245 }
00248 }