#include "TError.h"
#include "TObjString.h"
#include "TUrl.h"
#include "TXNetFileStager.h"
#include "TXNetSystem.h"
#include "TFileCollection.h"
#include "TStopwatch.h"
#include "TFileInfo.h"
TXNetFileStager::TXNetFileStager(const char *url) : TFileStager("xrd")
{
fSystem = 0;
if (url && strlen(url) > 0) {
GetPrefix(url, fPrefix);
fSystem = new TXNetSystem(fPrefix);
}
}
TXNetFileStager::~TXNetFileStager()
{
if (fSystem)
delete fSystem;
fSystem = 0;
fPrefix = "";
}
Bool_t TXNetFileStager::IsStaged(const char *path)
{
if (!IsValid()) {
GetPrefix(path, fPrefix);
fSystem = new TXNetSystem(path);
}
if (IsValid()) {
TString p(path);
if (!p.BeginsWith("root:"))
p.Insert(0, fPrefix);
return (fSystem->IsOnline(p));
}
Warning("IsStaged","TXNetSystem not initialized");
return kFALSE;
}
Bool_t TXNetFileStager::Stage(TCollection *paths, Option_t *opt)
{
if (IsValid()) {
UChar_t o = 8;
UChar_t p = 0;
if (opt && strlen(opt) > 0) {
TString xo(opt), io;
Ssiz_t from = 0;
while (xo.Tokenize(io, from, "[ ,|]")) {
if (io.Contains("option=")) {
io.ReplaceAll("option=","");
if (io.IsDigit()) {
Int_t i = io.Atoi();
if (i >= 0 && i <= 255)
o = (UChar_t) i;
}
}
if (io.Contains("priority=")) {
io.ReplaceAll("priority=","");
if (io.IsDigit()) {
Int_t i = io.Atoi();
if (i >= 0 && i <= 255)
p = (UChar_t) i;
}
}
}
}
return fSystem->Prepare(paths, o, p);
}
Warning("Stage","TXNetSystem not initialized");
return kFALSE;
}
Bool_t TXNetFileStager::Stage(const char *path, Option_t *opt)
{
if (!IsValid()) {
GetPrefix(path, fPrefix);
fSystem = new TXNetSystem(path);
}
if (IsValid()) {
UChar_t o = 8;
UChar_t p = 0;
TString xo(opt), io;
Ssiz_t from = 0;
while (xo.Tokenize(io, from, "[ ,|]")) {
if (io.Contains("option=")) {
io.ReplaceAll("option=","");
if (io.IsDigit()) {
Int_t i = io.Atoi();
if (i >= 0 && i <= 255)
o = (UChar_t) i;
}
}
if (io.Contains("priority=")) {
io.ReplaceAll("priority=","");
if (io.IsDigit()) {
Int_t i = io.Atoi();
if (i >= 0 && i <= 255)
p = (UChar_t) i;
}
}
}
TString pp(path);
if (!pp.BeginsWith("root:"))
pp.Insert(0, fPrefix);
return fSystem->Prepare(pp, o, p);
}
Warning("Stage","TXNetSystem not initialized");
return kFALSE;
}
void TXNetFileStager::GetPrefix(const char *url, TString &pfx)
{
if (gDebug > 1)
::Info("TXNetFileStager::GetPrefix", "enter: %s", url);
TUrl u(url);
pfx = Form("%s://", u.GetProtocol());
if (strlen(u.GetUser()) > 0)
pfx += Form("%s@", u.GetUser());
pfx += u.GetHost();
if (u.GetPort() != TUrl("root://host").GetPort())
pfx += Form(":%d", u.GetPort());
pfx += "/";
if (gDebug > 1)
::Info("TXNetFileStager::GetPrefix", "found prefix: %s", pfx.Data());
}
void TXNetFileStager::Print(Option_t *) const
{
Printf("+++ stager: %s %s", GetName(), fPrefix.Data());
}
Int_t TXNetFileStager::Locate(const char *path, TString &eurl)
{
if (!IsValid()) {
GetPrefix(path, fPrefix);
fSystem = new TXNetSystem(path);
}
if (IsValid())
return fSystem->Locate(path, eurl);
return -1;
}
Int_t TXNetFileStager::LocateCollection(TFileCollection *fc,
Bool_t addDummyUrl)
{
if (!fc) {
Error("Locate", "No input collection given!");
return -1;
}
Int_t count = 0;
TStopwatch ts;
Double_t timeTaken_s;
TFileInfo *fi;
Int_t rv = fSystem->Prepare(fc->GetList(), 0, 0, NULL);
TIter it(fc->GetList());
timeTaken_s = ts.RealTime();
if (gDebug > 0) {
Info("Locate", "Bulk xprep done in %.1lfs (returned %d)",
ts.RealTime(), rv);
}
ts.Start();
TString surl, endp;
while ((fi = dynamic_cast<TFileInfo *>(it.Next())) != NULL) {
surl = fi->GetCurrentUrl()->GetUrl();
if (!IsValid()) {
GetPrefix(surl.Data(), fPrefix);
if (gDebug > 0) {
Info("Locate", "Stager non initialized, doing it now for %s",
fPrefix.Data());
}
fSystem = new TXNetSystem(surl.Data());
}
if (fSystem->Locate(surl.Data(), endp)) {
fi->ResetBit(TFileInfo::kStaged);
if (addDummyUrl)
fi->AddUrl("noop://none", kTRUE);
if (gDebug > 1)
Info("Locate", "Not found: %s", surl.Data());
}
else {
fi->SetBit(TFileInfo::kStaged);
if (surl != endp) {
fi->AddUrl(endp.Data(), kTRUE);
}
else if (addDummyUrl) {
fi->AddUrl("noop://redir", kTRUE);
}
if (gDebug > 1)
Info("Locate", "Found: %s --> %s", surl.Data(), endp.Data());
}
count++;
}
timeTaken_s += ts.RealTime();
if (gDebug > 0) {
Info("Locate", "All locates finished in %.1lfs", ts.RealTime());
Info("Locate", "Mass prepare and locates took %.1lfs", timeTaken_s);
}
return count;
}
Bool_t TXNetFileStager::Matches(const char *s)
{
if (IsValid()) {
TString pfx;
GetPrefix(s, pfx);
return ((fPrefix == pfx) ? kTRUE : kFALSE);
}
return kFALSE;
}