CMS 3D CMS Logo

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