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 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
00098
00099
00100
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
00110
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
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
00165 f->enableAccounting(doStats_);
00166
00167
00168 f->setTempDir(tempDir_, minFree_);
00169
00170
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 addType(mgr, "^web:");
00178 addType(mgr, "^gsiftp:");
00179 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
00188
00189 if (!native("root")) addType(mgr, "^root:", 1);
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
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
00253
00254
00255
00256
00257 class TFileAdaptorUI {
00258 public:
00259
00260 TFileAdaptorUI();
00261 ~TFileAdaptorUI();
00262
00263
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);