CMS 3D CMS Logo

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

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