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 "XrdPfcInfo.hh"
31#include "XrdPfc.hh"
32#include "XrdPfcStats.hh"
33#include "XrdPfcTrace.hh"
34
35namespace
36{
37
38struct TraceHeader
39{
40 const char *f_tpf, *f_tdir, *f_tfile , *f_tmsg;
41
42 // tdir is supposed to be '/' terminated. Check can be added in ctor and a bool flag to mark if it is needed.
43 TraceHeader(const char *tpf, const char *tdir, const char *tfile = 0, const char *tmsg = 0) :
44 f_tpf(tpf), f_tdir(tdir), f_tfile(tfile), f_tmsg(tmsg) {}
45};
46
47XrdSysTrace& operator<<(XrdSysTrace& s, const TraceHeader& th)
48{
49 s << th.f_tpf << " " << th.f_tdir;
50 if (th.f_tfile) s << th.f_tfile;
51 if (th.f_tmsg) s << " " << th.f_tmsg;
52 s << " ";
53 return s;
54}
55
56struct FpHelper
57{
58 XrdOssDF *f_fp;
59 off_t f_off;
60 XrdSysTrace *f_trace;
61 const char *m_traceID;
62 const TraceHeader &f_trace_hdr;
63
64 XrdSysTrace* GetTrace() const { return f_trace; }
65
66 FpHelper(XrdOssDF* fp, off_t off, XrdSysTrace *trace, const char *tid, const TraceHeader &thdr) :
67 f_fp(fp), f_off(off), f_trace(trace), m_traceID(tid), f_trace_hdr(thdr)
68 {}
69
70 // Returns true on error
71 bool ReadRaw(void *buf, ssize_t size, bool warnp = true)
72 {
73 ssize_t ret = f_fp->Read(buf, f_off, size);
74 if (ret != size)
75 {
76 if (warnp)
77 {
78 TRACE(Warning, f_trace_hdr << "Oss Read failed at off=" << f_off << " size=" << size
79 << " ret=" << ret << " error=" << ((ret < 0) ? XrdSysE2T(-ret) : "<no error>"));
80 }
81 return true;
82 }
83 f_off += ret;
84 return false;
85 }
86
87 template<typename T> bool Read(T &loc, bool warnp = true)
88 {
89 return ReadRaw(&loc, sizeof(T), warnp);
90 }
91
92 // Returns true on error
93 bool WriteRaw(const void *buf, ssize_t size)
94 {
95 ssize_t ret = f_fp->Write(buf, f_off, size);
96 if (ret != size)
97 {
98 TRACE(Warning, f_trace_hdr << "Oss Write failed at off=" << f_off << " size=" << size
99 << " ret=" << ret << " error=" << ((ret < 0) ? XrdSysE2T(ret) : "<no error>"));
100 return true;
101 }
102 f_off += ret;
103 return false;
104 }
105
106 template<typename T> bool Write(const T &loc)
107 {
108 return WriteRaw(&loc, sizeof(T));
109 }
110};
111}
112
113using namespace XrdPfc;
114
115const char* Info::m_traceID = "CInfo";
116const char* Info::s_infoExtension = ".cinfo";
118 size_t Info::s_maxNumAccess = 20; // default, can be changed through configuration
119const int Info::s_defaultVersion = 4;
120
121//------------------------------------------------------------------------------
122
123Info::Info(XrdSysTrace* trace, bool prefetchBuffer) :
124 m_trace(trace),
126 m_version(0),
129 m_complete(false),
130 m_hasPrefetchBuffer(prefetchBuffer),
131 m_cksCalcMd5(0)
132{}
133
135{
136 if (m_buff_synced) free(m_buff_synced);
139 delete m_cksCalcMd5;
140}
141
142//------------------------------------------------------------------------------
143
145{
146 // The following should be:
147 // memset(m_buff_synced, 255, GetBitvecSizeInBytes());
148 // but GCC produces an overzealous 'possible argument transpose warning' and
149 // xrootd build uses warnings->errors escalation.
150 // This workaround can be removed for gcc >= 5.
151 // See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61294
152 const int nb = GetBitvecSizeInBytes();
153 for (int i = 0; i < nb; ++i)
154 m_buff_synced[i] = 255;
155
156 m_complete = true;
157}
158
159//------------------------------------------------------------------------------
160
161void Info::SetBufferSizeFileSizeAndCreationTime(long long bs, long long fs)
162{
163 // Needed only when Info object is created for the first time in File::Open()
164 m_store.m_buffer_size = bs;
165 m_store.m_file_size = fs;
166 ResizeBits();
167 m_store.m_creationTime = time(0);
168}
169
170//------------------------------------------------------------------------------
171
173{
174 // drop buffer in case of failed/partial reads
175
176 if (m_buff_synced) free(m_buff_synced);
179
180 m_bitvecSizeInBits = (m_store.m_file_size - 1) / m_store.m_buffer_size + 1;
181
182 m_buff_written = (unsigned char*) malloc(GetBitvecSizeInBytes());
183 m_buff_synced = (unsigned char*) malloc(GetBitvecSizeInBytes());
186
188 m_complete = false;
189
191 {
192 m_buff_prefetch = (unsigned char*) malloc(GetBitvecSizeInBytes());
194 }
195 else
196 {
197 m_buff_prefetch = 0;
198 }
199}
200
201//------------------------------------------------------------------------------
202
204{
205 if (IsCkSumCache())
206 {
207 m_store.m_status.f_cksum_check &= ~CSChk_Cache;
208 if ( ! HasNoCkSumTime())
209 m_store.m_noCkSumTime = time(0);
210 }
211}
212
214{
215 if (IsCkSumNet())
216 {
217 m_store.m_status.f_cksum_check &= ~CSChk_Net;
218 if ( ! HasNoCkSumTime())
219 m_store.m_noCkSumTime = time(0);
220 }
221}
222
223//------------------------------------------------------------------------------
224// Write / Read cinfo file
225//------------------------------------------------------------------------------
226
228{
229 return crc32c(0, &m_store, sizeof(Store));
230}
231
233{
234 uint32_t cks = crc32c(0, m_buff_synced, GetBitvecSizeInBytes());
235 return crc32c(cks, m_astats.data(), m_astats.size() * sizeof(AStat));
236}
237
238void Info::CalcCksumMd5(unsigned char* buff, char* digest)
239{
240 if (m_cksCalcMd5)
241 m_cksCalcMd5->Init();
242 else
243 m_cksCalcMd5 = new XrdCksCalcmd5();
244
245 m_cksCalcMd5->Update((const char*)buff, GetBitvecSizeInBytes());
246 memcpy(digest, m_cksCalcMd5->Final(), 16);
247}
248
249const char* Info::GetCkSumStateAsText() const
250{
251 switch (m_store.m_status.f_cksum_check) {
252 case CSChk_None : return "none";
253 case CSChk_Cache : return "cache";
254 case CSChk_Net : return "net";
255 case CSChk_Both : return "both";
256 default : return "unknown";
257 }
258}
259
260//------------------------------------------------------------------------------
261
262// std::string wrapper ?
263// bool Info::Write(XrdOssDF* fp, const std::string &fname)
264// {}
265
266bool Info::Write(XrdOssDF* fp, const char *dname, const char *fname)
267{
268 TraceHeader trace_pfx("Write()", dname, fname);
269
271 m_store.m_astatSize = (int32_t) m_astats.size();
272
273 FpHelper w(fp, 0, m_trace, m_traceID, trace_pfx);
274
275 if (w.Write(s_defaultVersion) ||
276 w.Write(m_store) ||
277 w.Write(CalcCksumStore()) ||
278 w.WriteRaw(m_buff_synced, GetBitvecSizeInBytes()) ||
279 w.WriteRaw(m_astats.data(), m_store.m_astatSize * sizeof(AStat)) ||
280 w.Write(CalcCksumSyncedAndAStats()))
281 {
282 return false;
283 }
284
285 return true;
286}
287
288//------------------------------------------------------------------------------
289
290// Potentially provide std::string wrapper.
291// bool Info::Read(XrdOssDF* fp, const std::string &fname)
292// {}
293
294bool Info::Read(XrdOssDF *fp, const char *dname, const char *fname)
295{
296 // Does not need lock, called only in File::Open before File::Run() starts.
297 // XXXX Wait, how about Purge, and LocalFilePath, Stat?
298
299 TraceHeader trace_pfx("Read()", dname, fname);
300
301 FpHelper r(fp, 0, m_trace, m_traceID, trace_pfx);
302
303 if (r.Read(m_version)) return false;
304
306 {
307 if (m_version == 2)
308 {
309 return ReadV2(fp, r.f_off, dname, fname);
310 }
311 else if (m_version == 3)
312 {
313 return ReadV3(fp, r.f_off, dname, fname);
314 }
315 else
316 {
317 TRACE(Warning, trace_pfx << "File version " << m_version << " not supported.");
318 return false;
319 }
320 }
321
322 uint32_t cksum;
323
324 if (r.Read(m_store) || r.Read(cksum)) return false;
325
326 if (cksum != CalcCksumStore())
327 {
328 TRACE(Error, trace_pfx << "Checksum Store mismatch.");
329 return false;
330 }
331
332 ResizeBits();
333 m_astats.resize(m_store.m_astatSize);
334
335 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes()) ||
336 r.ReadRaw(m_astats.data(), m_store.m_astatSize * sizeof(AStat)) ||
337 r.Read(cksum))
338 {
339 return false;
340 }
341
342 if (cksum != CalcCksumSyncedAndAStats())
343 {
344 TRACE(Error, trace_pfx << "Checksum Synced or AStats mismatch.");
345 return false;
346 }
347
349
351
352 return true;
353}
354
355//------------------------------------------------------------------------------
356// Access stats / records
357//------------------------------------------------------------------------------
358
360{
361 m_store.m_accessCnt = 0;
362 m_store.m_astatSize = 0;
363 m_astats.clear();
364}
365
367{
368 // Access in b assumed to happen after the one in this.
369
371 NumIos += b.NumIos;
372 Duration += b.Duration;
373 NumMerged += b.NumMerged + 1;
374 BytesHit += b.BytesHit;
377}
378
380{
381 time_t now = time(0);
382
383 std::vector<AStat> &v = m_astats;
384
385 for (int i = 0; i < (int) v.size() - 1; ++i)
386 {
387 if (v[i].DetachTime == 0)
388 v[i].DetachTime = std::min(v[i].AttachTime + v[i].Duration / v[i].NumIos, v[i+1].AttachTime);
389 }
390
391 while (v.size() > s_maxNumAccess)
392 {
393 double min_s = 1e10;
394 int min_i = -1;
395
396 int M = (int) v.size() - 2;
397 for (int i = 0; i < M; ++i)
398 {
399 AStat &a = v[i], &b = v[i + 1];
400
401 time_t t = std::max((time_t) 1, (now - b.AttachTime) / 2 + (now - a.DetachTime) / 2);
402 double s = (double) (b.AttachTime - a.DetachTime) / t;
403
404 if (s < min_s)
405 {
406 min_s = s;
407 min_i = i;
408 }
409 }
410 assert(min_i != -1);
411
412 v[min_i].MergeWith(v[min_i + 1]);
413
414 v.erase(v.begin() + (min_i + 1));
415 }
416}
417
418//------------------------------------------------------------------------------
419
421{
422 m_store.m_accessCnt++;
423
424 AStat as;
425 as.AttachTime = time(0);
426 m_astats.push_back(as);
427}
428
430{
431 m_astats.back().NumIos = s.m_NumIos;
432 m_astats.back().Duration = s.m_Duration;
433 m_astats.back().BytesHit = s.m_BytesHit;
434 m_astats.back().BytesMissed = s.m_BytesMissed;
435 m_astats.back().BytesBypassed = s.m_BytesBypassed;
436}
437
439{
440 m_astats.back().DetachTime = time(0);
441 WriteIOStat(s);
442}
443
444void Info::WriteIOStatSingle(long long bytes_disk)
445{
446 m_store.m_accessCnt++;
447
448 AStat as;
449 as.AttachTime = as.DetachTime = time(0);
450 as.NumIos = 1;
451 as.BytesHit = bytes_disk;
452 m_astats.push_back(as);
453}
454
455void Info::WriteIOStatSingle(long long bytes_disk, time_t att, time_t dtc)
456{
457 m_store.m_accessCnt++;
458
459 AStat as;
460 as.AttachTime = att;
461 as.DetachTime = dtc;
462 as.NumIos = 1;
463 as.Duration = dtc - att;
464 as.BytesHit = bytes_disk;
465 m_astats.push_back(as);
466}
467
468//------------------------------------------------------------------------------
469
470bool Info::GetLatestDetachTime(time_t& t) const
471{
472 if (m_astats.empty())
473 {
474 t = m_store.m_creationTime;
475 }
476 else
477 {
478 const AStat& ls = m_astats.back();
479
480 if (ls.DetachTime == 0)
481 t = ls.AttachTime + ls.Duration;
482 else
483 t = ls.DetachTime;
484 }
485
486 return t != 0;
487}
488
490{
491 return m_astats.empty() ? 0 : & m_astats.back();
492}
493
494//==============================================================================
495// Support for reading of previous cinfo versions
496//==============================================================================
497
498bool Info::ReadV3(XrdOssDF* fp, off_t off, const char *dname, const char *fname)
499{
500 TraceHeader trace_pfx("ReadV3()", dname, fname);
501
502 FpHelper r(fp, off, m_trace, m_traceID, trace_pfx);
503
504 if (r.Read(m_store.m_buffer_size)) return false;
505 if (r.Read(m_store.m_file_size)) return false;
506 ResizeBits();
507
508 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes())) return false;
510
511 char fileCksum[16], tmpCksum[16];
512 if (r.ReadRaw(&fileCksum[0], 16)) return false;
513 CalcCksumMd5(&m_buff_synced[0], &tmpCksum[0]);
514
515 if (memcmp(&fileCksum[0], &tmpCksum[0], 16))
516 {
517 TRACE(Error, trace_pfx << "buffer cksum and saved cksum don't match.");
518 return false;
519 }
520
521 // cache complete status
523
524 // read creation time
525 if (r.Read(m_store.m_creationTime)) return false;
526
527 // get number of accessess
528 if (r.Read(m_store.m_accessCnt, false)) m_store.m_accessCnt = 0; // was: return false;
529
530 // read access statistics
531 m_astats.reserve(std::min(m_store.m_accessCnt, s_maxNumAccess));
532 AStat as;
533 while ( ! r.Read(as, false))
534 {
535 // Consistency check ... weird stuff seen at UCSD StashCache.
536 if (as.NumIos <= 0 || as.AttachTime < 3600*24*365 ||
537 (as.DetachTime != 0 && (as.DetachTime < 3600*24*365 || as.DetachTime < as.AttachTime)))
538 {
539 TRACE(Warning, trace_pfx << "Corrupted access record, skipping.");
540 continue;
541 }
542
543 as.Reserved = 0;
544 m_astats.emplace_back(as);
545 }
546
547 // Comment for V4: m_store.m_noCkSumTime and m_store_mstatus.f_cksum_check
548 // are left as 0 (default values in Info ctor).
549
550 return true;
551}
552
553bool Info::ReadV2(XrdOssDF* fp, off_t off, const char *dname, const char *fname)
554{
555 struct AStatV2
556 {
557 time_t AttachTime;
558 time_t DetachTime;
559 long long BytesHit;
560 long long BytesMissed;
561 long long BytesBypassed;
562 };
563
564 TraceHeader trace_pfx("ReadV2()", dname, fname);
565
566 FpHelper r(fp, off, m_trace, m_traceID, trace_pfx);
567
568 if (r.Read(m_store.m_buffer_size)) return false;
569 if (r.Read(m_store.m_file_size)) return false;
570 ResizeBits();
571
572 if (r.ReadRaw(m_buff_synced, GetBitvecSizeInBytes())) return false;
574
575 char fileCksum[16], tmpCksum[16];
576 if (r.ReadRaw(&fileCksum[0], 16)) return false;
577 CalcCksumMd5(&m_buff_synced[0], &tmpCksum[0]);
578
579 if (memcmp(&fileCksum[0], &tmpCksum[0], 16))
580 {
581 TRACE(Error, trace_pfx << "buffer cksum and saved cksum don't match.");
582 return false;
583 }
584
585 // cache complete status
587
588 // read creation time
589 if (r.Read(m_store.m_creationTime)) return false;
590
591 // get number of accessess
592 if (r.Read(m_store.m_accessCnt, false)) m_store.m_accessCnt = 0; // was: return false;
593
594 // read access statistics
595 m_astats.reserve(std::min(m_store.m_accessCnt, s_maxNumAccess));
596 AStatV2 av2;
597 while ( ! r.ReadRaw(&av2, sizeof(AStatV2), false))
598 {
599 AStat as;
600 as.AttachTime = av2.AttachTime;
601 as.DetachTime = av2.DetachTime;
602 as.NumIos = 1;
603 as.Duration = av2.DetachTime - av2.AttachTime;
604 as.NumMerged = 0;
605 as.Reserved = 0;
606 as.BytesHit = av2.BytesHit;
607 as.BytesMissed = av2.BytesMissed;
608 as.BytesBypassed = av2.BytesBypassed;
609
610 // Consistency check ... weird stuff seen at UCSD StashCache.
611 if (as.AttachTime < 3600*24*365 ||
612 (as.DetachTime != 0 && (as.DetachTime < 3600*24*365 || as.DetachTime < as.AttachTime)))
613 {
614 TRACE(Warning, trace_pfx << "Corrupted access record, skipping.");
615 continue;
616 }
617
618 m_astats.emplace_back(as);
619 }
620
621 return true;
622}
623
624
625//==============================================================================
626// Test bitfield ops and masking of non-cksum fields
627//==============================================================================
628#ifdef XRDPFC_CKSUM_TEST
629
630void Info::TestCksumStuff()
631{
632 static const char* names[] = { "--", "-C", "N-", "NC" };
633
634 const Configuration &conf = Cache::GetInstance().RefConfiguration();
635
636 printf("Doing cksum tests for config %s\n", names[conf.m_cs_Chk]);
637
638 Info cfi(0);
639 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
640
641 cfi.SetCkSumState(CSChk_Both);
642 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
643
644 cfi.m_store.m_status._raw_ |= 0xff0000;
645 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
646
647 cfi.ResetCkSumCache();
648 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
649
650 cfi.ResetCkSumNet();
651 printf("cksum %d, raw %x\n", cfi.m_store.m_status.f_cksum_check, cfi.m_store.m_status._raw_);
652
653 for (int cs = CSChk_None; cs <= CSChk_Both; ++cs)
654 {
655 cfi.SetCkSumState((CkSumCheck_e) cs);
656 bool hasmb = conf.does_cschk_have_missing_bits(cfi.GetCkSumState());
657 cfi.DowngradeCkSumState(conf.get_cs_Chk());
658 printf("-- File conf %s -- does_cschk_have_missing_bits:%d, downgraded_state:%s\n",
659 names[cs], hasmb, names[cfi.GetCkSumState()]);
660 }
661}
662
663#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:204
static Cache & GetInstance()
Singleton access.
Definition XrdPfc.cc:132
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
bool does_cschk_have_missing_bits(CkSumCheck_e cks_on_file) const
Definition XrdPfc.hh:80
CkSumCheck_e get_cs_Chk() const
Definition XrdPfc.hh:73
int m_cs_Chk
Checksum check.
Definition XrdPfc.hh:119
Access statistics.
Definition XrdPfcInfo.hh:57
long long BytesHit
read from cache
Definition XrdPfcInfo.hh:64
long long BytesBypassed
read from remote and dropped
Definition XrdPfcInfo.hh:66
void MergeWith(const AStat &a)
int Duration
total duration of all IOs attached
Definition XrdPfcInfo.hh:61
int NumIos
number of IO objects attached during this access
Definition XrdPfcInfo.hh:60
time_t DetachTime
close time
Definition XrdPfcInfo.hh:59
long long BytesMissed
read from remote and cached
Definition XrdPfcInfo.hh:65
time_t AttachTime
open time
Definition XrdPfcInfo.hh:58
int NumMerged
number of times the record has been merged
Definition XrdPfcInfo.hh:62
long long m_buffer_size
buffer / block size
Definition XrdPfcInfo.hh:78
size_t m_accessCnt
total access count for the file
Definition XrdPfcInfo.hh:82
long long m_file_size
size of file in bytes
Definition XrdPfcInfo.hh:79
time_t m_creationTime
time the info file was created
Definition XrdPfcInfo.hh:80