00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "TFileCollection.h"
00024 #include "THashList.h"
00025 #include "TFileInfo.h"
00026 #include "TIterator.h"
00027 #include "TMap.h"
00028 #include "TObjString.h"
00029 #include "TUri.h"
00030 #include "TUrl.h"
00031 #include "TSystem.h"
00032 #include "Riostream.h"
00033 #include "TRegexp.h"
00034 #include "TError.h"
00035
00036
00037 ClassImp(TFileCollection)
00038
00039
00040 TFileCollection::TFileCollection(const char *name, const char *title,
00041 const char *textfile, Int_t nfiles, Int_t firstfile)
00042 : TNamed(name, title), fList(0), fMetaDataList(0), fDefaultTree(),
00043 fTotalSize(0), fNFiles(0), fNStagedFiles(0), fNCorruptFiles(0)
00044 {
00045
00046
00047
00048
00049 fList = new THashList();
00050 fList->SetOwner();
00051
00052 fMetaDataList = new TList;
00053 fMetaDataList->SetOwner();
00054
00055 AddFromFile(textfile, nfiles, firstfile);
00056 }
00057
00058
00059 TFileCollection::~TFileCollection()
00060 {
00061
00062
00063 delete fList;
00064 delete fMetaDataList;
00065 }
00066
00067
00068 Int_t TFileCollection::Add(TFileInfo *info)
00069 {
00070
00071
00072 if (fList && info) {
00073 if (!fList->FindObject(info->GetName())) {
00074 fList->Add(info);
00075 return 1;
00076 } else {
00077 Warning("Add", "file: '%s' already in the list - ignoring",
00078 info->GetCurrentUrl()->GetUrl());
00079 }
00080 }
00081 return 0;
00082 }
00083
00084
00085 Int_t TFileCollection::Add(TFileCollection *coll)
00086 {
00087
00088
00089 if (fList && coll && coll->GetList()) {
00090 TIter nxfi(coll->GetList());
00091 TFileInfo *fi = 0;
00092 while ((fi = (TFileInfo *) nxfi())) {
00093 fList->Add(new TFileInfo(*fi));
00094 }
00095 return 1;
00096 } else {
00097 return 0;
00098 }
00099 }
00100
00101
00102 Int_t TFileCollection::AddFromFile(const char *textfile, Int_t nfiles, Int_t firstfile)
00103 {
00104
00105
00106
00107
00108
00109
00110 if (!fList)
00111 return 0;
00112
00113 Int_t nf = 0;
00114 TString fn(textfile);
00115 if (!fn.IsNull() && !gSystem->ExpandPathName(fn)) {
00116 ifstream f;
00117 f.open(fn);
00118 if (f.is_open()) {
00119 Bool_t all = (nfiles <= 0) ? kTRUE : kFALSE;
00120 Int_t ff = (!all && (firstfile < 1)) ? 1 : firstfile;
00121 Int_t nn = 0;
00122 while (f.good() && (all || nf < nfiles)) {
00123 TString line;
00124 line.ReadToDelim(f);
00125
00126 if (!line.IsWhitespace() && !line.BeginsWith("#")) {
00127 nn++;
00128 if (all || nn >= ff) {
00129 fList->Add(new TFileInfo(line));
00130 nf++;
00131 }
00132 }
00133 }
00134 f.close();
00135 Update();
00136 } else
00137 Error("AddFromFile", "unable to open file %s (%s)", textfile, fn.Data());
00138 }
00139 return nf;
00140 }
00141
00142
00143 Int_t TFileCollection::Add(const char *dir)
00144 {
00145
00146
00147
00148
00149
00150
00151 Int_t nf = 0;
00152
00153 if (!fList)
00154 return nf;
00155
00156 if (!dir || !*dir) {
00157 Error("Add", "input dir undefined");
00158 return nf;
00159 }
00160
00161 FileStat_t st;
00162 FileStat_t tmp;
00163 TString baseDir = gSystem->DirName(dir);
00164
00165 if (gSystem->GetPathInfo(dir, st) == 0 ||
00166 gSystem->GetPathInfo(baseDir, tmp) == 0) {
00167
00168 if (R_ISREG(st.fMode)) {
00169
00170 TFileInfo *info = new TFileInfo(dir);
00171 info->SetBit(TFileInfo::kStaged);
00172 Add(info);
00173 nf++;
00174 Update();
00175 return nf;
00176 } else {
00177 void *dataSetDir = gSystem->OpenDirectory(gSystem->DirName(dir));
00178 if (!dataSetDir) {
00179
00180 Error("Add", "directory %s cannot be opened",
00181 gSystem->DirName(dir));
00182 } else {
00183 const char *ent;
00184 TString filesExp(TString("^") + gSystem->BaseName(dir) + "$");
00185 filesExp.ReplaceAll("*",".*");
00186 TRegexp rg(filesExp);
00187 while ((ent = gSystem->GetDirEntry(dataSetDir))) {
00188 TString entryString(ent);
00189 if (entryString.Index(rg) != kNPOS) {
00190
00191 TString fn = gSystem->DirName(dir);
00192 fn += "/";
00193 fn += ent;
00194 gSystem->GetPathInfo(fn, st);
00195 if (R_ISREG(st.fMode)) {
00196
00197 TFileInfo *info = new TFileInfo(fn);
00198 info->SetBit(TFileInfo::kStaged);
00199 Add(info);
00200 nf++;
00201 }
00202 }
00203 }
00204
00205 gSystem->FreeDirectory(dataSetDir);
00206 Update();
00207 }
00208 }
00209 }
00210 return nf;
00211 }
00212
00213
00214 Int_t TFileCollection::RemoveDuplicates()
00215 {
00216
00217
00218
00219 THashList *hl = new THashList;
00220 hl->SetOwner();
00221
00222 Int_t n0 = fList->GetSize();
00223 TIter nxfi(fList);
00224 TFileInfo *fi = 0;
00225 while ((fi = (TFileInfo *)nxfi())) {
00226 if (!(hl->FindObject(fi->GetUUID()->AsString()))) {
00227
00228 fList->Remove(fi);
00229 fi->SetName(fi->GetUUID()->AsString());
00230 hl->Add(fi);
00231 }
00232 }
00233 delete fList;
00234 fList = hl;
00235
00236 Int_t nr = n0 - fList->GetSize();
00237 if (nr > 0)
00238 Info("RemoveDuplicates", "%d duplicates found and removed", nr);
00239
00240 return nr;
00241 }
00242
00243
00244 TFileCollection *TFileCollection::GetStagedSubset()
00245 {
00246
00247
00248 if (!fList)
00249 return 0;
00250
00251 TFileCollection *subset = new TFileCollection(GetName(), GetTitle());
00252
00253 TIter iter(fList);
00254 TFileInfo *fileInfo = 0;
00255 while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next()))) {
00256 if (fileInfo->TestBit(TFileInfo::kStaged) && !fileInfo->TestBit(TFileInfo::kCorrupted))
00257 subset->Add(fileInfo);
00258 }
00259
00260 subset->Update();
00261
00262 return subset;
00263 }
00264
00265
00266 Long64_t TFileCollection::Merge(TCollection *li)
00267 {
00268
00269
00270 if (!li) return 0;
00271 if (li->IsEmpty()) return 0;
00272
00273
00274
00275 Bool_t mustCleanup = TestBit(kMustCleanup);
00276 if (mustCleanup) ResetBit(kMustCleanup);
00277 TList inlist;
00278 TFileCollection* hclone = (TFileCollection*)Clone("FirstClone");
00279 if (mustCleanup) SetBit(kMustCleanup);
00280 R__ASSERT(hclone);
00281
00282
00283 inlist.Add(hclone);
00284 inlist.AddAll(li);
00285
00286 Long64_t nentries=0;
00287 TIter next(&inlist);
00288 while (TObject *o = next()) {
00289 TFileCollection* coll = dynamic_cast<TFileCollection*> (o);
00290 if (!coll) {
00291 Error("Add","Attempt to add object of class: %s to a %s",
00292 o->ClassName(),this->ClassName());
00293 return -1;
00294 }
00295 Add(coll);
00296 nentries++;
00297 }
00298
00299
00300 inlist.Remove(hclone);
00301 delete hclone;
00302 return nentries;
00303
00304 }
00305
00306
00307 Int_t TFileCollection::Update(Long64_t avgsize)
00308 {
00309
00310
00311
00312
00313
00314
00315
00316
00317 if (!fList)
00318 return -1;
00319
00320 Int_t rc = 0;
00321
00322 fTotalSize = 0;
00323 fNStagedFiles = 0;
00324 fNCorruptFiles = 0;
00325
00326
00327
00328 TIter nxm(fMetaDataList);
00329 TFileInfoMeta *m = 0;
00330 while ((m = (TFileInfoMeta *)nxm())) {
00331 if (!(m->TestBit(TFileInfoMeta::kExternal))) {
00332 fMetaDataList->Remove(m);
00333 delete m;
00334 }
00335 }
00336
00337 fNFiles = fList->GetEntries();
00338
00339 TIter iter(fList);
00340 TFileInfo *fileInfo = 0;
00341 while ((fileInfo = dynamic_cast<TFileInfo*> (iter.Next()))) {
00342
00343 if (fileInfo->GetSize() > 0) {
00344 fTotalSize += fileInfo->GetSize();
00345 } else {
00346 rc = 1;
00347 if (avgsize > 0) {
00348 rc = 2;
00349 fTotalSize += avgsize;
00350 }
00351 }
00352
00353 if (fileInfo->TestBit(TFileInfo::kStaged) && !fileInfo->TestBit(TFileInfo::kCorrupted)) {
00354 fNStagedFiles++;
00355
00356 if (fileInfo->GetMetaDataList()) {
00357 TIter metaDataIter(fileInfo->GetMetaDataList());
00358
00359 TObject *obj = 0;
00360 while ((obj = metaDataIter.Next())) {
00361 TFileInfoMeta *metaData = dynamic_cast<TFileInfoMeta*>(obj);
00362 if (!metaData)
00363 continue;
00364 if (!metaData->IsTree())
00365 continue;
00366
00367
00368 TFileInfoMeta *metaDataSum = dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(metaData->GetName()));
00369 Bool_t newObj = kFALSE;
00370 if (!metaDataSum) {
00371
00372 metaDataSum = new TFileInfoMeta(metaData->GetName(), metaData->GetTitle());
00373 fMetaDataList->Add(metaDataSum);
00374 newObj = kTRUE;
00375 }
00376
00377
00378 if (newObj)
00379 metaDataSum->SetEntries(metaData->GetEntries());
00380 else
00381 metaDataSum->SetEntries(metaDataSum->GetEntries() + metaData->GetEntries());
00382 }
00383 }
00384 }
00385 if (fileInfo->TestBit(TFileInfo::kCorrupted))
00386 fNCorruptFiles++;
00387 }
00388
00389
00390 return rc;
00391 }
00392
00393
00394 void TFileCollection::Print(Option_t *option) const
00395 {
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 Printf("TFileCollection %s - %s contains: %lld files with a size of"
00406 " %lld bytes, %.1f %% staged - default tree name: '%s'",
00407 GetName(), GetTitle(), fNFiles, fTotalSize, GetStagedPercentage(),
00408 GetDefaultTreeName());
00409
00410 TString opt(option);
00411 if (opt.Contains("M", TString::kIgnoreCase)) {
00412 Printf("The files contain the following trees:");
00413
00414 TIter metaDataIter(fMetaDataList);
00415 TFileInfoMeta* metaData = 0;
00416 while ((metaData = dynamic_cast<TFileInfoMeta*>(metaDataIter.Next()))) {
00417 if (!metaData->IsTree())
00418 continue;
00419
00420 Printf("Tree %s: %lld events", metaData->GetName(), metaData->GetEntries());
00421 }
00422 }
00423
00424 if (fList && opt.Contains("F", TString::kIgnoreCase)) {
00425 Printf("The collection contains the following files:");
00426 if (!opt.Contains("L") && !fDefaultTree.IsNull())
00427 opt += TString::Format(" T:%s", fDefaultTree.Data());
00428 fList->Print(opt);
00429 }
00430 }
00431
00432
00433 void TFileCollection::SetAnchor(const char *anchor)
00434 {
00435
00436
00437 if (!fList)
00438 return;
00439
00440 TIter iter(fList);
00441 TFileInfo *fileInfo = 0;
00442 while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next()))) {
00443 fileInfo->ResetUrl();
00444 TUrl *url = 0;
00445 while ((url = fileInfo->NextUrl()))
00446 url->SetAnchor(anchor);
00447 fileInfo->ResetUrl();
00448 }
00449 }
00450
00451
00452 void TFileCollection::SetBitAll(UInt_t f)
00453 {
00454
00455
00456 if (!fList)
00457 return;
00458
00459 TIter iter(fList);
00460 TFileInfo *fileInfo = 0;
00461 while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
00462 fileInfo->SetBit(f);
00463 }
00464
00465
00466 void TFileCollection::ResetBitAll(UInt_t f)
00467 {
00468
00469
00470 if (!fList)
00471 return;
00472
00473 TIter iter(fList);
00474 TFileInfo *fileInfo = 0;
00475 while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
00476 fileInfo->ResetBit(f);
00477 }
00478
00479
00480 const char *TFileCollection::GetDefaultTreeName() const
00481 {
00482
00483
00484
00485
00486 if (fDefaultTree.Length() > 0)
00487 return fDefaultTree;
00488
00489 TIter metaDataIter(fMetaDataList);
00490 TFileInfoMeta *metaData = 0;
00491 while ((metaData = dynamic_cast<TFileInfoMeta*>(metaDataIter.Next()))) {
00492 if (!metaData->IsTree())
00493 continue;
00494 return metaData->GetName();
00495 }
00496 return 0;
00497 }
00498
00499
00500 Long64_t TFileCollection::GetTotalEntries(const char *tree) const
00501 {
00502
00503
00504
00505
00506 if (!tree || !*tree) {
00507 tree = GetDefaultTreeName();
00508 if (!tree)
00509 return -1;
00510 }
00511
00512 TFileInfoMeta *metaData = dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(tree));
00513 if (!metaData)
00514 return -1;
00515
00516 return metaData->GetEntries();
00517 }
00518
00519
00520 TFileInfoMeta *TFileCollection::GetMetaData(const char *meta) const
00521 {
00522
00523
00524
00525 if (!meta || !*meta)
00526 return 0;
00527
00528 return dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(meta));
00529 }
00530
00531
00532 void TFileCollection::SetDefaultMetaData(const char *meta)
00533 {
00534
00535
00536
00537 TFileInfoMeta *fim = GetMetaData(meta);
00538 if (fim) {
00539 fMetaDataList->Remove(fim);
00540 fMetaDataList->AddFirst(fim);
00541 }
00542 }
00543
00544
00545 void TFileCollection::RemoveMetaData(const char *meta)
00546 {
00547
00548
00549
00550 if (fList) {
00551 TIter iter(fList);
00552 TFileInfo *fileInfo = 0;
00553 while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
00554 fileInfo->RemoveMetaData(meta);
00555 }
00556
00557 if (meta) {
00558 TObject* obj = fMetaDataList->FindObject("meta");
00559 if (obj) {
00560 fMetaDataList->Remove(obj);
00561 delete obj;
00562 }
00563 } else
00564 fMetaDataList->Clear();
00565 }
00566
00567
00568 void TFileCollection::Sort()
00569 {
00570
00571
00572 if (!fList)
00573 return;
00574
00575 fList->Sort();
00576 }
00577
00578
00579 TObjString *TFileCollection::ExportInfo(const char *name, Int_t popt)
00580 {
00581
00582
00583
00584
00585 TString treeInfo;
00586 if (GetDefaultTreeName()) {
00587 TFileInfoMeta* meta = GetMetaData(GetDefaultTreeName());
00588 if (popt == 1) {
00589 treeInfo = GetDefaultTreeName();
00590 if (meta)
00591 treeInfo += TString::Format(", %lld entries", meta->GetEntries());
00592 TFileInfoMeta *frac = GetMetaData("/FractionOfTotal");
00593 if (frac)
00594 treeInfo += TString::Format(", %3.1f %% of total", frac->GetEntries() / 10.);
00595 } else {
00596 treeInfo.Form(" %s ", GetDefaultTreeName());
00597 if (treeInfo.Length() > 14) treeInfo.Replace(13, 1, '>');
00598 treeInfo.Resize(14);
00599 if (meta) {
00600 if (meta->GetEntries() > 99999999) {
00601 treeInfo += TString::Format("| %8lld ", meta->GetEntries());
00602 } else {
00603 treeInfo += TString::Format("| %8.4g ", (Double_t) meta->GetEntries());
00604 }
00605 }
00606 }
00607 } else {
00608 treeInfo = " N/A";
00609 }
00610 if (popt == 0) treeInfo.Resize(25);
00611
00612
00613 const char *unit[4] = {"kB", "MB", "GB", "TB"};
00614 Int_t k = 0;
00615 Long64_t refsz = 1024;
00616 Long64_t xsz = (Long64_t) (GetTotalSize() / refsz);
00617 while (xsz > 1024 && k < 3) {
00618 k++;
00619 refsz *= 1024;
00620 xsz = (Long64_t) (GetTotalSize() / refsz);
00621 }
00622
00623
00624 TString dsname(name);
00625 if (dsname.IsNull()) dsname = GetName();
00626
00627
00628 TObjString *outs = 0;
00629 if (popt == 1) {
00630 outs = new TObjString(Form("%s %lld files, %lld %s, staged %d %%, tree: %s", dsname.Data(),
00631 GetNFiles(), xsz, unit[k],
00632 (Int_t)GetStagedPercentage(), treeInfo.Data()));
00633 } else {
00634 outs = new TObjString(Form("%s| %7lld |%s| %5lld %s | %3d %%", dsname.Data(),
00635 GetNFiles(), treeInfo.Data(), xsz, unit[k],
00636 (Int_t)GetStagedPercentage()));
00637 }
00638
00639 return outs;
00640 }
00641
00642
00643 TFileCollection *TFileCollection::GetFilesOnServer(const char *server)
00644 {
00645
00646
00647
00648 TFileCollection *fc = (TFileCollection *)0;
00649
00650
00651 if (!server || strlen(server) <= 0) {
00652 Info("GetFilesOnServer", "server undefined - do nothing");
00653 return fc;
00654 }
00655
00656
00657 if (!fList || fList->GetSize() <= 0) {
00658 Info("GetFilesOnServer", "the list is empty - do nothing");
00659 return fc;
00660 }
00661
00662
00663 TUri uri(server);
00664 TString srv, scheme("root"), port;
00665 if (uri.GetScheme() != "") scheme = uri.GetScheme();
00666 if (uri.GetPort() != "") port.Form(":%s", uri.GetPort().Data());
00667 srv.Form("%s://%s%s", scheme.Data(), TUrl(server).GetHostFQDN(), port.Data());
00668 if (gDebug > 0)
00669 Info("GetFilesOnServer", "searching for files on server: '%s' (input: '%s')", srv.Data(), server);
00670
00671
00672 fc = new TFileCollection(GetName());
00673 TString title;
00674 if (GetTitle() && strlen(GetTitle()) > 0) {
00675 title.Form("%s (subset on server %s)", GetTitle(), srv.Data());
00676 } else {
00677 title.Form("subset of '%s' on server %s", GetName(), srv.Data());
00678 }
00679 fc->SetTitle(title.Data());
00680
00681 fc->SetDefaultTreeName(GetDefaultTreeName());
00682
00683
00684 srv.Insert(0, "^");
00685
00686
00687 TIter nxf(fList);
00688 TFileInfo *fi = 0;
00689 while ((fi = (TFileInfo *)nxf())) {
00690 TUrl *xu = 0;
00691 if ((xu = fi->FindByUrl(srv.Data()))) {
00692
00693 TFileInfo *nfi = new TFileInfo(xu->GetUrl(), fi->GetSize(),
00694 fi->GetUUID() ? fi->GetUUID()->AsString() : 0,
00695 fi->GetMD5() ? fi->GetMD5()->AsString() : 0);
00696 if (fi->GetMetaDataList()) {
00697 TIter nxm(fi->GetMetaDataList());
00698 TFileInfoMeta *md = 0;
00699 while ((md = (TFileInfoMeta *) nxm())) {
00700 nfi->AddMetaData(new TFileInfoMeta(*md));
00701 }
00702 }
00703 if (fi->TestBit(TFileInfo::kStaged)) nfi->SetBit(TFileInfo::kStaged);
00704 if (fi->TestBit(TFileInfo::kCorrupted)) nfi->SetBit(TFileInfo::kCorrupted);
00705 if (gDebug > 1)
00706 Info("GetFilesOnServer", "adding: %s", xu->GetUrl());
00707 fc->Add(nfi);
00708 }
00709 }
00710
00711
00712 if (fc->GetList()->GetSize() <= 0) {
00713 delete fc;
00714 fc = 0;
00715 Info("GetFilesOnServer", "dataset '%s' has no files on server: '%s' (searched for: '%s')",
00716 GetName(), server, srv.Data());
00717 }
00718
00719
00720 if (fc) {
00721 fc->Update();
00722
00723 Long64_t xf = (fc->GetTotalSize() * 1000) / GetTotalSize();
00724 TFileInfoMeta *m = new TFileInfoMeta("FractionOfTotal", "External Info", xf);
00725 m->SetBit(TFileInfoMeta::kExternal);
00726 fc->AddMetaData(m);
00727 }
00728
00729
00730 return fc;
00731 }
00732
00733
00734 TMap *TFileCollection::GetFilesPerServer(const char *exclude)
00735 {
00736
00737
00738
00739 TMap *dsmap = 0;
00740
00741
00742 if (!fList || fList->GetSize() <= 0) {
00743 Info("GetFilesPerServer", "the list is empty - do nothing");
00744 return dsmap;
00745 }
00746
00747
00748 THashList *excl = 0;
00749 if (exclude && strlen(exclude) > 0) {
00750 excl = new THashList;
00751 excl->SetOwner();
00752 TUri uri;
00753 TString srvs(exclude), s, srv, scheme, port;
00754 Int_t from = 0;
00755 while (srvs.Tokenize(s, from, ",")) {
00756 uri.SetUri(s.Data());
00757 scheme = "root";
00758 port = "";
00759 if (uri.GetScheme() != "") scheme = uri.GetScheme();
00760 if (uri.GetPort() != "") port.Form(":%s", uri.GetPort().Data());
00761 srv.Form("%s://%s%s", scheme.Data(), TUrl(s.Data()).GetHostFQDN(), port.Data());
00762
00763 excl->Add(new TObjString(srv.Data()));
00764 }
00765 }
00766
00767
00768 dsmap = new TMap();
00769
00770
00771 TIter nxf(fList);
00772 TFileInfo *fi = 0;
00773 TUri uri;
00774 TString key;
00775 TFileCollection *fc = 0;
00776 while ((fi = (TFileInfo *)nxf())) {
00777
00778 TUrl *curl = fi->GetCurrentUrl();
00779
00780 fi->ResetUrl();
00781 TUrl *xurl = 0;
00782 while ((xurl = fi->NextUrl())) {
00783
00784 key.Form("%s://%s", xurl->GetProtocol(), xurl->GetHostFQDN());
00785
00786 if (excl && excl->FindObject(key.Data())) continue;
00787
00788 if (xurl->GetPort() > 0) {
00789 key += TString::Format(":%d", xurl->GetPort());
00790 if (excl && excl->FindObject(key.Data())) continue;
00791 }
00792
00793 TPair *ent = 0;
00794 if (!(ent = (TPair *) dsmap->FindObject(key.Data()))) {
00795
00796 fc = new TFileCollection(GetName());
00797 TString title;
00798 if (GetTitle() && strlen(GetTitle()) > 0) {
00799 title.Form("%s (subset on server %s)", GetTitle(), key.Data());
00800 } else {
00801 title.Form("subset of '%s' on server %s", GetName(), key.Data());
00802 }
00803 fc->SetTitle(title.Data());
00804
00805 fc->SetDefaultTreeName(GetDefaultTreeName());
00806
00807 dsmap->Add(new TObjString(key.Data()), fc);
00808
00809 if (gDebug > 0)
00810 Info("GetFilesPerServer", "found server: '%s' (fc: %p)", key.Data(), fc);
00811 } else {
00812
00813 fc = (TFileCollection *) ent->Value();
00814 }
00815
00816 TFileInfo *nfi = new TFileInfo(xurl->GetUrl(kTRUE), fi->GetSize(),
00817 fi->GetUUID() ? fi->GetUUID()->AsString() : 0,
00818 fi->GetMD5() ? fi->GetMD5()->AsString() : 0);
00819 if (fi->GetMetaDataList()) {
00820 TIter nxm(fi->GetMetaDataList());
00821 TFileInfoMeta *md = 0;
00822 while ((md = (TFileInfoMeta *) nxm())) {
00823 nfi->AddMetaData(new TFileInfoMeta(*md));
00824 }
00825 }
00826 if (fi->TestBit(TFileInfo::kStaged)) nfi->SetBit(TFileInfo::kStaged);
00827 if (fi->TestBit(TFileInfo::kCorrupted)) nfi->SetBit(TFileInfo::kCorrupted);
00828 fc->Add(nfi);
00829 }
00830
00831 fi->SetCurrentUrl(curl);
00832 }
00833
00834
00835 TIter nxk(dsmap);
00836 TObject *k = 0;
00837 while ((k = nxk()) && (fc = (TFileCollection *) dsmap->GetValue(k))) {
00838 fc->Update();
00839
00840 Long64_t xf = (fc->GetTotalSize() * 1000) / GetTotalSize();
00841 TFileInfoMeta *m = new TFileInfoMeta("FractionOfTotal", "External Info", xf);
00842 m->SetBit(TFileInfoMeta::kExternal);
00843 fc->AddMetaData(m);
00844 }
00845
00846
00847 if (excl) delete excl;
00848
00849
00850 return dsmap;
00851 }
00852
00853
00854 Bool_t TFileCollection::AddMetaData(TObject *meta)
00855 {
00856
00857
00858
00859
00860
00861
00862
00863
00864 if (meta) {
00865 if (!fMetaDataList) {
00866 fMetaDataList = new TList;
00867 fMetaDataList->SetOwner();
00868 }
00869 fMetaDataList->Add(meta);
00870 return kTRUE;
00871 }
00872 return kFALSE;
00873 }