Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-10-01 22:40:45

0001 #include "TFileAdaptor.h"
0002 
0003 #include "FWCore/Catalog/interface/SiteLocalConfig.h"
0004 #include "FWCore/MessageLogger/interface/JobReport.h"
0005 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0008 #include "FWCore/ServiceRegistry/interface/Service.h"
0009 #include "FWCore/Utilities/interface/EDMException.h"
0010 #include "Utilities/StorageFactory/interface/StorageAccount.h"
0011 #include "Utilities/StorageFactory/interface/StorageFactory.h"
0012 
0013 #include <TROOT.h>
0014 #include <TFile.h>
0015 #include <TPluginManager.h>
0016 
0017 #include <memory>
0018 
0019 #include <algorithm>
0020 #include <sstream>
0021 
0022 // Driver for configuring ROOT plug-in manager to use TStorageFactoryFile.
0023 
0024 /**
0025    Register TFileAdaptor to be the handler for a given type.
0026 
0027    Once registered, URLs matching a specified regexp (for example, ^lstore: to
0028    manage files starting with lstore://) will be managed by a TFileAdaptor instance,
0029    possibly overriding any built-in ROOT adaptors.
0030 
0031    @param[in] mgr      The ROOT plugin manager object.
0032    @param[in] type     A regexp-string; URLs matching this string will use TFileAdaptor.
0033    @param[in] altType  Due to a limitation in the TPluginManager, if the type was 
0034                        previously managed by TXNetFile, we must invoke AddHandler with
0035                        a slightly different syntax.  Set this parameter to 1 if this
0036                        applies to you.  Otherwise, leave it at the default (0)
0037  */
0038 void TFileAdaptor::addType(TPluginManager* mgr, char const* type, int altType /*=0*/) {
0039   // HACK:
0040   // The ROOT plug-in manager does not understand loading plugins with different
0041   // signatures.  So, because TXNetSystem is registered with a different constructor
0042   // than all the other plugins, we must match its interface in order to override
0043   // it.
0044   if (altType == 0) {
0045     mgr->AddHandler("TFile",
0046                     type,
0047                     "TStorageFactoryFile",
0048                     "IOPoolTFileAdaptor",
0049                     "TStorageFactoryFile(char const*,Option_t*,char const*,Int_t)");
0050 
0051     mgr->AddHandler("TSystem", type, "TStorageFactorySystem", "IOPoolTFileAdaptor", "TStorageFactorySystem()");
0052   } else if (altType == 1) {
0053     mgr->AddHandler("TFile",
0054                     type,
0055                     "TStorageFactoryFile",
0056                     "IOPoolTFileAdaptor",
0057                     "TStorageFactoryFile(char const*,Option_t*,char const*,Int_t, Int_t, Bool_t)");
0058 
0059     mgr->AddHandler(
0060         "TSystem", type, "TStorageFactorySystem", "IOPoolTFileAdaptor", "TStorageFactorySystem(const char *,Bool_t)");
0061   }
0062 }
0063 
0064 bool TFileAdaptor::native(char const* proto) const {
0065   return std::find(native_.begin(), native_.end(), "all") != native_.end() ||
0066          std::find(native_.begin(), native_.end(), proto) != native_.end();
0067 }
0068 
0069 TFileAdaptor::TFileAdaptor(edm::ParameterSet const& pset, edm::ActivityRegistry& ar)
0070     : enabled_(true),
0071       doStats_(true),
0072       enablePrefetching_(false),
0073       cacheHint_("auto-detect"),
0074       readHint_("auto-detect"),
0075       tempDir_(),
0076       minFree_(0),
0077       timeout_(0U),
0078       debugLevel_(0U),
0079       native_() {
0080   if (!(enabled_ = pset.getUntrackedParameter<bool>("enable", enabled_)))
0081     return;
0082 
0083   using namespace edm::storage;
0084   StorageFactory* f = StorageFactory::getToModify();
0085   doStats_ = pset.getUntrackedParameter<bool>("stats", doStats_);
0086 
0087   // values set in the site local config or in SiteLocalConfigService override
0088   // any values set here for this service.
0089   // These parameters here are needed only for backward compatibility
0090   // for WMDM tools until we switch to only using the site local config for this info.
0091   cacheHint_ = pset.getUntrackedParameter<std::string>("cacheHint", cacheHint_);
0092   readHint_ = pset.getUntrackedParameter<std::string>("readHint", readHint_);
0093   tempDir_ = pset.getUntrackedParameter<std::string>("tempDir", f->tempPath());
0094   minFree_ = pset.getUntrackedParameter<double>("tempMinFree", f->tempMinFree());
0095   native_ = pset.getUntrackedParameter<std::vector<std::string> >("native", native_);
0096 
0097   ar.watchPostEndJob(this, &TFileAdaptor::termination);
0098 
0099   // Retrieve values from SiteLocalConfigService.
0100   // Any such values will override values set above.
0101   edm::Service<edm::SiteLocalConfig> pSLC;
0102   if (pSLC.isAvailable()) {
0103     if (std::string const* p = pSLC->sourceCacheTempDir()) {
0104       tempDir_ = *p;
0105     }
0106     if (double const* p = pSLC->sourceCacheMinFree()) {
0107       minFree_ = *p;
0108     }
0109     if (std::string const* p = pSLC->sourceCacheHint()) {
0110       cacheHint_ = *p;
0111     }
0112     if (std::string const* p = pSLC->sourceReadHint()) {
0113       readHint_ = *p;
0114     }
0115     if (unsigned int const* p = pSLC->sourceTimeout()) {
0116       timeout_ = *p;
0117     }
0118     if (std::vector<std::string> const* p = pSLC->sourceNativeProtocols()) {
0119       native_ = *p;
0120     }
0121     debugLevel_ = pSLC->debugLevel();
0122     enablePrefetching_ = pSLC->enablePrefetching();
0123   }
0124 
0125   // Prefetching does not work with storage-only; forcibly disable it.
0126   if ((enablePrefetching_) && ((cacheHint_ == "storage-only") || (cacheHint_ == "auto-detect")))
0127     cacheHint_ = "application-only";
0128 
0129   // tell factory how clients should access files
0130   if (cacheHint_ == "application-only")
0131     f->setCacheHint(StorageFactory::CACHE_HINT_APPLICATION);
0132   else if (cacheHint_ == "storage-only")
0133     f->setCacheHint(StorageFactory::CACHE_HINT_STORAGE);
0134   else if (cacheHint_ == "lazy-download")
0135     f->setCacheHint(StorageFactory::CACHE_HINT_LAZY_DOWNLOAD);
0136   else if (cacheHint_ == "auto-detect")
0137     f->setCacheHint(StorageFactory::CACHE_HINT_AUTO_DETECT);
0138   else
0139     throw cms::Exception("TFileAdaptor") << "Unrecognised 'cacheHint' value '" << cacheHint_
0140                                          << "', recognised values are 'application-only',"
0141                                          << " 'storage-only', 'lazy-download', 'auto-detect'";
0142 
0143   if (readHint_ == "direct-unbuffered")
0144     f->setReadHint(StorageFactory::READ_HINT_UNBUFFERED);
0145   else if (readHint_ == "read-ahead-buffered")
0146     f->setReadHint(StorageFactory::READ_HINT_READAHEAD);
0147   else if (readHint_ == "auto-detect")
0148     f->setReadHint(StorageFactory::READ_HINT_AUTO);
0149   else
0150     throw cms::Exception("TFileAdaptor") << "Unrecognised 'readHint' value '" << readHint_
0151                                          << "', recognised values are 'direct-unbuffered',"
0152                                          << " 'read-ahead-buffered', 'auto-detect'";
0153 
0154   f->setTimeout(timeout_);
0155   f->setDebugLevel(debugLevel_);
0156 
0157   // enable file access stats accounting if requested
0158   f->enableAccounting(doStats_);
0159 
0160   // tell where to save files.
0161   f->setTempDir(tempDir_, minFree_);
0162 
0163   // set our own root plugins
0164   TPluginManager* mgr = gROOT->GetPluginManager();
0165 
0166   // Make sure ROOT parses system directories first.
0167   mgr->LoadHandlersFromPluginDirs("TFile");
0168   mgr->LoadHandlersFromPluginDirs("TSystem");
0169 
0170   if (!native("file"))
0171     addType(mgr, "^file:");
0172   if (!native("http"))
0173     addType(mgr, "^http:");
0174   if (!native("http"))
0175     addType(mgr, "^http[s]?:");
0176   if (!native("ftp"))
0177     addType(mgr, "^ftp:");
0178   /* always */ addType(mgr, "^web:");
0179   /* always */ addType(mgr, "^gsiftp:");
0180   /* always */ addType(mgr, "^sfn:");
0181   if (!native("rfio"))
0182     addType(mgr, "^rfio:");
0183   if (!native("dcache"))
0184     addType(mgr, "^dcache:");
0185   if (!native("dcap"))
0186     addType(mgr, "^dcap:");
0187   if (!native("gsidcap"))
0188     addType(mgr, "^gsidcap:");
0189   if (!native("storm"))
0190     addType(mgr, "^storm:");
0191   if (!native("storm-lcg"))
0192     addType(mgr, "^storm-lcg:");
0193   if (!native("lstore"))
0194     addType(mgr, "^lstore:");
0195   if (!native("root"))
0196     addType(mgr, "^root:", 1);  // See comments in addType
0197   if (!native("root"))
0198     addType(mgr, "^[x]?root:", 1);  // See comments in addType
0199 }
0200 
0201 void TFileAdaptor::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0202   edm::ParameterSetDescription desc;
0203   desc.addOptionalUntracked<bool>("enable");
0204   desc.addOptionalUntracked<bool>("stats");
0205   desc.addOptionalUntracked<std::string>("cacheHint");
0206   desc.addOptionalUntracked<std::string>("readHint");
0207   desc.addOptionalUntracked<std::string>("tempDir");
0208   desc.addOptionalUntracked<double>("tempMinFree");
0209   desc.addOptionalUntracked<std::vector<std::string> >("native");
0210   descriptions.add("AdaptorConfig", desc);
0211 }
0212 
0213 // Write current Storage statistics on a ostream
0214 void TFileAdaptor::termination(void) const {
0215   std::map<std::string, std::string> data;
0216   statsXML(data);
0217   if (!data.empty()) {
0218     edm::Service<edm::JobReport> reportSvc;
0219     reportSvc->reportPerformanceSummary("StorageStatistics", data);
0220   }
0221 }
0222 
0223 void TFileAdaptor::stats(std::ostream& o) const {
0224   if (!doStats_) {
0225     return;
0226   }
0227   float const oneMeg = 1048576.0;
0228   o << "Storage parameters: adaptor: true"
0229     << " Stats:" << (doStats_ ? "true" : "false") << '\n'
0230     << " Prefetching:" << (enablePrefetching_ ? "true" : "false") << '\n'
0231     << " Cache hint:" << cacheHint_ << '\n'
0232     << " Read hint:" << readHint_ << '\n'
0233     << "Storage statistics: " << edm::storage::StorageAccount::summaryText() << "; tfile/read=?/?/"
0234     << (TFile::GetFileBytesRead() / oneMeg) << "MB/?ms/?ms/?ms"
0235     << "; tfile/write=?/?/" << (TFile::GetFileBytesWritten() / oneMeg) << "MB/?ms/?ms/?ms";
0236 }
0237 
0238 void TFileAdaptor::statsXML(std::map<std::string, std::string>& data) const {
0239   if (!doStats_) {
0240     return;
0241   }
0242   float const oneMeg = 1048576.0;
0243   data.insert(std::make_pair("Parameter-untracked-bool-enabled", "true"));
0244   data.insert(std::make_pair("Parameter-untracked-bool-stats", (doStats_ ? "true" : "false")));
0245   data.insert(std::make_pair("Parameter-untracked-bool-prefetching", (enablePrefetching_ ? "true" : "false")));
0246   data.insert(std::make_pair("Parameter-untracked-string-cacheHint", cacheHint_));
0247   data.insert(std::make_pair("Parameter-untracked-string-readHint", readHint_));
0248   edm::storage::StorageAccount::fillSummary(data);
0249   std::ostringstream r;
0250   std::ostringstream w;
0251   r << (TFile::GetFileBytesRead() / oneMeg);
0252   w << (TFile::GetFileBytesWritten() / oneMeg);
0253   data.insert(std::make_pair("ROOT-tfile-read-totalMegabytes", r.str()));
0254   data.insert(std::make_pair("ROOT-tfile-write-totalMegabytes", w.str()));
0255 }
0256 
0257 #include <iostream>
0258 
0259 TFileAdaptorUI::TFileAdaptorUI() {
0260   edm::ActivityRegistry ar;
0261   const edm::ParameterSet param;
0262   me = std::make_shared<TFileAdaptor>(param, ar);  // propagate_const<T> has no reset() function
0263 }
0264 
0265 TFileAdaptorUI::~TFileAdaptorUI() {}
0266 
0267 void TFileAdaptorUI::stats() const {
0268   me->stats(std::cout);
0269   std::cout << std::endl;
0270 }