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 "BESCache.h"
00041 #include "BESContainerStorageException.h"
00042 #include "BESDebug.h"
00043 #include "TheBESKeys.h"
00044 #include "config.h"
00045
00046 BESUncompressManager *BESUncompressManager::_instance = 0 ;
00047
00051 BESUncompressManager::BESUncompressManager()
00052 {
00053 add_method( "gz", BESUncompressGZ::uncompress ) ;
00054 #ifdef HAVE_BZLIB_H
00055 add_method( "bz2", BESUncompressBZ2::uncompress ) ;
00056 #endif
00057
00058 bool found = false ;
00059 string key = "BES.Uncompress.Retry" ;
00060 string val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00061 if( !found || val.empty() )
00062 {
00063 _retry = 2 ;
00064 }
00065 else
00066 {
00067 istringstream is( val ) ;
00068 is >> _retry ;
00069 }
00070
00071 key = "BES.Uncompress.NumTries" ;
00072 val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00073 if( !found || val.empty() )
00074 {
00075 _num_tries = 10 ;
00076 }
00077 else
00078 {
00079 istringstream is( val ) ;
00080 is >> _num_tries ;
00081 }
00082 }
00083
00093 bool
00094 BESUncompressManager::add_method( const string &name,
00095 p_bes_uncompress method )
00096 {
00097 BESUncompressManager::UCIter i ;
00098 i = _uncompress_list.find( name ) ;
00099 if( i == _uncompress_list.end() )
00100 {
00101 _uncompress_list[name] = method ;
00102 return true ;
00103 }
00104 return false ;
00105 }
00106
00115 bool
00116 BESUncompressManager::remove_method( const string &name )
00117 {
00118 BESUncompressManager::UIter i ;
00119 i = _uncompress_list.find( name ) ;
00120 if( i != _uncompress_list.end() )
00121 {
00122 _uncompress_list.erase( i ) ;
00123 return true ;
00124 }
00125 return false ;
00126 }
00127
00136 p_bes_uncompress
00137 BESUncompressManager::find_method( const string &name )
00138 {
00139 BESUncompressManager::UCIter i ;
00140 i = _uncompress_list.find( name ) ;
00141 if( i != _uncompress_list.end() )
00142 {
00143 return (*i).second ;
00144 }
00145 return 0 ;
00146 }
00147
00153 string
00154 BESUncompressManager::get_method_names()
00155 {
00156 string ret ;
00157 bool first_name = true ;
00158 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00159 for( ; i != _uncompress_list.end(); i++ )
00160 {
00161 if( !first_name )
00162 ret += ", " ;
00163 ret += (*i).first ;
00164 first_name = false ;
00165 }
00166 return ret ;
00167 }
00168
00176 string
00177 BESUncompressManager::uncompress( const string &src, BESCache &cache )
00178 {
00179 BESDEBUG( "BESUncompressManager::uncompress - src = " << src << endl )
00180 string::size_type dot = src.rfind( "." ) ;
00181 if( dot != string::npos )
00182 {
00183 string ext = src.substr( dot+1, src.length() - dot ) ;
00184
00185 for( int i = 0; i < ext.length(); i++ )
00186 {
00187 ext[i] = tolower( ext[i] ) ;
00188 }
00189
00190
00191
00192
00193 p_bes_uncompress p = find_method( ext ) ;
00194 if( p )
00195 {
00196
00197
00198
00199 if( cache.lock( _retry, _num_tries ) )
00200 {
00201 try
00202 {
00203
00204
00205
00206 BESDEBUG( "BESUncompressManager::uncompress - is cached? " \
00207 << src << endl )
00208 string target ;
00209 if( cache.is_cached( src, target ) )
00210 {
00211 BESDEBUG( "BESUncompressManager::uncompress - " \
00212 << "is cached " << target << endl )
00213 cache.unlock() ;
00214 return target ;
00215 }
00216
00217
00218
00219
00220 BESDEBUG( "BESUncompressManager::uncompress - " \
00221 << "purging cache" << endl )
00222 cache.purge() ;
00223
00224
00225 BESDEBUG( "BESUncompressManager::uncompress - " \
00226 << "uncompress to " << target \
00227 << " using " << ext << " uncompression" \
00228 << endl )
00229
00230
00231 cache.unlock() ;
00232
00233
00234
00235
00236 return p( src, target ) ;
00237 }
00238 catch( BESException &e )
00239 {
00240
00241
00242 cache.unlock() ;
00243 throw e ;
00244 }
00245 catch( ... )
00246 {
00247
00248
00249 cache.unlock() ;
00250 string err = (string)"Problem working with the cache, "
00251 + "unknow error" ;
00252 throw BESContainerStorageException( err, __FILE__,__LINE__);
00253 }
00254 }
00255 else
00256 {
00257 string err = "Unable to lock the cache "
00258 + cache.cache_dir() ;
00259 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00260 }
00261 }
00262 else
00263 {
00264 BESDEBUG( "BESUncompressManager::uncompress - not compressed " \
00265 << endl )
00266 }
00267 }
00268 else
00269 {
00270 string err = "Unable to determine type of file from "
00271 + src ;
00272 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00273 }
00274
00275 return src ;
00276 }
00277
00285 void
00286 BESUncompressManager::dump( ostream &strm ) const
00287 {
00288 strm << BESIndent::LMarg << "BESUncompressManager::dump - ("
00289 << (void *)this << ")" << endl ;
00290 BESIndent::Indent() ;
00291 if( _uncompress_list.size() )
00292 {
00293 strm << BESIndent::LMarg << "registered uncompression methods:" << endl;
00294 BESIndent::Indent() ;
00295 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00296 BESUncompressManager::UCIter ie = _uncompress_list.end() ;
00297 for( ; i != ie; i++ )
00298 {
00299 strm << BESIndent::LMarg << (*i).first << endl ;
00300 }
00301 BESIndent::UnIndent() ;
00302 }
00303 else
00304 {
00305 strm << BESIndent::LMarg << "registered uncompress methods: none" << endl ;
00306 }
00307 BESIndent::UnIndent() ;
00308 }
00309
00310 BESUncompressManager *
00311 BESUncompressManager::TheManager()
00312 {
00313 if( _instance == 0 )
00314 {
00315 _instance = new BESUncompressManager ;
00316 }
00317 return _instance ;
00318 }