CMS 3D CMS Logo

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