xrootd
XrdClientReadCache.hh
Go to the documentation of this file.
1 
2 // //
3 // XrdClientReadCache //
4 // //
5 // Author: Fabrizio Furano (INFN Padova, 2006) //
6 // //
7 // Classes to handle cache reading and cache placeholders //
8 // //
10 
11 // $Id$
12 
13 #ifndef XRD_READCACHE_H
14 #define XRD_READCACHE_H
15 
16 #include "XrdSys/XrdSysHeaders.hh"
21 
22 
23 //
24 // XrdClientReadCacheItem
25 //
26 // An item is nothing more than an interval of bytes taken from a file.
27 // Extremes are included.
28 // Since a cache object is to be associated to a single instance
29 // of TXNetFile, we do not have to keep here any filehandle
30 //
31 
33 private:
34  // A placeholder block is a "fake block" used to mark outstanding data
36 
37  long long fBeginOffset; // Offset of the first byte of data
38  void *fData;
39  long long fEndOffset; // Offset of the last byte of data
40  long fTimestampTicks; // timestamp updated each time it's referenced
41 
42 public:
43  XrdClientReadCacheItem(const void *buffer, long long begin_offs,
44  long long end_offs, long long ticksnow,
45  bool placeholder=false);
47 
48  inline long long BeginOffset() { return fBeginOffset; }
49  inline long long EndOffset() { return fEndOffset; }
50 
51  // Is this obj contained in the given interval (which is going to be inserted) ?
52  inline bool ContainedInInterval(long long begin_offs, long long end_offs) {
53  return ( (end_offs >= begin_offs) &&
54  (fBeginOffset >= begin_offs) &&
55  (fEndOffset <= end_offs) );
56  }
57 
58  // Does this obj contain the given interval (which is going to be requested) ?
59  inline bool ContainsInterval(long long begin_offs, long long end_offs) {
60  return ( (end_offs > begin_offs) &&
61  (fBeginOffset <= begin_offs) && (fEndOffset >= end_offs) );
62  }
63 
64  // Are the two intervals intersecting in some way?
65  inline bool IntersectInterval(long long begin_offs, long long end_offs) {
66  if ( ContainsOffset( begin_offs ) || ContainsOffset( end_offs ) ) return true;
67  if ( (fBeginOffset >= begin_offs) && (fBeginOffset <= end_offs) ) return true;
68  return false;
69  }
70 
71 
72  inline bool ContainsOffset(long long offs) {
73  return (fBeginOffset <= offs) && (fEndOffset >= offs);
74  }
75 
76  void *GetData() { return fData; }
77 
78  // Get the requested interval, if possible
79  inline bool GetInterval(const void *buffer, long long begin_offs,
80  long long end_offs) {
81  if (!ContainsInterval(begin_offs, end_offs))
82  return FALSE;
83  memcpy((void *)buffer, ((char *)fData)+(begin_offs - fBeginOffset),
84  end_offs - begin_offs + 1);
85  return TRUE;
86  }
87 
88  // Get as many bytes as possible, starting from the beginning of the given
89  // interval
90  inline long GetPartialInterval(const void *buffer, long long begin_offs,
91  long long end_offs) {
92 
93  long long b = -1, e, l;
94 
95  if (begin_offs > end_offs) return 0;
96 
97  // Try to set the starting point, if contained in the given interval
98  if ( (begin_offs >= fBeginOffset) &&
99  (begin_offs <= fEndOffset) )
100  b = begin_offs;
101 
102  if (b < 0) return 0;
103 
104  // The starting point is in the interval. Let's get the minimum endpoint
105  e = xrdmin(end_offs, fEndOffset);
106 
107  l = e - b + 1;
108 
109  if (buffer && fData)
110  memcpy((void *)buffer, ((char *)fData)+(b - fBeginOffset), l);
111 
112  return l;
113  }
114 
115  inline long long GetTimestampTicks() { return(fTimestampTicks); }
116 
117  inline bool IsPlaceholder() { return fIsPlaceholder; }
118 
119  long Size() { return (fEndOffset - fBeginOffset + 1); }
120 
121  inline void Touch(long long ticksnow) { fTimestampTicks = ticksnow; }
122 
123  bool Pinned;
124 };
125 
126 //
127 // XrdClientReadCache
128 //
129 // The content of the cache. Not cache blocks, but
130 // variable length Items
131 //
133 
134 // A cache interval, extremes included
136  long long beginoffs;
137  long long endoffs;
138 };
139 
141 
143 private:
144 
145  long long fBytesHit; // Total number of bytes read with a cache hit
146  long long fBytesSubmitted; // Total number of bytes inserted
149  long long fMaxCacheSize;
150  long long fMissCount; // Counter of the cache misses
151  float fMissRate; // Miss rate
153  long long fReadsCounter; // Counter of all the attempted reads (hit or miss)
154  int fBlkRemPolicy; // The algorithm used to remove "old" chunks
155  long long fTimestampTickCounter; // Aging mechanism yuk!
156  long long fTotalByteCount;
157 
158  long long GetTimestampTick();
159  bool MakeFreeSpace(long long bytes);
160 
161  bool RemoveItem();
162  bool RemoveLRUItem();
163  bool RemoveFirstItem();
164 
165  inline void UpdatePerfCounters() {
166  if (fReadsCounter > 0)
168  if (fBytesSubmitted > 0)
170  }
171 
172  int FindInsertionApprox(long long begin_offs);
173  int FindInsertionApprox_rec(int startidx, int endidx,
174  long long begin_offs);
175 public:
176 
177  // The algos available for the removal of "old" blocks
178  enum {
182  };
183 
186 
187  long GetDataIfPresent(const void *buffer, long long begin_offs,
188  long long end_offs, bool PerfCalc,
189  XrdClientIntvList &missingblks, long &outstandingblks);
190 
191  void GetInfo(
192  // The actual cache size
193  int &size,
194 
195  // The number of bytes submitted since the beginning
196  long long &bytessubmitted,
197 
198  // The number of bytes found in the cache (estimate)
199  long long &byteshit,
200 
201  // The number of reads which did not find their data
202  // (estimate)
203  long long &misscount,
204 
205  // miss/totalreads ratio (estimate)
206  float &missrate,
207 
208  // number of read requests towards the cache
209  long long &readreqcnt,
210 
211  // ratio between bytes found / bytes submitted
212  float &bytesusefulness
213  );
214 
215  inline long long GetTotalByteCount() {
217  return fTotalByteCount;
218  }
219 
220  void PutPlaceholder(long long begin_offs, long long end_offs);
221 
222  inline void PrintPerfCounters() {
224 
225  cout << "Low level caching info:" << endl;
226  cout << " StallsRate=" << fMissRate << endl;
227  cout << " StallsCount=" << fMissCount << endl;
228  cout << " ReadsCounter=" << fReadsCounter << endl;
229  cout << " BytesUsefulness=" << fBytesUsefulness << endl;
230  cout << " BytesSubmitted=" << fBytesSubmitted << " BytesHit=" <<
231  fBytesHit << endl << endl;
232  }
233 
234 
235  void PrintCache();
236 
237  void SubmitXMessage(XrdClientMessage *xmsg, long long begin_offs,
238  long long end_offs);
239 
240  bool SubmitRawData(const void *buffer, long long begin_offs,
241  long long end_offs, bool pinned=false);
242 
243  void RemoveItems(bool leavepinned=true);
244  void RemoveItems(long long begin_offs, long long end_offs, bool remove_overlapped = false);
245  void RemovePlaceholders();
246 
247 
248  void SetSize(int sz) {
249  fMaxCacheSize = sz;
250  }
251 
252  void SetBlkRemovalPolicy(int p) {
253  fBlkRemPolicy = p;
254  }
255 
256  void UnPinCacheBlk(long long begin_offs, long long end_offs);
257  void *FindBlk(long long begin_offs, long long end_offs);
258 
259  // To check if a block dimension will fit into the cache
260  inline bool WillFit(long long bc) {
262  return (bc < fMaxCacheSize);
263  }
264 
265 };
266 
267 #endif