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
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
00069
00070
00071
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
00081
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
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
00134 f->enableAccounting(doStats_);
00135
00136
00137 f->setTempDir(tempDir_, minFree_);
00138
00139
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 addType(mgr, "^web:");
00147 addType(mgr, "^gsiftp:");
00148 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
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
00218
00219
00220
00221
00222 class TFileAdaptorUI {
00223 public:
00224
00225 TFileAdaptorUI();
00226 ~TFileAdaptorUI();
00227
00228
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);