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 Pathname & rootDir_r,
00053 const PackageProvider & packageProvider_r )
00054 : CommitPackageCache::Impl( packageProvider_r )
00055 , _rootDir( rootDir_r )
00056 {}
00057
00059
00060
00061
00062
00063 bool CommitPackageCacheReadAhead::onInteractiveMedia( const PoolItem & pi ) const
00064 {
00065 if ( pi->mediaNr() == 0 )
00066 return false;
00067 if ( pi->repoInfo().baseUrlsEmpty() )
00068 return false;
00069 std::string scheme( pi->repoInfo().baseUrlsBegin()->getScheme() );
00070 return ( scheme == "dvd" || scheme == "cd" );
00071 }
00072
00074
00075
00076
00077
00078 void CommitPackageCacheReadAhead::cacheLastInteractive( const PoolItem & citem_r )
00079 {
00080
00081 try
00082 {
00083 doCacheLastInteractive( citem_r );
00084 }
00085 catch ( const Exception & excpt_r )
00086 {
00087 ZYPP_CAUGHT( excpt_r );
00088 WAR << "Failed to cache " << _lastInteractive << endl;
00089 }
00090 }
00091
00093
00094
00095
00096
00097 void CommitPackageCacheReadAhead::doCacheLastInteractive( const PoolItem & citem_r )
00098 {
00099 CacheMap addToCache;
00100 ByteCount addSize;
00101
00102
00103
00104 for_( it,_commitList.begin(), _commitList.end() )
00105 {
00106 PoolItem pi( *it );
00107 if ( IMediaKey( pi ) == _lastInteractive
00108 && isKind<Package>(pi.resolvable())
00109 && pi.status().isToBeInstalled() )
00110 {
00111 if ( _cacheMap.find( pi ) == _cacheMap.end() )
00112 {
00113 addToCache[pi];
00114 addSize += pi->downloadSize();
00115 }
00116 }
00117 }
00118
00119 if ( addToCache.empty() )
00120 return;
00121 MIL << "could cache " << _lastInteractive << ": " << addToCache.size() << " items: " << addSize << endl;
00122
00123
00124
00125
00126 if ( ! _cacheDir )
00127 {
00128 _cacheDir.reset( new filesystem::TmpDir( _rootDir, "commitCache." ) );
00129 PathInfo pi( _cacheDir->path() );
00130 if ( ! pi.isDir() )
00131 {
00132 ERR << "Can not initialize cache dir " << pi << endl;
00133 return;
00134 }
00135 }
00136
00137
00138
00139 ByteCount df( filesystem::df( _cacheDir->path() ) );
00140 MIL << "available disk space in " << _cacheDir->path() << ": " << df << endl;
00141
00142 if ( df / 10 < addSize )
00143 {
00144 WAR << "cache would require more than 10% of the available " << df << " disk space " << endl;
00145 WAR << "not caching " << _lastInteractive << endl;
00146 return;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 for ( CacheMap::iterator it = addToCache.begin(); it != addToCache.end(); ++it )
00156 {
00157
00158 ManagedFile fromSource( sourceProvidePackage( it->first ) );
00159
00160
00161 std::string destName( str::form( "S%p_%u_%s",
00162 it->first->repository().id(),
00163 it->first->mediaNr(),
00164 fromSource.value().basename().c_str() ) );
00165
00166 ManagedFile fileInCache( _cacheDir->path() / destName,
00167 filesystem::unlink );
00168
00169 if ( filesystem::copy( fromSource.value(), fileInCache ) != 0 )
00170 {
00171
00172 ERR << "Copy to cache failed on " << fromSource.value() << endl;
00173 ZYPP_THROW( Exception("Copy to cache failed.") );
00174 }
00175
00176
00177 it->second = fileInCache;
00178 }
00179
00180
00181
00182 _cacheMap.insert( addToCache.begin(), addToCache.end() );
00183 return;
00184 }
00185
00187
00188
00189
00190
00191 ManagedFile CommitPackageCacheReadAhead::get( const PoolItem & citem_r )
00192 {
00193
00194 if ( ! onInteractiveMedia( citem_r ) )
00195 {
00196 return sourceProvidePackage( citem_r );
00197 }
00198
00199
00200 CacheMap::iterator it = _cacheMap.find( citem_r );
00201 if ( it != _cacheMap.end() )
00202 {
00203
00204
00205
00206 ManagedFile cacheHit( it->second );
00207 _cacheMap.erase( it );
00208
00209
00210 PathInfo pi( cacheHit.value() );
00211 if ( pi.isFile() )
00212 {
00213 MIL << "Cache package provide " << cacheHit << endl;
00214 return cacheHit;
00215 }
00216
00217 WAR << "Cached file vanished: " << pi << endl;
00218 }
00219
00220
00221
00222
00223
00224 IMediaKey current( citem_r );
00225 if ( current != _lastInteractive )
00226 {
00227 if ( _lastInteractive != IMediaKey() )
00228 {
00229 cacheLastInteractive( citem_r );
00230 }
00231
00232 DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive
00233 << " to " << current << endl;
00234 _lastInteractive = current;
00235 }
00236
00237
00238 return sourceProvidePackage( citem_r );
00239 }
00240
00241
00243 }
00246 }