CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/Utilities/StorageFactory/src/StorageFactory.cc

Go to the documentation of this file.
00001 #include "Utilities/StorageFactory/interface/StorageFactory.h"
00002 #include "Utilities/StorageFactory/interface/StorageMakerFactory.h"
00003 #include "Utilities/StorageFactory/interface/StorageAccount.h"
00004 #include "Utilities/StorageFactory/interface/StorageAccountProxy.h"
00005 #include "Utilities/StorageFactory/interface/LocalCacheFile.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/PluginManager/interface/PluginManager.h"
00008 #include "FWCore/PluginManager/interface/standard.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include <boost/shared_ptr.hpp>
00011 
00012 StorageFactory StorageFactory::s_instance;
00013 
00014 StorageFactory::StorageFactory (void)
00015   : m_cacheHint(CACHE_HINT_AUTO_DETECT),
00016     m_readHint(READ_HINT_AUTO),
00017     m_accounting (false),
00018     m_tempfree (4.), // GB
00019     m_temppath (".:$TMPDIR"),
00020     m_timeout(0U),
00021     m_debugLevel(0U)
00022 {
00023   setTempDir(m_temppath, m_tempfree);
00024 }
00025 
00026 StorageFactory::~StorageFactory (void)
00027 {
00028   for (MakerTable::iterator i = m_makers.begin (); i != m_makers.end (); ++i)
00029     delete i->second;
00030 }
00031 
00032 StorageFactory *
00033 StorageFactory::get (void)
00034 { return &s_instance; }
00035 
00036 bool
00037 StorageFactory::enableAccounting (bool enabled)
00038 {
00039   bool old = m_accounting;
00040   m_accounting = enabled;
00041   return old;
00042 }
00043 
00044 bool
00045 StorageFactory::accounting(void) const
00046 { return m_accounting; }
00047 
00048 void
00049 StorageFactory::setCacheHint(CacheHint value)
00050 { m_cacheHint = value; }
00051 
00052 StorageFactory::CacheHint
00053 StorageFactory::cacheHint(void) const
00054 { return m_cacheHint; }
00055 
00056 void
00057 StorageFactory::setReadHint(ReadHint value)
00058 { m_readHint = value; }
00059 
00060 StorageFactory::ReadHint
00061 StorageFactory::readHint(void) const
00062 { return m_readHint; }
00063 
00064 void
00065 StorageFactory::setTimeout(unsigned int timeout)
00066 { m_timeout = timeout; }
00067 
00068 unsigned int
00069 StorageFactory::timeout(void) const
00070 { return m_timeout; }
00071 
00072 void
00073 StorageFactory::setDebugLevel(unsigned int level)
00074 { m_debugLevel = level; }
00075 
00076 unsigned int
00077 StorageFactory::debugLevel(void) const
00078 { return m_debugLevel; }
00079 
00080 void
00081 StorageFactory::setTempDir(const std::string &s, double minFreeSpace)
00082 {
00083 #if 0
00084   std::cerr /* edm::LogInfo("StorageFactory") */
00085     << "Considering path '" << s
00086     << "', min free space " << minFreeSpace
00087     << "GB for temp dir" << std::endl;
00088 #endif
00089 
00090   size_t begin = 0;
00091   std::vector<std::string> dirs;
00092   dirs.reserve(std::count(s.begin(), s.end(), ':') + 1);
00093 
00094   while (true)
00095   {
00096     size_t end = s.find(':', begin);
00097     if (end == std::string::npos)
00098     {
00099       dirs.push_back(s.substr(begin, end));
00100       break;
00101     }
00102     else
00103     {
00104       dirs.push_back(s.substr(begin, end - begin));
00105       begin = end+1;
00106     }
00107   }
00108 
00109   m_temppath = s;
00110   m_tempfree = minFreeSpace;
00111   m_tempdir = m_lfs.findCachePath(dirs, minFreeSpace);
00112 
00113 #if 0
00114   std::cerr /* edm::LogInfo("StorageFactory") */
00115     << "Using '" << m_tempdir << "' for temp dir"
00116     << std::endl;
00117 #endif
00118 }
00119 
00120 std::string
00121 StorageFactory::tempDir(void) const
00122 { return m_tempdir; }
00123 
00124 std::string
00125 StorageFactory::tempPath(void) const
00126 { return m_temppath; }
00127 
00128 double
00129 StorageFactory::tempMinFree(void) const
00130 { return m_tempfree; }
00131 
00132 StorageMaker *
00133 StorageFactory::getMaker (const std::string &proto)
00134 {
00135   StorageMaker *&instance = m_makers [proto];
00136   if (! edmplugin::PluginManager::isAvailable())
00137     edmplugin::PluginManager::configure(edmplugin::standard::config());
00138   if (! instance)
00139     instance = StorageMakerFactory::get()->tryToCreate(proto);
00140   return instance;
00141 }
00142 
00143 StorageMaker *
00144 StorageFactory::getMaker (const std::string &url,
00145                           std::string &protocol,
00146                           std::string &rest)
00147 {
00148   size_t p = url.find(':');
00149   if (p != std::string::npos)
00150   {
00151     protocol = url.substr(0,p);
00152     rest = url.substr(p+1);
00153   }
00154   else
00155   {
00156     protocol = "file"; 
00157     rest = url;
00158   }
00159 
00160   return getMaker (protocol);
00161 }
00162    
00163 Storage *
00164 StorageFactory::open (const std::string &url, int mode /* = IOFlags::OpenRead */)
00165 { 
00166   std::string protocol;
00167   std::string rest;
00168   Storage *ret = 0;
00169   boost::shared_ptr<StorageAccount::Stamp> stats;
00170   if (StorageMaker *maker = getMaker (url, protocol, rest))
00171   {
00172     maker->setDebugLevel(m_debugLevel);
00173     if (m_accounting) 
00174       stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "open")));
00175     try
00176     {
00177       if (Storage *storage = maker->open (protocol, rest, mode))
00178       {
00179         if (dynamic_cast<LocalCacheFile *>(storage))
00180           protocol = "local-cache";
00181 
00182         if (m_accounting)
00183           ret = new StorageAccountProxy(protocol, storage);
00184         else
00185           ret = storage;
00186 
00187         if (stats)
00188           stats->tick();
00189       }
00190     }
00191     catch (cms::Exception &err)
00192     {
00193       err.addContext("Calling StorageFactory::open()");
00194       err.addAdditionalInfo(err.message());
00195       err.clearMessage();
00196       err << "Failed to open the file '" << url << "'";
00197       throw;
00198     }
00199   } 
00200   return ret;
00201 }
00202 
00203 void
00204 StorageFactory::stagein (const std::string &url)
00205 { 
00206   std::string protocol;
00207   std::string rest;
00208 
00209   boost::shared_ptr<StorageAccount::Stamp> stats;
00210   if (StorageMaker *maker = getMaker (url, protocol, rest))
00211   {
00212     if (m_accounting) 
00213       stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "stagein")));
00214     try
00215     {
00216       maker->stagein (protocol, rest);
00217       if (stats) stats->tick();
00218     }
00219     catch (cms::Exception &err)
00220     {
00221       edm::LogWarning("StorageFactory::stagein()")
00222         << "Failed to stage in file '" << url << "' because:\n"
00223         << err.explainSelf();
00224     }
00225   }
00226 }
00227 
00228 bool
00229 StorageFactory::check (const std::string &url, IOOffset *size /* = 0 */)
00230 { 
00231   std::string protocol;
00232   std::string rest;
00233 
00234   bool ret = false;
00235   boost::shared_ptr<StorageAccount::Stamp> stats;
00236   if (StorageMaker *maker = getMaker (url, protocol, rest))
00237   {
00238     if (m_accounting) 
00239       stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "check")));
00240     try
00241     {
00242       ret = maker->check (protocol, rest, size);
00243       if (stats) stats->tick();
00244     }
00245     catch (cms::Exception &err)
00246     {
00247       edm::LogWarning("StorageFactory::check()")
00248         << "Existence or size check for the file '" << url << "' failed because:\n"
00249         << err.explainSelf();
00250     }
00251   }
00252  
00253   return ret;
00254 }
00255 
00256 Storage *
00257 StorageFactory::wrapNonLocalFile (Storage *s,
00258                                   const std::string &proto,
00259                                   const std::string &path,
00260                                   int mode)
00261 {
00262   StorageFactory::CacheHint hint = cacheHint();
00263   if ((hint == StorageFactory::CACHE_HINT_LAZY_DOWNLOAD)
00264       && ! (mode & IOFlags::OpenWrite)
00265       && ! m_tempdir.empty()
00266       && (path.empty() || ! m_lfs.isLocalPath(path)))
00267   {
00268     if (accounting())
00269       s = new StorageAccountProxy(proto, s);
00270     s = new LocalCacheFile(s, m_tempdir);
00271   }
00272 
00273   return s;
00274 }
00275 
00276 void
00277 StorageFactory::activateTimeout (const std::string &url)
00278 {
00279   std::string protocol;
00280   std::string rest;
00281 
00282   if (StorageMaker *maker = getMaker (url, protocol, rest))
00283   {
00284     maker->setTimeout (m_timeout);
00285   }
00286 }
00287 
00288