Logo ROOT   6.08/07
Reference Guide
XrdClientReadCache.hh
Go to the documentation of this file.
1 #ifndef XRD_READCACHE_H
2 #define XRD_READCACHE_H
3 /******************************************************************************/
4 /* */
5 /* X r d C l i e n t R e a d C a c h e . h h */
6 /* */
7 /* Author: Fabrizio Furano (INFN Padova, 2006) */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 //////////////////////////////////////////////////////////////////////////
31 // //
32 // Classes to handle cache reading and cache placeholders //
33 // //
34 //////////////////////////////////////////////////////////////////////////
35 
36 #include "XrdSys/XrdSysHeaders.hh"
41 
42 //
43 // XrdClientReadCacheItem
44 //
45 // An item is nothing more than an interval of bytes taken from a file.
46 // Extremes are included.
47 // Since a cache object is to be associated to a single instance
48 // of TXNetFile, we do not have to keep here any filehandle
49 //
50 
52 private:
53  // A placeholder block is a "fake block" used to mark outstanding data
55 
56  long long fBeginOffset; // Offset of the first byte of data
57  void *fData;
58  long long fEndOffset; // Offset of the last byte of data
59  long fTimestampTicks; // timestamp updated each time it's referenced
60 
61 public:
62  XrdClientReadCacheItem(const void *buffer, long long begin_offs,
63  long long end_offs, long long ticksnow,
64  bool placeholder=false);
66 
67  inline long long BeginOffset() { return fBeginOffset; }
68  inline long long EndOffset() { return fEndOffset; }
69 
70  // Is this obj contained in the given interval (which is going to be inserted) ?
71  inline bool ContainedInInterval(long long begin_offs, long long end_offs) {
72  return ( (end_offs >= begin_offs) &&
73  (fBeginOffset >= begin_offs) &&
74  (fEndOffset <= end_offs) );
75  }
76 
77  // Does this obj contain the given interval (which is going to be requested) ?
78  inline bool ContainsInterval(long long begin_offs, long long end_offs) {
79  return ( (end_offs > begin_offs) &&
80  (fBeginOffset <= begin_offs) && (fEndOffset >= end_offs) );
81  }
82 
83  // Are the two intervals intersecting in some way?
84  inline bool IntersectInterval(long long begin_offs, long long end_offs) {
85  if ( ContainsOffset( begin_offs ) || ContainsOffset( end_offs ) ) return true;
86  if ( (fBeginOffset >= begin_offs) && (fBeginOffset <= end_offs) ) return true;
87  return false;
88  }
89 
90 
91  inline bool ContainsOffset(long long offs) {
92  return (fBeginOffset <= offs) && (fEndOffset >= offs);
93  }
94 
95  void *GetData() { return fData; }
96 
97  // Get the requested interval, if possible
98  inline bool GetInterval(const void *buffer, long long begin_offs,
99  long long end_offs) {
100  if (!ContainsInterval(begin_offs, end_offs))
101  return FALSE;
102  memcpy((void *)buffer, ((char *)fData)+(begin_offs - fBeginOffset),
103  end_offs - begin_offs + 1);
104  return TRUE;
105  }
106 
107  // Get as many bytes as possible, starting from the beginning of the given
108  // interval
109  inline long GetPartialInterval(const void *buffer, long long begin_offs,
110  long long end_offs) {
111 
112  long long b = -1, e, l;
113 
114  if (begin_offs > end_offs) return 0;
115 
116  // Try to set the starting point, if contained in the given interval
117  if ( (begin_offs >= fBeginOffset) &&
118  (begin_offs <= fEndOffset) )
119  b = begin_offs;
120 
121  if (b < 0) return 0;
122 
123  // The starting point is in the interval. Let's get the minimum endpoint
124  e = xrdmin(end_offs, fEndOffset);
125 
126  l = e - b + 1;
127 
128  if (buffer && fData)
129  memcpy((void *)buffer, ((char *)fData)+(b - fBeginOffset), l);
130 
131  return l;
132  }
133 
134  inline long long GetTimestampTicks() { return(fTimestampTicks); }
135 
136  inline bool IsPlaceholder() { return fIsPlaceholder; }
137 
138  long Size() { return (fEndOffset - fBeginOffset + 1); }
139 
140  inline void Touch(long long ticksnow) { fTimestampTicks = ticksnow; }
141 
142  bool Pinned;
143 };
144 
145 //
146 // XrdClientReadCache
147 //
148 // The content of the cache. Not cache blocks, but
149 // variable length Items
150 //
152 
153 // A cache interval, extremes included
155  long long beginoffs;
156  long long endoffs;
157 };
158 
160 
162 private:
163 
164  long long fBytesHit; // Total number of bytes read with a cache hit
165  long long fBytesSubmitted; // Total number of bytes inserted
168  long long fMaxCacheSize;
169  long long fMissCount; // Counter of the cache misses
170  float fMissRate; // Miss rate
172  long long fReadsCounter; // Counter of all the attempted reads (hit or miss)
173  int fBlkRemPolicy; // The algorithm used to remove "old" chunks
174  long long fTimestampTickCounter; // Aging mechanism yuk!
175  long long fTotalByteCount;
176 
177  long long GetTimestampTick();
178  bool MakeFreeSpace(long long bytes);
179 
180  bool RemoveItem();
181  bool RemoveLRUItem();
182  bool RemoveFirstItem();
183 
184  inline void UpdatePerfCounters() {
185  if (fReadsCounter > 0)
186  fMissRate = (float)fMissCount / fReadsCounter;
187  if (fBytesSubmitted > 0)
188  fBytesUsefulness = (float)fBytesHit / fBytesSubmitted;
189  }
190 
191  int FindInsertionApprox(long long begin_offs);
192  int FindInsertionApprox_rec(int startidx, int endidx,
193  long long begin_offs);
194 public:
195 
196  // The algos available for the removal of "old" blocks
197  enum {
198  kRmBlk_LRU = 0,
200  kRmBlk_FIFO
201  };
202 
205 
206  long GetDataIfPresent(const void *buffer, long long begin_offs,
207  long long end_offs, bool PerfCalc,
208  XrdClientIntvList &missingblks, long &outstandingblks);
209 
210  void GetInfo(
211  // The actual cache size
212  int &size,
213 
214  // The number of bytes submitted since the beginning
215  long long &bytessubmitted,
216 
217  // The number of bytes found in the cache (estimate)
218  long long &byteshit,
219 
220  // The number of reads which did not find their data
221  // (estimate)
222  long long &misscount,
223 
224  // miss/totalreads ratio (estimate)
225  float &missrate,
226 
227  // number of read requests towards the cache
228  long long &readreqcnt,
229 
230  // ratio between bytes found / bytes submitted
231  float &bytesusefulness
232  );
233 
234  inline long long GetTotalByteCount() {
235  XrdSysMutexHelper m(fMutex);
236  return fTotalByteCount;
237  }
238 
239  void PutPlaceholder(long long begin_offs, long long end_offs);
240 
241  inline void PrintPerfCounters() {
242  XrdSysMutexHelper m(fMutex);
243 
244  cout << "Low level caching info:" << endl;
245  cout << " StallsRate=" << fMissRate << endl;
246  cout << " StallsCount=" << fMissCount << endl;
247  cout << " ReadsCounter=" << fReadsCounter << endl;
248  cout << " BytesUsefulness=" << fBytesUsefulness << endl;
249  cout << " BytesSubmitted=" << fBytesSubmitted << " BytesHit=" <<
250  fBytesHit << endl << endl;
251  }
252 
253 
254  void PrintCache();
255 
256  void SubmitXMessage(XrdClientMessage *xmsg, long long begin_offs,
257  long long end_offs);
258 
259  bool SubmitRawData(const void *buffer, long long begin_offs,
260  long long end_offs, bool pinned=false);
261 
262  void RemoveItems(bool leavepinned=true);
263  void RemoveItems(long long begin_offs, long long end_offs, bool remove_overlapped = false);
264  void RemovePlaceholders();
265 
266 
267  void SetSize(int sz) {
268  fMaxCacheSize = sz;
269  }
270 
271  void SetBlkRemovalPolicy(int p) {
272  fBlkRemPolicy = p;
273  }
274 
275  void UnPinCacheBlk(long long begin_offs, long long end_offs);
276  void *FindBlk(long long begin_offs, long long end_offs);
277 
278  // To check if a block dimension will fit into the cache
279  inline bool WillFit(long long bc) {
280  XrdSysMutexHelper m(fMutex);
281  return (bc < fMaxCacheSize);
282  }
283 
284 };
285 #endif
XrdClientReadCacheItem(const void *buffer, long long begin_offs, long long end_offs, long long ticksnow, bool placeholder=false)
bool WillFit(long long bc)
bool ContainedInInterval(long long begin_offs, long long end_offs)
#define XrdSysRecMutex
Definition: XrdSysToOuc.h:18
bool ContainsOffset(long long offs)
bool IntersectInterval(long long begin_offs, long long end_offs)
long GetPartialInterval(const void *buffer, long long begin_offs, long long end_offs)
void SetBlkRemovalPolicy(int p)
bool ContainsInterval(long long begin_offs, long long end_offs)
void Touch(long long ticksnow)
#define XrdSysMutexHelper
Definition: XrdSysToOuc.h:17
XrdClientVector< XrdClientReadCacheItem * > ItemVect
TMarker * m
Definition: textangle.C:8
TLine * l
Definition: textangle.C:4
#define xrdmin(a, b)
#define TRUE
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
XrdClientVector< XrdClientCacheInterval > XrdClientIntvList
#define FALSE
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
bool GetInterval(const void *buffer, long long begin_offs, long long end_offs)