CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch2/src/IOPool/TFileAdaptor/src/TFileAdaptor.cc

Go to the documentation of this file.
00001 #include "TFileAdaptor.h"
00002 
00003 #include "FWCore/Catalog/interface/SiteLocalConfig.h"
00004 #include "FWCore/MessageLogger/interface/JobReport.h"
00005 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00008 #include "FWCore/ServiceRegistry/interface/Service.h"
00009 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
00010 #include "FWCore/Utilities/interface/EDMException.h"
00011 #include "Utilities/StorageFactory/interface/StorageAccount.h"
00012 #include "Utilities/StorageFactory/interface/StorageFactory.h"
00013 
00014 #include <TROOT.h>
00015 #include <TFile.h>
00016 #include <TPluginManager.h>
00017 
00018 #include <boost/shared_ptr.hpp>
00019 
00020 #include <algorithm>
00021 #include <sstream>
00022 
00023 // Driver for configuring ROOT plug-in manager to use TStorageFactoryFile.
00024 
00039   void
00040   TFileAdaptor::addType(TPluginManager* mgr, char const* type, int altType /*=0*/) {
00041 
00042     mgr->AddHandler("TFile",
00043                     type,
00044                     "TStorageFactoryFile",
00045                     "IOPoolTFileAdaptor",
00046                     "TStorageFactoryFile(char const*,Option_t*,char const*,Int_t)");
00047 
00048     // HACK:
00049     // The ROOT plug-in manager does not understand loading plugins with different
00050     // signatures.  So, because TXNetSystem is registered with a different constructor
00051     // than all the other plugins, we must match its interface in order to override
00052     // it.
00053     if (altType == 0) {
00054       mgr->AddHandler("TSystem",
00055                       type,
00056                       "TStorageFactorySystem",
00057                       "IOPoolTFileAdaptor",
00058                       "TStorageFactorySystem()");
00059     } else if (altType == 1) {
00060       mgr->AddHandler("TSystem",
00061                       type,
00062                       "TStorageFactorySystem",
00063                       "IOPoolTFileAdaptor",
00064                       "TStorageFactorySystem(const char *,Bool_t)");
00065     }
00066 
00067   }
00068 
00069   bool
00070   TFileAdaptor::native(char const* proto) const {
00071     return std::find(native_.begin(), native_.end(), "all") != native_.end()
00072       || std::find(native_.begin(), native_.end(), proto) != native_.end();
00073   }
00074 
00075   TFileAdaptor::TFileAdaptor(edm::ParameterSet const& pset, edm::ActivityRegistry& ar)
00076     : enabled_(true),
00077       doStats_(true),
00078       cacheHint_("application-only"),
00079       readHint_("auto-detect"),
00080       tempDir_(),
00081       minFree_(0),
00082       timeout_(0U),
00083       debugLevel_(0U),
00084       native_() {
00085     if (!(enabled_ = pset.getUntrackedParameter<bool> ("enable", enabled_)))
00086       return;
00087 
00088     StorageFactory* f = StorageFactory::get();
00089     doStats_ = pset.getUntrackedParameter<bool> ("stats", doStats_);
00090 
00091     // values set in the site local config or in SiteLocalConfigService override
00092     // any values set here for this service.
00093     // These parameters here are needed only for backward compatibility
00094     // for WMDM tools until we switch to only using the site local config for this info.
00095     cacheHint_ = pset.getUntrackedParameter<std::string> ("cacheHint", cacheHint_);
00096     readHint_ = pset.getUntrackedParameter<std::string> ("readHint", readHint_);
00097     tempDir_ = pset.getUntrackedParameter<std::string> ("tempDir", f->tempPath());
00098     minFree_ = pset.getUntrackedParameter<double> ("tempMinFree", f->tempMinFree());
00099     native_ = pset.getUntrackedParameter<std::vector<std::string> >("native", native_);
00100 
00101     ar.watchPostEndJob(this, &TFileAdaptor::termination);
00102 
00103     // Retrieve values from SiteLocalConfigService.
00104     // Any such values will override values set above.
00105     edm::Service<edm::SiteLocalConfig> pSLC;
00106     if (pSLC.isAvailable()) {
00107       if (std::string const* p = pSLC->sourceCacheTempDir()) {
00108         tempDir_ = *p;
00109       }
00110       if (double const* p = pSLC->sourceCacheMinFree()) {
00111         minFree_ = *p;
00112       }
00113       if (std::string const* p = pSLC->sourceCacheHint()) {
00114         cacheHint_ = *p;
00115       }
00116       if (std::string const* p = pSLC->sourceReadHint()) {
00117         readHint_ = *p;
00118       }
00119       if (unsigned int const* p = pSLC->sourceTimeout()) {
00120         timeout_ = *p;
00121       }
00122       if (std::vector<std::string> const* p = pSLC->sourceNativeProtocols()) {
00123         native_ = *p;
00124       }
00125       debugLevel_ = pSLC->debugLevel();
00126     }
00127 
00128     // tell factory how clients should access files
00129     if (cacheHint_ == "application-only")
00130       f->setCacheHint(StorageFactory::CACHE_HINT_APPLICATION);
00131     else if (cacheHint_ == "storage-only")
00132       f->setCacheHint(StorageFactory::CACHE_HINT_STORAGE);
00133     else if (cacheHint_ == "lazy-download")
00134       f->setCacheHint(StorageFactory::CACHE_HINT_LAZY_DOWNLOAD);
00135     else if (cacheHint_ == "auto-detect")
00136       f->setCacheHint(StorageFactory::CACHE_HINT_AUTO_DETECT);
00137     else
00138       throw cms::Exception("TFileAdaptor")
00139         << "Unrecognised 'cacheHint' value '" << cacheHint_
00140         << "', recognised values are 'application-only',"
00141         << " 'storage-only', 'lazy-download', 'auto-detect'";
00142 
00143     if (readHint_ == "direct-unbuffered")
00144       f->setReadHint(StorageFactory::READ_HINT_UNBUFFERED);
00145     else if (readHint_ == "read-ahead-buffered")
00146       f->setReadHint(StorageFactory::READ_HINT_READAHEAD);
00147     else if (readHint_ == "auto-detect")
00148       f->setReadHint(StorageFactory::READ_HINT_AUTO);
00149     else
00150       throw cms::Exception("TFileAdaptor")
00151         << "Unrecognised 'readHint' value '" << readHint_
00152         << "', recognised values are 'direct-unbuffered',"
00153         << " 'read-ahead-buffered', 'auto-detect'";
00154 
00155     f->setTimeout(timeout_);
00156     f->setDebugLevel(debugLevel_);
00157 
00158     // enable file access stats accounting if requested
00159     f->enableAccounting(doStats_);
00160 
00161     // tell where to save files.
00162     f->setTempDir(tempDir_, minFree_);
00163 
00164     // set our own root plugins
00165     TPluginManager* mgr = gROOT->GetPluginManager();
00166     mgr->LoadHandlersFromPluginDirs();
00167 
00168     if (!native("file"))      addType(mgr, "^file:");
00169     if (!native("https"))      addType(mgr, "^https:");
00170     if (!native("ftp"))       addType(mgr, "^ftp:");
00171     /* always */              addType(mgr, "^web:");
00172     /* always */              addType(mgr, "^gsiftp:");
00173     /* always */              addType(mgr, "^sfn:");
00174     if (!native("rfio"))      addType(mgr, "^rfio:");
00175     if (!native("dcache"))    addType(mgr, "^dcache:");
00176     if (!native("dcap"))      addType(mgr, "^dcap:");
00177     if (!native("gsidcap"))   addType(mgr, "^gsidcap:");
00178     if (!native("storm"))     addType(mgr, "^storm:");
00179     if (!native("storm-lcg")) addType(mgr, "^storm-lcg:");
00180     if (!native("lstore"))    addType(mgr, "^lstore:");
00181     // This is ready to go from a code point-of-view.
00182     // Waiting on the validation "OK" from Computing.
00183     //if (!native("root"))      addType(mgr, "^root:", 1); // See comments in addType
00184   }
00185 
00186   void
00187   TFileAdaptor::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00188     edm::ParameterSetDescription desc;
00189     desc.addOptionalUntracked<bool>("enable");
00190     desc.addOptionalUntracked<bool>("stats");
00191     desc.addOptionalUntracked<std::string>("cacheHint");
00192     desc.addOptionalUntracked<std::string>("readHint");
00193     desc.addOptionalUntracked<std::string>("tempDir");
00194     desc.addOptionalUntracked<double>("tempMinFree");
00195     desc.addOptionalUntracked<std::vector<std::string> >("native");
00196     descriptions.add("AdaptorConfig", desc);
00197   }
00198 
00199   // Write current Storage statistics on a ostream
00200   void
00201   TFileAdaptor::termination(void) const {
00202     std::map<std::string, std::string> data;
00203     statsXML(data);
00204     if (!data.empty()) {
00205       edm::Service<edm::JobReport> reportSvc;
00206       reportSvc->reportPerformanceSummary("StorageStatistics", data);
00207     }
00208   }
00209 
00210   void
00211   TFileAdaptor::stats(std::ostream& o) const {
00212     if (!doStats_) {
00213       return;
00214     }
00215     float const oneMeg = 1048576.0;
00216     o << "Storage parameters: adaptor: true"
00217       << " Stats:" << (doStats_ ? "true" : "false") << '\n'
00218       << " Cache hint:" << cacheHint_ << '\n'
00219       << " Read hint:" << readHint_ << '\n'
00220       << "Storage statistics: "
00221       << StorageAccount::summaryText()
00222       << "; tfile/read=?/?/" << (TFile::GetFileBytesRead() / oneMeg) << "MB/?ms/?ms/?ms"
00223       << "; tfile/write=?/?/" << (TFile::GetFileBytesWritten() / oneMeg) << "MB/?ms/?ms/?ms";
00224   }
00225 
00226   void
00227   TFileAdaptor::statsXML(std::map<std::string, std::string>& data) const {
00228     if (!doStats_) {
00229       return;
00230     }
00231     float const oneMeg = 1048576.0;
00232     data.insert(std::make_pair("Parameter-untracked-bool-enabled", "true"));
00233     data.insert(std::make_pair("Parameter-untracked-bool-stats", (doStats_ ? "true" : "false")));
00234     data.insert(std::make_pair("Parameter-untracked-string-cacheHint", cacheHint_));
00235     data.insert(std::make_pair("Parameter-untracked-string-readHint", readHint_));
00236     StorageAccount::fillSummary(data);
00237     std::ostringstream r;
00238     std::ostringstream w;
00239     r << (TFile::GetFileBytesRead() / oneMeg);
00240     w << (TFile::GetFileBytesWritten() / oneMeg);
00241     data.insert(std::make_pair("ROOT-tfile-read-totalMegabytes", r.str()));
00242     data.insert(std::make_pair("ROOT-tfile-write-totalMegabytes", w.str()));
00243   }
00244 
00245 /*
00246  * wrapper to bind TFileAdaptor to root, python etc
00247  * loading IOPoolTFileAdaptor library and instantiating
00248  * TFileAdaptorUI will make root to use StorageAdaptor for I/O instead
00249  * of its own plugins
00250  */
00251 class TFileAdaptorUI {
00252 public:
00253 
00254   TFileAdaptorUI();
00255   ~TFileAdaptorUI();
00256 
00257   // print current Storage statistics on cout
00258   void stats() const;
00259 
00260 private:
00261   boost::shared_ptr<TFileAdaptor> me;
00262 };
00263 
00264 #include <iostream>
00265 
00266 TFileAdaptorUI::TFileAdaptorUI() {
00267   edm::ActivityRegistry ar;
00268   const edm::ParameterSet param;
00269   me.reset(new TFileAdaptor(param, ar));
00270 }
00271 
00272 TFileAdaptorUI::~TFileAdaptorUI() {}
00273 
00274 void TFileAdaptorUI::stats() const {
00275   me->stats(std::cout); std::cout << std::endl;
00276 }
00277 
00278 typedef TFileAdaptor AdaptorConfig;
00279 
00280 DEFINE_FWK_SERVICE(AdaptorConfig);