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.),
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
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
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 )
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 )
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