00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sstream>
00034
00035 using std::istringstream ;
00036
00037 #include "BESUncompressManager.h"
00038 #include "BESUncompressGZ.h"
00039 #include "BESUncompressBZ2.h"
00040 #include "BESUncompressZ.h"
00041 #include "BESCache.h"
00042 #include "BESContainerStorageException.h"
00043 #include "BESDebug.h"
00044 #include "TheBESKeys.h"
00045
00046 BESUncompressManager *BESUncompressManager::_instance = 0 ;
00047
00051 BESUncompressManager::BESUncompressManager()
00052 {
00053 add_method( "gz", BESUncompressGZ::uncompress ) ;
00054 add_method( "bz2", BESUncompressBZ2::uncompress ) ;
00055 add_method( "z", BESUncompressZ::uncompress ) ;
00056
00057 bool found = false ;
00058 string key = "BES.Uncompress.Retry" ;
00059 string val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00060 if( !found || val.empty() )
00061 {
00062 _retry = 2 ;
00063 }
00064 else
00065 {
00066 istringstream is( val ) ;
00067 is >> _retry ;
00068 }
00069
00070 key = "BES.Uncompress.NumTries" ;
00071 val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00072 if( !found || val.empty() )
00073 {
00074 _num_tries = 10 ;
00075 }
00076 else
00077 {
00078 istringstream is( val ) ;
00079 is >> _num_tries ;
00080 }
00081 }
00082
00092 bool
00093 BESUncompressManager::add_method( const string &name,
00094 p_bes_uncompress method )
00095 {
00096 BESUncompressManager::UCIter i ;
00097 i = _uncompress_list.find( name ) ;
00098 if( i == _uncompress_list.end() )
00099 {
00100 _uncompress_list[name] = method ;
00101 return true ;
00102 }
00103 return false ;
00104 }
00105
00114 bool
00115 BESUncompressManager::remove_method( const string &name )
00116 {
00117 BESUncompressManager::UIter i ;
00118 i = _uncompress_list.find( name ) ;
00119 if( i != _uncompress_list.end() )
00120 {
00121 _uncompress_list.erase( i ) ;
00122 return true ;
00123 }
00124 return false ;
00125 }
00126
00135 p_bes_uncompress
00136 BESUncompressManager::find_method( const string &name )
00137 {
00138 BESUncompressManager::UCIter i ;
00139 i = _uncompress_list.find( name ) ;
00140 if( i != _uncompress_list.end() )
00141 {
00142 return (*i).second ;
00143 }
00144 return 0 ;
00145 }
00146
00152 string
00153 BESUncompressManager::get_method_names()
00154 {
00155 string ret ;
00156 bool first_name = true ;
00157 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00158 for( ; i != _uncompress_list.end(); i++ )
00159 {
00160 if( !first_name )
00161 ret += ", " ;
00162 ret += (*i).first ;
00163 first_name = false ;
00164 }
00165 return ret ;
00166 }
00167
00197 string
00198 BESUncompressManager::uncompress( const string &src, BESCache &cache )
00199 {
00200 BESDEBUG( "bes", "BESUncompressManager::uncompress - src = " << src << endl )
00201 string::size_type dot = src.rfind( "." ) ;
00202 if( dot != string::npos )
00203 {
00204 string ext = src.substr( dot+1, src.length() - dot ) ;
00205
00206 for( int i = 0; i < ext.length(); i++ )
00207 {
00208 ext[i] = tolower( ext[i] ) ;
00209 }
00210
00211
00212
00213
00214 p_bes_uncompress p = find_method( ext ) ;
00215 if( p )
00216 {
00217
00218
00219
00220 if( cache.lock( _retry, _num_tries ) )
00221 {
00222 try
00223 {
00224
00225
00226
00227 BESDEBUG( "bes", "BESUncompressManager::uncompress - is cached? " \
00228 << src << endl )
00229 string target ;
00230 if( cache.is_cached( src, target ) )
00231 {
00232 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00233 << "is cached " << target << endl )
00234 cache.unlock() ;
00235 return target ;
00236 }
00237
00238
00239
00240
00241 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00242 << "purging cache" << endl )
00243 cache.purge() ;
00244
00245
00246 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00247 << "uncompress to " << target \
00248 << " using " << ext << " uncompression" \
00249 << endl )
00250
00251
00252 cache.unlock() ;
00253
00254
00255
00256
00257 return p( src, target ) ;
00258 }
00259 catch( BESException &e )
00260 {
00261
00262
00263 cache.unlock() ;
00264 throw e ;
00265 }
00266 catch( ... )
00267 {
00268
00269
00270 cache.unlock() ;
00271 string err = (string)"Problem working with the cache, "
00272 + "unknow error" ;
00273 throw BESContainerStorageException( err, __FILE__,__LINE__);
00274 }
00275 }
00276 else
00277 {
00278 string err = "Unable to lock the cache "
00279 + cache.cache_dir() ;
00280 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00281 }
00282 }
00283 else
00284 {
00285 BESDEBUG( "bes", "BESUncompressManager::uncompress - not compressed " \
00286 << endl )
00287 }
00288 }
00289 else
00290 {
00291 BESDEBUG( "bes", "BESUncompressmanager::uncompress - not file extension" \
00292 << endl )
00293 #if 0
00294
00295
00296 string err = "Unable to determine type of file from "
00297 + src ;
00298 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00299 #endif
00300 }
00301
00302 return src ;
00303 }
00304
00312 void
00313 BESUncompressManager::dump( ostream &strm ) const
00314 {
00315 strm << BESIndent::LMarg << "BESUncompressManager::dump - ("
00316 << (void *)this << ")" << endl ;
00317 BESIndent::Indent() ;
00318 if( _uncompress_list.size() )
00319 {
00320 strm << BESIndent::LMarg << "registered uncompression methods:" << endl;
00321 BESIndent::Indent() ;
00322 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00323 BESUncompressManager::UCIter ie = _uncompress_list.end() ;
00324 for( ; i != ie; i++ )
00325 {
00326 strm << BESIndent::LMarg << (*i).first << endl ;
00327 }
00328 BESIndent::UnIndent() ;
00329 }
00330 else
00331 {
00332 strm << BESIndent::LMarg << "registered uncompress methods: none" << endl ;
00333 }
00334 BESIndent::UnIndent() ;
00335 }
00336
00337 BESUncompressManager *
00338 BESUncompressManager::TheManager()
00339 {
00340 if( _instance == 0 )
00341 {
00342 _instance = new BESUncompressManager ;
00343 }
00344 return _instance ;
00345 }