CMS 3D CMS Logo

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