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
00024
00039 void
00040 TFileAdaptor::addType(TPluginManager* mgr, char const* type, int altType ) {
00041
00042
00043
00044
00045
00046
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
00099
00100
00101
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
00111
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
00137 if ((enablePrefetching_) && ((cacheHint_ == "storage-only") || (cacheHint_ == "auto-detect")))
00138 cacheHint_ = "application-only";
00139
00140
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
00171 f->enableAccounting(doStats_);
00172
00173
00174 f->setTempDir(tempDir_, minFree_);
00175
00176
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 addType(mgr, "^web:");
00184 addType(mgr, "^gsiftp:");
00185 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
00194
00195 if (!native("root")) addType(mgr, "^root:", 1);
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
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
00261
00262
00263
00264
00265 class TFileAdaptorUI {
00266 public:
00267
00268 TFileAdaptorUI();
00269 ~TFileAdaptorUI();
00270
00271
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);