35 ClassImp(TProofOutputFile);
40 TProofOutputFile::TProofOutputFile(
const char *path,
41 ERunType type, UInt_t opt,
const char *dsname)
42 : TNamed(path,
""), fRunType(type), fTypeOpt(opt)
48 ResetBit(TProofOutputFile::kRetrieve);
49 ResetBit(TProofOutputFile::kSwapFile);
68 TProofOutputFile::TProofOutputFile(
const char *path,
69 const char *option,
const char *dsname)
76 fMergeHistosOneGo = kFALSE;
81 if (option && strlen(option) > 0) {
83 if (opt.Contains(
"L") || (opt ==
"LOCAL")) fTypeOpt = kLocal;
84 if (opt.Contains(
"H")) fMergeHistosOneGo = kTRUE;
85 if (!opt.Contains(
"M") && opt.Contains(
"D")) {
89 if (opt.Contains(
"R")) fTypeOpt = (ETypeOpt) (fTypeOpt | kRegister);
90 if (opt.Contains(
"O")) fTypeOpt = (ETypeOpt) (fTypeOpt | kOverwrite);
91 if (opt.Contains(
"V")) fTypeOpt = (ETypeOpt) (fTypeOpt | kVerify);
101 void TProofOutputFile::Init(
const char *path,
const char *dsname)
103 fLocalHost = TUrl(gSystem->HostName()).GetHostFQDN();
104 Int_t port = gEnv->GetValue(
"ProofServ.XpdPort", -1);
112 TProofServ::ResolveKeywords(xpath, 0);
113 TUrl u(xpath, kTRUE);
115 fFileName = u.GetFile();
117 SetName(gSystem->BaseName(fFileName.Data()));
121 if (fRunType == kDataset) {
122 if (dsname && strlen(dsname) > 0) {
131 if (u.GetOptions() && strlen(u.GetOptions()) > 0)
132 fOptionsAnchor += TString::Format(
"?%s", u.GetOptions());
133 if (u.GetAnchor() && strlen(u.GetAnchor()) > 0)
134 fOptionsAnchor += TString::Format(
"#%s", u.GetAnchor());
138 Int_t pos = fDir.Index(fFileName);
139 if (pos != kNPOS) fDir.Remove(pos);
142 if (fDir.BeginsWith(
"file:")) {
147 TString dirPath = gSystem->DirName(fFileName);
148 fFileName = gSystem->BaseName(fFileName);
149 if (AssertDir(dirPath) != 0)
150 Error(
"Init",
"problems asserting path '%s'", dirPath.Data());
151 TString dirData = (!IsMerge() && gProofServ) ? gProofServ->GetDataDir()
152 : gSystem->WorkingDirectory();
153 if ((dirPath[0] ==
'/') && gSystem->AccessPathName(dirPath, kWritePermission)) {
154 Warning(
"Init",
"not allowed to create files under '%s' - chrooting to '%s'",
155 dirPath.Data(), dirData.Data());
156 dirPath.Insert(0, dirData);
157 }
else if (dirPath.BeginsWith(
"..")) {
158 dirPath.Remove(0, 2);
159 if (dirPath[0] !=
'/') dirPath.Insert(0,
"/");
160 dirPath.Insert(0, dirData);
161 }
else if (dirPath[0] ==
'.' || dirPath[0] ==
'~') {
162 dirPath.Remove(0, 1);
163 if (dirPath[0] !=
'/') dirPath.Insert(0,
"/");
164 dirPath.Insert(0, dirData);
165 }
else if (dirPath.IsNull()) {
171 if (!IsMerge() || (!dirPath.BeginsWith(gProofServ->GetDataDir()) &&
172 !dirPath.BeginsWith(gSystem->WorkingDirectory()))) {
173 if (!dirPath.Contains(gProofServ->GetOrdinal())) {
174 if (!dirPath.EndsWith(
"/")) dirPath +=
"/";
175 dirPath += gProofServ->GetOrdinal();
179 if (!dirPath.Contains(gProofServ->GetSessionTag())) {
180 if (!dirPath.EndsWith(
"/")) dirPath +=
"/";
181 dirPath += gProofServ->GetSessionTag();
183 if (!dirPath.Contains(
"<qnum>")) {
184 if (!dirPath.EndsWith(
"/")) dirPath +=
"/";
188 TProofServ::ResolveKeywords(dirPath, 0);
194 if (AssertDir(dirPath) != 0)
195 Error(
"Init",
"problems asserting path '%s'", dirPath.Data());
197 TProofServ::GetLocalServer(fDir);
198 TProofServ::FilterLocalroot(dirPath, fDir);
203 Info(
"Init",
"dir: %s (raw: %s)", fDir.Data(), fRawDir.Data());
206 ResetBit(TProofOutputFile::kOutputFileNameSet);
207 fOutputFileName =
"<file>";
208 if (gEnv->Lookup(
"Proof.OutputFile")) {
209 fOutputFileName = gEnv->GetValue(
"Proof.OutputFile",
"<file>");
210 SetBit(TProofOutputFile::kOutputFileNameSet);
213 TString fileName = path;
214 if (!fileName.EndsWith(
".root")) fileName +=
".root";
216 if (!fOutputFileName.IsNull() && !fOutputFileName.Contains(
"<file>")) {
217 if (!fOutputFileName.EndsWith(
"/")) fOutputFileName +=
"/";
218 fOutputFileName += fileName;
221 fileName.ReplaceAll(
"<ord>",
"");
222 TProofServ::ResolveKeywords(fOutputFileName, fileName);
223 Info(
"Init",
"output file url: %s", fOutputFileName.Data());
225 fWorkerOrdinal =
"<ord>";
226 TProofServ::ResolveKeywords(fWorkerOrdinal, 0);
232 TProofOutputFile::~TProofOutputFile()
234 if (fDataSet)
delete fDataSet;
235 if (fMerger)
delete fMerger;
241 void TProofOutputFile::SetOutputFileName(
const char *name)
243 if (name && strlen(name) > 0) {
244 fOutputFileName = name;
245 TProofServ::ResolveKeywords(fOutputFileName);
246 PDB(kOutput,1) Info("SetOutputFileName", "output file url: %s", fOutputFileName.Data());
248 fOutputFileName =
"";
250 SetBit(TProofOutputFile::kOutputFileNameSet);
256 TFile* TProofOutputFile::OpenFile(
const char* opt)
258 if (fFileName.IsNull())
return 0;
262 fileLoc.Form(
"%s/%s%s", fRawDir.Data(), fFileName.Data(), fOptionsAnchor.Data());
265 TFile *retFile = TFile::Open(fileLoc, opt);
274 Int_t TProofOutputFile::AdoptFile(TFile *f)
276 if (!f || (f && f->IsZombie())) {
277 Error(
"AdoptFile",
"file is undefined or zombie!");
280 const TUrl *u = f->GetEndpointUrl();
282 Error(
"AdoptFile",
"file end-point url is undefined!");
288 if (!strcmp(u->GetProtocol(),
"file")) {
294 fFileName = gSystem->BaseName(fDir.Data());
295 fDir.ReplaceAll(fFileName,
"");
301 TProofServ::GetLocalServer(localDS);
302 if (!localDS.IsNull()) {
303 TProofServ::FilterLocalroot(fDir, localDS);
304 fDir.Insert(0, localDS);
314 Long64_t TProofOutputFile::Merge(TCollection* list)
316 PDB(kOutput,2) Info("Merge","enter: merge? %d", IsMerge());
319 if(!list || list->IsEmpty()) return 0;
324 TString outputFileLoc = (fOutputFileName.IsNull()) ? fFileName : fOutputFileName;
326 Bool_t localMerge = (fRunType == kMerge && fTypeOpt == kLocal) ? kTRUE : kFALSE;
327 TFileMerger *merger = GetFileMerger(localMerge);
329 Error(
"Merge",
"could not instantiate the file merger");
334 merger->OutputFile(outputFileLoc);
335 fileLoc.Form(
"%s/%s", fDir.Data(), GetFileName());
336 AddFile(merger, fileLoc);
342 while((o = next())) {
343 TProofOutputFile *pFile =
dynamic_cast<TProofOutputFile *
>(o);
345 fileLoc.Form(
"%s/%s", pFile->GetDir(), pFile->GetFileName());
346 AddFile(merger, fileLoc);
351 TUrl mssUrl(gEnv->GetValue(
"ProofServ.PoolUrl",
""));
353 TFileCollection *dataset = GetFileCollection();
355 Error(
"Merge",
"could not instantiate the file collection");
363 PDB(kOutput,2) Info("Merge","dataset: %s (nfiles: %lld)", dataset->GetName(), dataset->GetNFiles());
364 if (dataset->GetNFiles() == 0) {
366 path.Form(
"%s/%s%s", GetDir(), GetFileName(), GetOptionsAnchor());
367 fi =
new TFileInfo(path);
369 if (mssUrl.IsValid()) {
370 TUrl ur(fi->GetFirstUrl()->GetUrl());
371 ur.SetProtocol(mssUrl.GetProtocol());
372 ur.SetHost(mssUrl.GetHost());
373 ur.SetPort(mssUrl.GetPort());
374 if (mssUrl.GetUser() && strlen(mssUrl.GetUser()) > 0)
375 ur.SetUser(mssUrl.GetUser());
376 fi->AddUrl(ur.GetUrl());
379 path.Form(
"%s/%s?node=%s", GetDir(kTRUE), GetFileName(), GetLocalHost());
381 PDB(kOutput,2) fi->Print();
388 while((o = next())) {
389 TProofOutputFile *pFile =
dynamic_cast<TProofOutputFile *
>(o);
392 path.Form(
"%s/%s%s", pFile->GetDir(), pFile->GetFileName(), pFile->GetOptionsAnchor());
393 fi =
new TFileInfo(path);
395 if (mssUrl.IsValid()) {
396 TUrl ur(fi->GetFirstUrl()->GetUrl());
397 ur.SetProtocol(mssUrl.GetProtocol());
398 ur.SetHost(mssUrl.GetHost());
399 ur.SetPort(mssUrl.GetPort());
400 if (mssUrl.GetUser() && strlen(mssUrl.GetUser()) > 0)
401 ur.SetUser(mssUrl.GetUser());
402 fi->AddUrl(ur.GetUrl());
405 path.Form(
"%s/%s?node=%s", pFile->GetDir(kTRUE), pFile->GetFileName(), pFile->GetLocalHost());
407 PDB(kOutput,2) fi->Print();
413 PDB(kOutput,2) Info("Merge","Done");
422 void TProofOutputFile::Print(Option_t *)
const
424 Info(
"Print",
"-------------- %s : start (%s) ------------", GetName(), fLocalHost.Data());
425 Info(
"Print",
" dir: %s", fDir.Data());
426 Info(
"Print",
" raw dir: %s", fRawDir.Data());
427 Info(
"Print",
" file name: %s%s", fFileName.Data(), fOptionsAnchor.Data());
429 Info(
"Print",
" run type: create a merged file");
430 Info(
"Print",
" merging option: %s",
431 (fTypeOpt == kLocal) ?
"local copy" :
"keep remote");
434 if ((fTypeOpt & kRegister)) opt +=
"R";
435 if ((fTypeOpt & kOverwrite)) opt +=
"O";
436 if ((fTypeOpt & kVerify)) opt +=
"V";
437 Info(
"Print",
" run type: create dataset (name: '%s', opt: '%s')",
438 GetTitle(), opt.Data());
440 Info(
"Print",
" output file name: %s", fOutputFileName.Data());
441 Info(
"Print",
" ordinal: %s", fWorkerOrdinal.Data());
442 Info(
"Print",
"-------------- %s : done -------------", GetName());
450 void TProofOutputFile::NotifyError(
const char *msg)
454 gProofServ->SendAsynMessage(msg);
458 Info(
"NotifyError",
"called with empty message");
467 void TProofOutputFile::AddFile(TFileMerger *merger,
const char *path)
469 if (merger && path) {
470 if (!merger->AddFile(path))
471 NotifyError(Form(
"TProofOutputFile::AddFile:"
472 " error from TFileMerger::AddFile(%s)", path));
479 void TProofOutputFile::Unlink(
const char *path)
482 if (!gSystem->AccessPathName(path)) {
483 if (gSystem->Unlink(path) != 0)
484 NotifyError(Form(
"TProofOutputFile::Unlink:"
485 " error from TSystem::Unlink(%s)", path));
493 TFileCollection *TProofOutputFile::GetFileCollection()
496 fDataSet =
new TFileCollection(GetTitle());
503 TFileMerger *TProofOutputFile::GetFileMerger(Bool_t local)
506 fMerger =
new TFileMerger(local, fMergeHistosOneGo);
515 Int_t TProofOutputFile::AssertDir(
const char *dirpath)
517 TString existsPath(dirpath);
519 while (existsPath !=
"/" && existsPath !=
"." && gSystem->AccessPathName(existsPath)) {
520 subPaths.AddFirst(
new TObjString(gSystem->BaseName(existsPath)));
521 existsPath = gSystem->DirName(existsPath);
523 subPaths.SetOwner(kTRUE);
525 if (gSystem->GetPathInfo(existsPath, st) == 0) {
526 TString xpath = existsPath;
527 TIter nxp(&subPaths);
529 while ((os = (TObjString *) nxp())) {
530 xpath += TString::Format(
"/%s", os->GetName());
531 if (gSystem->mkdir(xpath, kTRUE) == 0) {
532 if (gSystem->Chmod(xpath, (UInt_t) st.fMode) != 0)
533 ::Warning(
"TProofOutputFile::AssertDir",
"problems setting mode on '%s'", xpath.Data());
535 ::Error(
"TProofOutputFile::AssertDir",
"problems creating path '%s'", xpath.Data());
540 ::Warning(
"TProofOutputFile::AssertDir",
"could not get info for path '%s': will only try to create"
541 " the full path w/o trying to set the mode", existsPath.Data());
542 if (gSystem->mkdir(existsPath, kTRUE) != 0) {
543 ::Error(
"TProofOutputFile::AssertDir",
"problems creating path '%s'", existsPath.Data());