Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:13

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