XRootD
Loading...
Searching...
No Matches
XrdPfcInfo.cc
Go to the documentation of this file.
1//----------------------------------------------------------------------------------
2// Copyright (c) 2014 by Board of Trustees of the Leland Stanford, Jr., University
3// Author: Alja Mrak-Tadel, Matevz Tadel, Brian Bockelman
4//----------------------------------------------------------------------------------
5// XRootD is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// XRootD is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
17//----------------------------------------------------------------------------------
18
19#include <sys/file.h>
20#include <assert.h>
21#include <ctime>
22#include <cstring>
23#include <cstdlib>
24#include <sys/stat.h>
25
26#include "XrdOss/XrdOss.hh"
29#include "XrdSys/XrdSysTrace.hh"
30#include "XrdCl/XrdClLog.hh"
32#include "XrdPfcInfo.hh"
33#include "XrdPfc.hh"
34#include "XrdPfcStats.hh"
35#include "XrdPfcTrace.hh"
36
37namespace
38{
39
40struct TraceHeader
41{
42 const char *f_tpf, *f_tdir, *f_tfile , *f_tmsg;
43
44 // tdir is supposed to be '/' terminated. Check can be added in ctor and a bool flag to mark if it is needed.
45 TraceHeader(const char *tpf, const char *tdir, const char *tfile = 0, const char *tmsg = 0) :
46 f_tpf(tpf), f_tdir(tdir), f_tfile(tfile), f_tmsg(tmsg) {}
47};
48
49XrdSysTrace& operator<<(XrdSysTrace& s, const TraceHeader& th)
50{
51 s << th.f_tpf << " " << th.f_tdir;
52 if (th.f_tfile) s << th.f_tfile;
53 if (th.f_tmsg) s << " " << th.f_tmsg;
54 s << " ";
55 return s;
56}
57
58struct FpHelper
59{
60 XrdOssDF *f_fp;
61 off_t f_off;
62 XrdSysTrace *f_trace;
63 const char *m_traceID;
64 const TraceHeader &f_trace_hdr;
65
66 XrdSysTrace* GetTrace() const { return f_trace; }
67
68 FpHelper(XrdOssDF* fp, off_t off, XrdSysTrace *trace, const char *tid, const TraceHeader &thdr) :
69 f_fp(fp), f_off(off), f_trace(trace), m_traceID(tid), f_trace_hdr(thdr)
70 {}
71
72 // Returns true on error
73 bool ReadRaw(void *buf, ssize_t size, bool warnp = true)
74 {
75 ssize_t ret = f_fp->Read(buf, f_off, size);
76 if (ret != size)
77 {
78 if (warnp)
79 {
80 TRACE(Warning, f_trace_hdr << "Oss Read failed at off=" << f_off << " size=" << size
81 << " ret=" << ret << " error=" << ((ret < 0) ? XrdSysE2T(-ret) : "<no error>"));
82 }
83 return true;
84 }
85 f_off += ret;
86 return false;
87 }
88
89 template<typename T> bool Read(T &loc, bool warnp = true)
90 {
91 return ReadRaw(&loc, sizeof(T), warnp);
92 }
93
94 // Returns true on error
95 bool WriteRaw(const void *buf, ssize_t size)
96 {
97 ssize_t ret = f_fp->Write(buf, f_off, size);
98 if (ret != size)
99 {
100 TRACE(Warning, f_trace_hdr << "Oss Write failed at off=" << f_off << " size=" << size
101 << " ret=" << ret << " error=" << ((ret < 0) ? XrdSysE2T(ret) : "<no error>"));
102 return true;
103 }
104 f_off += ret;
105 return false;
106 }
107
108 template<typename T> bool Write(const T &loc)
109 {
110 return WriteRaw(&loc, sizeof(T));
111 }
112};
113}
114
115using namespace XrdPfc;
116
117const char* Info::m_traceID = "CInfo";
118const char* Info::s_infoExtension = ".cinfo";
120 size_t Info::s_maxNumAccess = 20; // default, can be changed through configuration
121const int Info::s_defaultVersion = 4;
122
123//------------------------------------------------------------------------------
124
125Info::Info(XrdSysTrace* trace, bool prefetchBuffer) :
126 m_trace(trace),
128 m_version(0),
131 m_complete(false),
132 m_hasPrefetchBuffer(prefetchBuffer),
133 m_cksCalcMd5(0)
134{}
135
137{
138 if (m_buff_synced) free(m_buff_synced);
141 delete m_cksCalcMd5;
142}
143
144//------------------------------------------------------------------------------
145
147{
148 // The following should be:
149 // memset(m_buff_synced, 255, GetBitvecSizeInBytes());
150 // but GCC produces an overzealous 'possible argument transpose warning' and
151 // xrootd build uses warnings->errors escalation.
152 // This workaround can be removed for gcc >= 5.
153 // See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61294
154 const int nb = GetBitvecSizeInBytes();
155 for (int i = 0; i < nb; ++i)
156 m_buff_synced[i] = 255;
157
158 m_complete = true;
159}
160
161//------------------------------------------------------------------------------
162
163void Info::SetBufferSizeFileSizeAndCreationTime(long long bs, long long fs)
164{
165 // Needed only when Info object is created for the first time in File::Open()
166 m_store.m_buffer_size = bs;
167 m_store.m_file_size = fs;
168 ResizeBits();
169 m_store.m_creationTime = time(0);
170}
171
172//------------------------------------------------------------------------------
173
175{
176 // drop buffer in case of failed/partial reads
177
178 if (m_buff_synced) free(m_buff_synced);
181
182 m_bitvecSizeInBits = (m_store.m_file_size - 1) / m_store.m_buffer_size + 1;
183
184 m_buff_written = (unsigned char*) malloc(GetBitvecSizeInBytes());
185 m_buff_synced = (unsigned char*) malloc(GetBitvecSizeInBytes());
188
190 m_complete = false;
191
193 {
194 m_buff_prefetch = (unsigned char*) malloc(GetBitvecSizeInBytes());
196 }
197 else
198 {
199 m_buff_prefetch = 0;
200 }
201}
202
203//------------------------------------------------------------------------------
204
206{
207 if (IsCkSumCache())
208 {
209 m_store.m_status.f_cksum_check &= ~CSChk_Cache;
210 if ( ! HasNoCkSumTime())
211 m_store.m_noCkSumTime = time(0);
212 }
213}
214
216{
217 if (IsCkSumNet())
218 {
219 m_store.m_status.f_cksum_check &= ~CSChk_Net;
220 if ( ! HasNoCkSumTime())
221 m_store.m_noCkSumTime = time(0);
222 }
223}
224
225//------------------------------------------------------------------------------
226// Write / Read cinfo file
227//------------------------------------------------------------------------------
228
230{
231 return crc32c(0, &m_store, sizeof(Store));
232}
233
235{
236 uint32_t cks = crc32c(0, m_buff_synced, GetBitvecSizeInBytes());
237 return crc32c(cks, m_astats.data(), m_astats.size() * sizeof(AStat));
238}
239
240void Info::CalcCksumMd5(unsigned char* buff, char* digest)
241{
242 if (m_cksCalcMd5)
243 m_cksCalcMd5->Init();
244 else
245 m_cksCalcMd5 = new XrdCksCalcmd5();
246
247 m_cksCalcMd5->Update((const char*)buff, GetBitvecSizeInBytes());
248 memcpy(digest, m_cksCalcMd5->Final(), 16);
249}
250
251const char* Info::GetCkSumStateAsText() const
252{
253 switch (m_store.m_status.f_cksum_check) {
254 case CSChk_None : return "none";
255 case CSChk_Cache : return "cache";
256 case CSChk_Net : return "net";
257 case CSChk_Both : return "both";
258 default : return "unknown";
259 }
260}
261
262//------------------------------------------------------------------------------
263
264// std::string wrapper ?
265// bool Info::Write(XrdOssDF* fp, const std::string &fname)
266// {}
267
268bool Info::Write(XrdOssDF* fp, const char *dname, const char *fname)
269{
270 TraceHeader trace_pfx("Write()", dname, fname);
271
273 m_store.m_astatSize = (int32_t) m_astats.size();
274
275 FpHelper w(fp, 0, m_trace, m_traceID, trace_pfx);
276
277 if (w.Write(s_defaultVersion) ||
278 w.Write(m_store) ||
279 w.Write(CalcCksumStore()) ||
280 w.WriteRaw(m_buff_synced, GetBitvecSizeInBytes()) ||
281 w.WriteRaw(m_astats.data(), m_store.m_astatSize * sizeof(AStat)) ||
282 w.Write(CalcCksumSyncedAndAStats()))
283 {
284 return false;
285 }
286
287 return true;
288}
289
290//------------------------------------------------------------------------------
291
292// Potentially provide std::string wrapper.
293// bool Info::Read(XrdOssDF* fp, const std::string &fname)
294// {}
295
296bool Info::Read(XrdOssDF *fp, const char *dname, const char *fname)
297{
298 // Does not need lock, called only in File::Open before File::Run() starts.
299 // XXXX Wait, how about Purge, and LocalFilePath, Stat?
300
301 TraceHeader trace_pfx("Read()", dname, fname);
302
303 FpHelper r(fp, 0, m_trace, m_traceID, trace_pfx);
304
305 if (r.Read(m_version)) return false;
306
308 {
309 if (m_version == 2)
310 {
311 return ReadV2(fp, r.f_off, dname, fname);
312 }
313 else if (m_version == 3)
314 {
315 return ReadV3(fp, r.f_off, dname, fname);
316 }
317 else
318 {
319 TRACE(Warning, trace_pfx << "File version " << m_version << " not supported.");
320 return false;
321 }
322 }
323
324 uint32_t cksum;
325
326 if (r.Read(m_store) || r.Read(cksum)) return false;
327
328 if (cksum != CalcCksumStore())
329 {
330 TRACE(Error, trace_pfx << "Checksum Store mismatch.");
331 return false;
332 }
333
334 ResizeBits();
335 m_astats.resize(m_store.m_astatSize);
336
337 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes()) ||
338 r.ReadRaw(m_astats.data(), m_store.m_astatSize * sizeof(AStat)) ||
339 r.Read(cksum))
340 {
341 return false;
342 }
343
344 if (cksum != CalcCksumSyncedAndAStats())
345 {
346 TRACE(Error, trace_pfx << "Checksum Synced or AStats mismatch.");
347 return false;
348 }
349
351
353
354 return true;
355}
356
357//------------------------------------------------------------------------------
358// Access stats / records
359//------------------------------------------------------------------------------
360
362{
363 m_store.m_accessCnt = 0;
364 m_store.m_astatSize = 0;
365 m_astats.clear();
366}
367
369{
370 // Access in b assumed to happen after the one in this.
371
373 NumIos += b.NumIos;
374 Duration += b.Duration;
375 NumMerged += b.NumMerged + 1;
376 BytesHit += b.BytesHit;
379}
380
382{
383 time_t now = time(0);
384
385 std::vector<AStat> &v = m_astats;
386
387 for (int i = 0; i < (int) v.size() - 1; ++i)
388 {
389 if (v[i].DetachTime == 0)
390 v[i].DetachTime = std::min(v[i].AttachTime + v[i].Duration / v[i].NumIos, v[i+1].AttachTime);
391 }
392
393 while (v.size() > s_maxNumAccess)
394 {
395 double min_s = 1e10;
396 int min_i = -1;
397
398 int M = (int) v.size() - 2;
399 for (int i = 0; i < M; ++i)
400 {
401 AStat &a = v[i], &b = v[i + 1];
402
403 time_t t = std::max((time_t) 1, (now - b.AttachTime) / 2 + (now - a.DetachTime) / 2);
404 double s = (double) (b.AttachTime - a.DetachTime) / t;
405
406 if (s < min_s)
407 {
408 min_s = s;
409 min_i = i;
410 }
411 }
412 assert(min_i != -1);
413
414 v[min_i].MergeWith(v[min_i + 1]);
415
416 v.erase(v.begin() + (min_i + 1));
417 }
418}
419
420//------------------------------------------------------------------------------
421
423{
424 m_store.m_accessCnt++;
425
426 AStat as;
427 as.AttachTime = time(0);
428 m_astats.push_back(as);
429}
430
432{
433 m_astats.back().NumIos = s.m_NumIos;
434 m_astats.back().Duration = s.m_Duration;
435 m_astats.back().BytesHit = s.m_BytesHit;
436 m_astats.back().BytesMissed = s.m_BytesMissed;
437 m_astats.back().BytesBypassed = s.m_BytesBypassed;
438}
439
441{
442 m_astats.back().DetachTime = time(0);
443 WriteIOStat(s);
444}
445
446void Info::WriteIOStatSingle(long long bytes_disk)
447{
448 m_store.m_accessCnt++;
449
450 AStat as;
451 as.AttachTime = as.DetachTime = time(0);
452 as.NumIos = 1;
453 as.BytesHit = bytes_disk;
454 m_astats.push_back(as);
455}
456
457void Info::WriteIOStatSingle(long long bytes_disk, time_t att, time_t dtc)
458{
459 m_store.m_accessCnt++;
460
461 AStat as;
462 as.AttachTime = att;
463 as.DetachTime = dtc;
464 as.NumIos = 1;
465 as.Duration = dtc - att;
466 as.BytesHit = bytes_disk;
467 m_astats.push_back(as);
468}
469
470//------------------------------------------------------------------------------
471
472bool Info::GetLatestDetachTime(time_t& t) const
473{
474 if (m_astats.empty())
475 {
476 t = m_store.m_creationTime;
477 }
478 else
479 {
480 const AStat& ls = m_astats.back();
481
482 if (ls.DetachTime == 0)
483 t = ls.AttachTime + ls.Duration;
484 else
485 t = ls.DetachTime;
486 }
487
488 return t != 0;
489}
490
492{
493 return m_astats.empty() ? 0 : & m_astats.back();
494}
495
496//==============================================================================
497// Support for reading of previous cinfo versions
498//==============================================================================
499
500bool Info::ReadV3(XrdOssDF* fp, off_t off, const char *dname, const char *fname)
501{
502 TraceHeader trace_pfx("ReadV3()", dname, fname);
503
504 FpHelper r(fp, off, m_trace, m_traceID, trace_pfx);
505
506 if (r.Read(m_store.m_buffer_size)) return false;
507 if (r.Read(m_store.m_file_size)) return false;
508 ResizeBits();
509
510 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes())) return false;
512
513 char fileCksum[16], tmpCksum[16];
514 if (r.ReadRaw(&fileCksum[0], 16)) return false;
515 CalcCksumMd5(&m_buff_synced[0], &tmpCksum[0]);
516
517 if (memcmp(&fileCksum[0], &tmpCksum[0], 16))
518 {
519 TRACE(Error, trace_pfx << "buffer cksum and saved cksum don't match.");
520 return false;
521 }
522
523 // cache complete status
525
526 // read creation time
527 if (r.Read(m_store.m_creationTime)) return false;
528
529 // get number of accessess
530 if (r.Read(m_store.m_accessCnt, false)) m_store.m_accessCnt = 0; // was: return false;
531
532 // read access statistics
533 m_astats.reserve(std::min(m_store.m_accessCnt, s_maxNumAccess));
534 AStat as;
535 while ( ! r.Read(as, false))
536 {
537 // Consistency check ... weird stuff seen at UCSD StashCache.
538 if (as.NumIos <= 0 || as.AttachTime < 3600*24*365 ||
539 (as.DetachTime != 0 && (as.DetachTime < 3600*24*365 || as.DetachTime < as.AttachTime)))
540 {
541 TRACE(Warning, trace_pfx << "Corrupted access record, skipping.");
542 continue;
543 }
544
545 as.Reserved = 0;
546 m_astats.emplace_back(as);
547 }
548
549 // Comment for V4: m_store.m_noCkSumTime and m_store_mstatus.f_cksum_check
550 // are left as 0 (default values in Info ctor).
551
552 return true;
553}
554
555bool Info::ReadV2(XrdOssDF* fp, off_t off, const char *dname, const char *fname)
556{
557 struct AStatV2
558 {
559 time_t AttachTime;
560 time_t DetachTime;
561 long long BytesHit;
562 long long BytesMissed;
563 long long BytesBypassed;
564 };
565
566 TraceHeader trace_pfx("ReadV2()", dname, fname);
567
568 FpHelper r(fp, off, m_trace, m_traceID, trace_pfx);
569
570 if (r.Read(m_store.m_buffer_size)) return false;
571 if (r.Read(m_store.m_file_size)) return false;
572 ResizeBits();
573
574 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes())) return false;
576
577 char fileCksum[16], tmpCksum[16];
578 if (r.ReadRaw(&fileCksum[0], 16)) return false;
579 CalcCksumMd5(&m_buff_synced[0], &tmpCksum[0]);
580
581 if (memcmp(&fileCksum[0], &tmpCksum[0], 16))
582 {
583 TRACE(Error, trace_pfx << "buffer cksum and saved cksum don't match.");
584 return false;
585 }
586
587 // cache complete status
589
590 // read creation time
591 if (r.Read(m_store.m_creationTime)) return false;
592
593 // get number of accessess
594 if (r.Read(m_store.m_accessCnt, false)) m_store.m_accessCnt = 0; // was: return false;
595
596 // read access statistics
597 m_astats.reserve(std::min(m_store.m_accessCnt, s_maxNumAccess));
598 AStatV2 av2;
599 while ( ! r.ReadRaw(&av2, sizeof(AStatV2), false))
600 {
601 AStat as;
602 as.AttachTime = av2.AttachTime;
603 as.DetachTime = av2.DetachTime;
604 as.NumIos = 1;
605 as.Duration = av2.DetachTime - av2.AttachTime;
606 as.NumMerged = 0;
607 as.Reserved = 0;
608 as.BytesHit = av2.BytesHit;
609 as.BytesMissed = av2.BytesMissed;
610 as.BytesBypassed = av2.BytesBypassed;
611
612 // Consistency check ... weird stuff seen at UCSD StashCache.
613 if (as.AttachTime < 3600*24*365 ||
614 (as.DetachTime != 0 && (as.DetachTime < 3600*24*365 || as.DetachTime < as.AttachTime)))
615 {
616 TRACE(Warning, trace_pfx << "Corrupted access record, skipping.");
617 continue;
618 }
619
620 m_astats.emplace_back(as);
621 }
622
623 return true;
624}
625
626
627//==============================================================================
628// Test bitfield ops and masking of non-cksum fields
629//==============================================================================
630#ifdef XRDPFC_CKSUM_TEST
631
632void Info::TestCksumStuff()
633{
634 static const char* names[] = { "--", "-C", "N-", "NC" };
635
636 const Configuration &conf = Cache::GetInstance().RefConfiguration();
637
638 printf("Doing cksum tests for config %s\n", names[conf.m_cs_Chk]);
639
640 Info cfi(0);
641 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
642
643 cfi.SetCkSumState(CSChk_Both);
644 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
645
646 cfi.m_store.m_status._raw_ |= 0xff0000;
647 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
648
649 cfi.ResetCkSumCache();
650 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
651
652 cfi.ResetCkSumNet();
653 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
654
655 for (int cs = CSChk_None; cs <= CSChk_Both; ++cs)
656 {
657 cfi.SetCkSumState((CkSumCheck_e) cs);
658 bool hasmb = conf.does_cschk_have_missing_bits(cfi.GetCkSumState());
659 cfi.DowngradeCkSumState(conf.get_cs_Chk());
660 printf("-- File conf %s -- does_cschk_have_missing_bits:%d, downgraded_state:%s\n",
661 names[cs], hasmb, names[cfi.GetCkSumState()]);
662 }
663}
664
665#endif
uint32_t crc32c(uint32_t crc, void const *buf, size_t len)
std::ostream & operator<<(std::ostream &os, const XrdOucString s)
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
#define TRACE(act, x)
Definition XrdTrace.hh:63
const Configuration & RefConfiguration() const
Reference XrdPfc configuration.
Definition XrdPfc.hh:319
static Cache & GetInstance()
Singleton access.
Definition XrdPfc.cc:163
void UpdateDownloadCompleteStatus()
Update complete status.
static const char * s_infoExtension
uint32_t CalcCksumStore()
Get cksum, MD5 is for backward compatibility with V2 and V3.
void ResizeBits()
Reserve bit vectors for file_size / buffer_size bytes.
void ResetCkSumCache()
static const int s_defaultVersion
void WriteIOStatSingle(long long bytes_disk)
Write single open/close time for given bytes read from disk.
Info(XrdSysTrace *trace, bool prefetchBuffer=false)
Constructor.
int GetBitvecSizeInBytes() const
Get size of download-state bit-vector in bytes.
unsigned char * m_buff_prefetch
prefetch statistics
static const size_t s_infoExtensionLen
const AStat * GetLastAccessStats() const
Get latest access stats.
void WriteIOStatAttach()
Write open time in the last entry of access statistics.
bool GetLatestDetachTime(time_t &t) const
Get latest detach time.
void ResetCkSumNet()
bool Write(XrdOssDF *fp, const char *dname, const char *fname=0)
void CompactifyAccessRecords()
Compactify access records to the configured maximum.
uint32_t CalcCksumSyncedAndAStats()
~Info()
Destructor.
unsigned char * m_buff_written
download state vector
bool IsCkSumNet() const
unsigned char * m_buff_synced
disk written state vector
bool m_complete
cached; if false, set to true when missingBlocks hit zero
void ResetAllAccessStats()
Reset IO Stats.
bool IsCkSumCache() const
int m_missingBlocks
cached, updated in SetBitWritten()
void WriteIOStat(Stats &s)
Write bytes missed, hits, and disk.
int m_bitvecSizeInBits
cached
XrdSysTrace * m_trace
std::vector< AStat > m_astats
access records
void SetAllBitsSynced()
Mark all blocks as synced to disk.
bool Read(XrdOssDF *fp, const char *dname, const char *fname=0)
Read content of cinfo file into this object.
const char * GetCkSumStateAsText() const
void SetBufferSizeFileSizeAndCreationTime(long long bs, long long fs)
void WriteIOStatDetach(Stats &s)
Write close time together with bytes missed, hits, and disk.
static size_t s_maxNumAccess
static const char * m_traceID
void CalcCksumMd5(unsigned char *buff, char *digest)
bool m_hasPrefetchBuffer
constains current prefetch score
bool HasNoCkSumTime() const
Statistics of cache utilisation by a File object.
long long m_BytesMissed
number of bytes served from remote and cached
long long m_BytesBypassed
number of bytes served directly through XrdCl
int m_Duration
total duration of all IOs attached
int m_NumIos
number of IO objects attached during this access
long long m_BytesHit
number of bytes served from disk
ReadImpl< false > Read(Ctx< File > file, Arg< uint64_t > offset, Arg< uint32_t > size, Arg< void * > buffer, uint16_t timeout=0)
Factory for creating ReadImpl objects.
WriteImpl< false > Write(Ctx< File > file, Arg< uint64_t > offset, Arg< uint32_t > size, Arg< const void * > buffer, uint16_t timeout=0)
Factory for creating WriteImpl objects.
@ CSChk_Cache
XrdSysTrace * GetTrace()
bool does_cschk_have_missing_bits(CkSumCheck_e cks_on_file) const
Definition XrdPfc.hh:74
CkSumCheck_e get_cs_Chk() const
Definition XrdPfc.hh:67
int m_cs_Chk
Checksum check.
Definition XrdPfc.hh:112
Access statistics.
Definition XrdPfcInfo.hh:61
long long BytesHit
read from cache
Definition XrdPfcInfo.hh:68
long long BytesBypassed
read from remote and dropped
Definition XrdPfcInfo.hh:70
void MergeWith(const AStat &a)
int Duration
total duration of all IOs attached
Definition XrdPfcInfo.hh:65
int NumIos
number of IO objects attached during this access
Definition XrdPfcInfo.hh:64
time_t DetachTime
close time
Definition XrdPfcInfo.hh:63
long long BytesMissed
read from remote and cached
Definition XrdPfcInfo.hh:69
time_t AttachTime
open time
Definition XrdPfcInfo.hh:62
int NumMerged
number of times the record has been merged
Definition XrdPfcInfo.hh:66
long long m_buffer_size
buffer / block size
Definition XrdPfcInfo.hh:82
size_t m_accessCnt
total access count for the file
Definition XrdPfcInfo.hh:86
long long m_file_size
size of file in bytes
Definition XrdPfcInfo.hh:83
time_t m_creationTime
time the info file was created
Definition XrdPfcInfo.hh:84