33 #include <sys/types.h>
38 #if defined(R__SUN) || defined(R__HPUX) || \
39 defined(R__AIX) || defined(R__LINUX) || defined(R__SOLARIS) || \
40 defined(R__HIUX) || defined(R__FBSD) || defined(R__MACOSX) || \
41 defined(R__HURD) || defined(R__OBSD)
50 static const char*
const DCACHE_PREFIX =
"dcache:";
51 static const size_t DCACHE_PREFIX_LEN = strlen(DCACHE_PREFIX);
52 static const char*
const DCAP_PREFIX =
"dcap:";
53 static const size_t DCAP_PREFIX_LEN = strlen(DCAP_PREFIX);
56 ClassImp(TDCacheFile);
71 TDCacheFile::TDCacheFile(
const char *path, Option_t *option,
72 const char *ftitle, Int_t compress):
73 TFile(path,
"NET", ftitle, compress)
75 TString pathString = GetDcapPath(path);
76 path = pathString.Data();
85 Bool_t create = (fOption ==
"CREATE") ? kTRUE : kFALSE;
86 Bool_t recreate = (fOption ==
"RECREATE") ? kTRUE : kFALSE;
87 Bool_t update = (fOption ==
"UPDATE") ? kTRUE : kFALSE;
88 Bool_t read = (fOption ==
"READ") ? kTRUE : kFALSE;
89 if (!create && !recreate && !update && !read) {
97 const char *fnameWithPrefix;
99 if (!strncmp(path, DCAP_PREFIX, DCAP_PREFIX_LEN)) {
100 fnameWithPrefix = fname = path;
104 if ((tname = gSystem->ExpandPathName(path))) {
106 stmp2 = DCACHE_PREFIX;
110 fnameWithPrefix = stmp2;
112 Error(
"TDCacheFile",
"error expanding path %s", path);
118 if (!gSystem->AccessPathName(fnameWithPrefix, kFileExists))
124 if (create && !gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
125 Error(
"TDCacheFile",
"file %s already exists", fname);
129 if (gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
133 if (update && gSystem->AccessPathName(fnameWithPrefix, kWritePermission)) {
134 Error(
"TDCacheFile",
"no write permission, could not open file %s", fname);
142 if (create || update) {
144 fD = SysOpen(fname, O_RDWR | O_CREAT, 0644);
146 fD = SysOpen(fname, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
149 SysError(
"TDCacheFile",
"file %s can not be opened", fname);
155 fD = SysOpen(fname, O_RDONLY, 0644);
157 fD = SysOpen(fname, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
160 if (gSystem->AccessPathName(fnameWithPrefix, kFileExists)) {
161 Error(
"TDCacheFile",
"file %s does not exist", fname);
164 if (gSystem->AccessPathName(fnameWithPrefix, kReadPermission)) {
165 Error(
"TDCacheFile",
"no read permission, could not open file %s", fname);
168 SysError(
"TDCacheFile",
"file %s can not be opened for reading", fname);
178 int dcache_RAHEAD_SIZE = RAHEAD_BUFFER_SIZE;
179 const char *DCACHE_RA_BUFFER = gSystem->Getenv(
"DCACHE_RA_BUFFER");
180 if (DCACHE_RA_BUFFER) {
181 int ra_buffer = atoi(DCACHE_RA_BUFFER);
182 dcache_RAHEAD_SIZE = ra_buffer<=0 ? dcache_RAHEAD_SIZE : ra_buffer;
184 dc_setBufferSize(fD, dcache_RAHEAD_SIZE);
202 TDCacheFile::~TDCacheFile()
211 Bool_t TDCacheFile::ReadBuffer(
char *buf, Int_t len)
214 if ((st = ReadBufferViaCache(buf, len))) {
220 return TFile::ReadBuffer(buf, len);
227 Bool_t TDCacheFile::ReadBuffer(
char *buf, Long64_t pos, Int_t len)
231 if ((st = ReadBufferViaCache(buf, len))) {
237 return TFile::ReadBuffer(buf, pos, len);
247 Bool_t TDCacheFile::ReadBuffers(
char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
253 vector = (iovec2 *)malloc(
sizeof(iovec2)*nbuf);
256 for (Int_t i = 0; i < nbuf; i++) {
257 vector[i].buf = &buf[total_len];
258 vector[i].offset = pos[i] + fArchiveOffset;
259 vector[i].len = len[i];
263 Int_t rc = dc_readv2(fD, vector, nbuf);
267 fBytesRead += total_len;
268 SetFileBytesRead(GetFileBytesRead() + total_len);
277 Bool_t result = kTRUE;
278 TFileCacheRead *old = fCacheRead;
281 Long64_t low = pos[0];
282 Long64_t high = pos[nbuf-1] + len[nbuf-1] - pos[0];
285 for(Int_t j=0; j < nbuf; j++) {
289 if ( total && high / total < 10 ) {
291 char *temp =
new char[high];
293 result = ReadBuffer(temp,high);
296 for (Int_t i = 0; i < nbuf; i++) {
297 memcpy(&buf[k], &(temp[pos[i]-pos[0]]), len[i]);
306 for (Int_t i = 0; i < nbuf; i++) {
308 result = ReadBuffer(&buf[k], len[i]);
323 Bool_t TDCacheFile::WriteBuffer(
const char *buf, Int_t len)
325 if (!IsOpen() || !fWritable)
return kTRUE;
328 if ((st = WriteBufferViaCache(buf, len))) {
334 return TFile::WriteBuffer(buf, len);
340 Bool_t TDCacheFile::Stage(
const char *path, UInt_t after,
const char *location)
342 TString pathString = GetDcapPath(path);
343 path = pathString.Data();
347 if (dc_stage(path, after, location) == 0)
351 gSystem->SetErrorStr(dc_strerror(dc_errno));
361 Bool_t TDCacheFile::CheckFile(
const char *path,
const char *location)
363 TString pathString = GetDcapPath(path);
364 path = pathString.Data();
368 if (dc_check(path, location) == 0)
372 gSystem->SetErrorStr(dc_strerror(dc_errno));
380 void TDCacheFile::SetOpenTimeout(UInt_t n)
382 dc_setOpenTimeout(n);
388 void TDCacheFile::SetOnError(EOnErrorAction a)
396 void TDCacheFile::SetReplyHostName(
const char *host_name)
398 dc_setReplyHostName((
char*)host_name);
404 const char *TDCacheFile::GetDcapVersion()
406 return getDcapVersion();
412 Int_t TDCacheFile::SysOpen(
const char *pathname, Int_t flags, UInt_t mode)
419 dc_setClientActive();
423 Int_t rc = dc_open(pathname, flags, (Int_t) mode);
427 gSystem->SetErrorStr(dc_strerror(dc_errno));
436 Int_t TDCacheFile::SysClose(Int_t fd)
440 Int_t rc = dc_close(fd);
444 gSystem->SetErrorStr(dc_strerror(dc_errno));
453 Int_t TDCacheFile::SysRead(Int_t fd,
void *buf, Int_t len)
457 Int_t rc = dc_read(fd, buf, len);
461 gSystem->SetErrorStr(dc_strerror(dc_errno));
470 Int_t TDCacheFile::SysWrite(Int_t fd,
const void *buf, Int_t len)
474 Int_t rc = dc_write(fd, (
char *)buf, len);
478 gSystem->SetErrorStr(dc_strerror(dc_errno));
487 Long64_t TDCacheFile::SysSeek(Int_t fd, Long64_t offset, Int_t whence)
491 Long64_t rc = dc_lseek64(fd, offset, whence);
495 gSystem->SetErrorStr(dc_strerror(dc_errno));
506 Int_t TDCacheFile::SysSync(Int_t fd)
514 gSystem->SetErrorStr(dc_strerror(dc_errno));
530 Int_t TDCacheFile::SysStat(Int_t, Long_t *
id, Long64_t *size,
531 Long_t *flags, Long_t *modtime)
536 struct stat64 & statbuf = fStatBuffer;
538 if (fOption !=
"READ" || !fStatCached) {
542 const char *path = GetName();
543 TString pathString = GetDcapPath(path);
544 path = pathString.Data();
546 if (path && (dc_stat64(path, &statbuf) >= 0)) {
553 *
id = (statbuf.st_dev << 24) + statbuf.st_ino;
555 *size = statbuf.st_size;
557 *modtime = statbuf.st_mtime;
560 if (statbuf.st_mode & ((S_IEXEC)|(S_IEXEC>>3)|(S_IEXEC>>6)))
562 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
564 if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
565 (statbuf.st_mode & S_IFMT) != S_IFDIR)
576 void TDCacheFile::ResetErrno()
const
579 TSystem::ResetErrno();
587 TString TDCacheFile::GetDcapPath(
const char *path)
590 while (!strncmp(path, DCACHE_PREFIX, DCACHE_PREFIX_LEN)) {
591 path += DCACHE_PREFIX_LEN;
595 TString pathString(url.GetUrl());
598 if(!strncmp(url.GetProtocol(),
"file", 4) || !strcmp(url.GetHost(),
"")){
599 pathString = url.GetFile();
609 TDCacheSystem::TDCacheSystem() : TSystem(
"-DCache",
"DCache Helper System")
620 int TDCacheSystem::MakeDirectory(
const char *path)
624 TString pathString = TDCacheFile::GetDcapPath(path);
625 path = pathString.Data();
627 rc = dc_mkdir(path, 0755);
630 gSystem->SetErrorStr(dc_strerror(dc_errno));
639 void *TDCacheSystem::OpenDirectory(
const char *path)
642 TString pathString = TDCacheFile::GetDcapPath(path);
643 path = pathString.Data();
645 fDirp = dc_opendir(path);
648 gSystem->SetErrorStr(dc_strerror(dc_errno));
657 void TDCacheSystem::FreeDirectory(
void * dirp)
662 rc = dc_closedir((DIR *)dirp);
665 gSystem->SetErrorStr(dc_strerror(dc_errno));
675 const char *TDCacheSystem::GetDirEntry(
void * dirp)
680 ent = dc_readdir((DIR *)dirp);
683 gSystem->SetErrorStr(dc_strerror(dc_errno));
686 return !ent ? 0 : ent->d_name;
694 Bool_t TDCacheSystem::AccessPathName(
const char *path, EAccessMode mode)
696 TString pathString = TDCacheFile::GetDcapPath(path);
697 path = pathString.Data();
699 return dc_access(path, mode);
708 int TDCacheSystem::GetPathInfo(
const char *path, FileStat_t &buf)
710 TString pathString = TDCacheFile::GetDcapPath(path);
711 path = pathString.Data();
715 if (path && (dc_stat64(path, &sbuf) >= 0)) {
717 buf.fDev = sbuf.st_dev;
718 buf.fIno = sbuf.st_ino;
719 buf.fMode = sbuf.st_mode;
720 buf.fUid = sbuf.st_uid;
721 buf.fGid = sbuf.st_gid;
722 buf.fSize = sbuf.st_size;
723 buf.fMtime = sbuf.st_mtime;
724 buf.fIsLink = kFALSE;