xrootd
XrdOucCache.hh
Go to the documentation of this file.
1 #ifndef __XRDOUCCACHE_HH__
2 #define __XRDOUCCACHE_HH__
3 /******************************************************************************/
4 /* */
5 /* X r d O u c C a c h e . h h */
6 /* */
7 /* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* All Rights Reserved */
9 /* Produced by Andrew Hanushevsky for Stanford University under contract */
10 /* DE-AC02-76-SFO0515 with the Department of Energy */
11 /* */
12 /* This file is part of the XRootD software suite. */
13 /* */
14 /* XRootD is free software: you can redistribute it and/or modify it under */
15 /* the terms of the GNU Lesser General Public License as published by the */
16 /* Free Software Foundation, either version 3 of the License, or (at your */
17 /* option) any later version. */
18 /* */
19 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
20 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
21 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
22 /* License for more details. */
23 /* */
24 /* You should have received a copy of the GNU Lesser General Public License */
25 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
26 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
27 /* */
28 /* The copyright holder's institutional names and contributor's names may not */
29 /* be used to endorse or promote products derived from this software without */
30 /* specific prior written permission of the institution or contributor. */
31 /******************************************************************************/
32 
33 #include "XrdOuc/XrdOucIOVec.hh"
34 #include "XrdSys/XrdSysPthread.hh"
35 
36 /* The classes defined here can be used to implement a general cache for
37  data from an arbitrary source (e.g. files, sockets, etc); as follows:
38 
39  1. Create an instance of XrdOucCacheIO. This object is used to actually
40  bring in missing data into the cache or write out dirty cache pages.
41  There can be many instances of this class, as needed. However, make sure
42  that there is a 1-to-1 unique correspondence between data and its CacheIO
43  object. Violating this may cause the same data to be cached multiple
44  times and if the cache is writable the data may be inconsistent!
45 
46  2. Create an instance of XrdOucCache. You can specify various cache
47  handling parameters (see the class definition). You can also define
48  additional instances if you want more than one cache. The specific cache
49  you create will be defined by an implementation that derives from these
50  classes. For instance, an implementation of a memory cache is defined
51  in "XrdOucCacheDram.hh".
52 
53  3. Use the Attach() method in XrdOucCache to attach your XrdOucCacheIO
54  object with a cache instance. The method returns a remanufactured
55  XrdOucCacheIO object that interposes the cache in front of the original
56  XrdOucCacheIO. This allows you to transparently use the cache.
57 
58  4. When finished using the remanufactured XrdOucCacheIO object, use its
59  Detach() method to remove the association from the cache. Other actions
60  are defined by the actual implementation. For instance XrdOucCacheDram
61  also releases any assigned cache pages, writes out any dirty pages, and
62  may optionally delete the object when all references have been removed.
63 
64  5. You may delete cache instances as well. Just be sure that no associations
65  still exist using the XrdOucCache::isAttached() method. Otherwise, the
66  cache destructor will wait until all attached objects are detached.
67 
68  Example:
69  class physIO : public XrdOucCacheIO {...}; // Define required methods
70  class xCache : public XrdOucCache {...}; // The cache implementation
71  XrdOucCache::Parms myParms; // Set any desired parameters
72  XrdOucCache *myCache;
73  XrdOucCacheIO *cacheIO;
74  xCache theCache; // Implementation instance
75 
76  myCache = theCache.Create(myParms); // Create a cache instance
77  cacheIO = myCache->Attach(physIO); // Interpose the cache
78 
79  // Use cacheIO (fronted by myCache) instead of physIO. When done...
80 
81  delete cacheIO->Detach(); // Deletes cacheIO and physIO
82 */
83 
84 /******************************************************************************/
85 /* C l a s s X r d O u c C a c h e S t a t s */
86 /******************************************************************************/
87 
88 /* The XrdOucCacheStats object holds statistics on cache usage. It is available
89  in for each XrdOucCacheIO and each XrdOucCache object. The former usually
90  identifies a specific file while the latter provides summary information.
91 */
92 
94 {
95 public:
96 long long BytesPead; // Bytes read via preread (not included in BytesRead)
97 long long BytesRead; // Total number of bytes read into the cache
98 long long BytesGet; // Number of bytes delivered from the cache
99 long long BytesPass; // Number of bytes read but not cached
100 long long BytesWrite; // Total number of bytes written from the cache
101 long long BytesPut; // Number of bytes updated in the cache
102 int Hits; // Number of times wanted data was in the cache
103 int Miss; // Number of times wanted data was *not* in the cache
104 int HitsPR; // Number of pages wanted data was just preread
105 int MissPR; // Number of pages wanted data was just read
106 
107 inline void Get(XrdOucCacheStats &Dst)
108  {sMutex.Lock();
109  Dst.BytesRead = BytesPead; Dst.BytesGet = BytesRead;
110  Dst.BytesPass = BytesPass;
111  Dst.BytesWrite = BytesWrite; Dst.BytesPut = BytesPut;
112  Dst.Hits = Hits; Dst.Miss = Miss;
113  Dst.HitsPR = HitsPR; Dst.MissPR = MissPR;
114  sMutex.UnLock();
115  }
116 
117 inline void Add(XrdOucCacheStats &Src)
118  {sMutex.Lock();
119  BytesRead += Src.BytesPead; BytesGet += Src.BytesRead;
120  BytesPass += Src.BytesPass;
121  BytesWrite += Src.BytesWrite; BytesPut += Src.BytesPut;
122  Hits += Src.Hits; Miss += Src.Miss;
123  HitsPR += Src.HitsPR; MissPR += Src.MissPR;
124  sMutex.UnLock();
125  }
126 
127 inline void Add(long long &Dest, int &Val)
128  {sMutex.Lock(); Dest += Val; sMutex.UnLock();}
129 
130 inline void Lock() {sMutex.Lock();}
131 inline void UnLock() {sMutex.UnLock();}
132 
134  BytesPass(0), BytesWrite(0), BytesPut(0),
135  Hits(0), Miss(0),
136  HitsPR(0), MissPR(0) {}
138 private:
140 };
141 
142 /******************************************************************************/
143 /* X r d O u c C a c h e I O C B */
144 /******************************************************************************/
145 
146 //-----------------------------------------------------------------------------
149 //-----------------------------------------------------------------------------
150 
152 {
153 public:
154 
155 //------------------------------------------------------------------------------
161 //------------------------------------------------------------------------------
162 virtual
163 void Done(int result) = 0;
164 
166 virtual ~XrdOucCacheIOCB() {}
167 };
168 
169 /******************************************************************************/
170 /* C l a s s X r d O u c C a c h e I O */
171 /******************************************************************************/
172 
173 /* The XrdOucCacheIO object is responsible for interacting with the original
174  data source/target. It can be used with or without a front-end cache.
175 
176  Six abstract methods are provided FSize(), Path(), Read(), Sync(), Trunc(),
177  and Write(). You must provide implementations for each as described below.
178 
179  Four additional virtual methods are pre-defined: Base(), Detach(), and
180  Preread() (2x). Normally, there is no need to over-ride these methods.
181 
182  Finally, each object carries with it a XrdOucCacheStats object.
183 */
184 
186 {
187 public:
188 
189 // FSize() returns the current size of the file associated with this object.
190 
191 // Success: size of the file in bytes.
192 // Failure: -errno associated with the error.
193 virtual
194 long long FSize() = 0;
195 
196 // Path() returns the path name associated with this object.
197 //
198 virtual
199 const char *Path() = 0;
200 
201 // Read() places Length bytes in Buffer from a data source at Offset.
202 // When fronted by a cache, the cache is inspected first.
203 
204 // Success: actual number of bytes placed in Buffer.
205 // Failure: -errno associated with the error.
206 virtual
207 int Read (char *Buffer, long long Offset, int Length) = 0;
208 
209 // ReadV() Performs a vector of read requests. When fronted by a cache,
210 // the cache is inspected first. By batching requests, it provides
211 // us the ability to skip expensive network round trips.
212 // If any reads fail or return short, the entire operation should
213 // fail.
214 
215 // Success: actual number of bytes read.
216 // Failure: -errno associated with the read error.
217 virtual
218 int ReadV(const XrdOucIOVec *readV, int n)
219  {int nbytes = 0, curCount = 0;
220  for (int i=0; i<n; i++)
221  {curCount = Read(readV[i].data,
222  readV[i].offset,
223  readV[i].size);
224  if (curCount != readV[i].size)
225  {if (curCount < 0) return curCount;
226  return -ESPIPE;
227  }
228  nbytes += curCount;
229  }
230  return nbytes;
231  }
232 
233 // Sync() copies any outstanding modified bytes to the target.
234 
235 // Success: return 0.
236 // Failure: -errno associated with the error.
237 virtual
238 int Sync() = 0;
239 
240 // Trunc() truncates the file to the specified offset.
241 
242 // Success: return 0.
243 // Failure: -errno associated with the error.
244 virtual
245 int Trunc(long long Offset) = 0;
246 
247 
248 // Write() takes Length bytes in Buffer and writes to a data target at Offset.
249 // When fronted by a cache, the cache is updated as well.
250 
251 // Success: actual number of bytes copied from the Buffer.
252 // Failure: -errno associated with the error.
253 virtual
254 int Write(char *Buffer, long long Offset, int Length) = 0;
255 
256 // Base() returns the underlying XrdOucCacheIO object being used.
257 //
258 virtual XrdOucCacheIO *Base() {return this;}
259 
260 // Detach() detaches the object from the cache. It must be called instead of
261 // using the delete operator since CacheIO objects may have multiple
262 // outstanding references and actual deletion may need to be defered.
263 // Detach() returns the underlying CacheIO object when the last
264 // reference has been removed and 0 otherwise. This allows to say
265 // something like "delete ioP->Detach()" if you want to make sure you
266 // delete the underlying object as well. Alternatively, use the optADB
267 // option when attaching a CacheIO object to a cache. This will delete
268 // underlying object and always return 0 to avoid a double delete.
269 // When not fronted by a cache, Detach() always returns itself. This
270 // makes its use consistent whether or not a cache is employed.
271 //
272 virtual XrdOucCacheIO *Detach() {return this;}
273 
274 
275 // ioActive() returns true if there is any ongoing IO operation. The function is
276 // used in XrdPosixXrootd::Close() to check if destruction od PosixFile
277 // has to be done in a separate task.
278 virtual bool ioActive() { return false; }
279 
280 // Preread() places Length bytes into the cache from a data source at Offset.
281 // When there is no cache or the associated cache does not support or
282 // allow pre-reads, it's a no-op. Cache placement limits do not apply.
283 // To maximize parallelism, Peread() should called *after* obtaining
284 // the wanted bytes using Read(). If the cache implementation supports
285 // automatic prereads; you can setup parameters on how this should be
286 // done using the next the next structure and method. The following
287 // options can be specified:
288 //
289 static const int SingleUse = 0x0001; // Mark pages for single use
290 
291 virtual
292 void Preread (long long Offset, int Length, int Opts=0)
293 {
294  (void)Offset; (void)Length; (void)Opts;
295 }
296 
297 // The following structure describes automatic preread parameters. These can be
298 // set at any time for each XrdOucCacheIO object. It can also be specified when
299 // creating a cache to establish the defaults (see XrdOucCache::Create()).
300 // Generally, an implementation that supports prereads should disable small
301 // prereads when minPages or loBound is set to zero; and should disable large
302 // prereads when maxiRead or maxPages is set to zero. Refer to the actual
303 // derived class implementation on how the cache handles prereads.
304 //
305 struct aprParms
306  {int Trigger; // preread if (rdln < Trigger) (0 -> pagesize+1)
307  int prRecalc; // Recalc pr efficiency every prRecalc bytes (0->50M)
308  int Reserve4;
309  short minPages; // If rdln/pgsz < min, preread minPages (0->off)
310  signed
311  char minPerf; // Minimum auto preread performance required (0->n/a)
312  char Reserve1;
313 
315  minPages(0), minPerf(90), Reserve1(0)
316  {}
317  };
318 
319 virtual
320 void Preread(aprParms &Parms) { (void)Parms; }
321 
322 // Here is where the stats about cache and I/O usage reside. There
323 // is a summary object in the associated cache as well.
324 //
326 
327 virtual ~XrdOucCacheIO() {} // Always use Detach() instead of direct delete!
328 };
329 
330 /******************************************************************************/
331 /* C l a s s X r d O u c C a c h e */
332 /******************************************************************************/
333 
334 /* The XrdOucCache class is used to define an instance of a cache. There can
335  be many such instances. Each instance is associated with one or more
336  XrdOucCacheIO objects. Use the Attach() method in this class to create
337  such associations.
338 */
339 
341 {
342 public:
343 
344 /* Attach() must be called to obtain a new XrdOucCacheIO object that fronts an
345  existing XrdOucCacheIO object with this cache.
346  Upon success a pointer to a new XrdOucCacheIO object is returned
347  and must be used to read and write data with the cache interposed.
348  Upon failure, the original XrdOucCacheIO object is returned with
349  errno set. You can continue using the object without any cache.
350  The following Attach() options are available and, when specified,
351  override the default options associated with the cache, except for
352  optRW, optNEW, and optWIN which are valid only for a r/w cache.
353 */
354 static const int optADB = 0x1000; // Automatically delete underlying CacheIO
355 static const int optFIS = 0x0001; // File is Structured (e.g. root file)
356 static const int optFIU = 0x0002; // File is Unstructured (e.g. unix file)
357 static const int optRW = 0x0004; // File is read/write (o/w read/only)
358 static const int optNEW = 0x0014; // File is new -> optRW (o/w read to write)
359 static const int optWIN = 0x0024; // File is new -> optRW use write-in cache
360 
361 virtual
362 XrdOucCacheIO *Attach(XrdOucCacheIO *ioP, int Options=0) = 0;
363 
364 /* isAttached()
365  Returns the number of CacheIO objects attached to this cache.
366  Hence, 0 (false) if none and true otherwise.
367 */
368 virtual
369 int isAttached() {return 0;}
370 
371 /* You must first create an instance of a cache using the Create() method.
372  The Parms structure is used to pass parameters about the cache and should
373  be filled in with values meaningful to the type of cache being created.
374  The fields below, while oriented toward a memory cache, are sufficiently
375  generic to apply to almost any kind of cache. Refer to the actual
376  implementation in the derived class to see how these values are used.
377 */
378 struct Parms
379  {long long CacheSize; // Size of cache in bytes (default 100MB)
380  int PageSize; // Size of each page in bytes (default 32KB)
381  int Max2Cache; // Largest read to cache (default PageSize)
382  int MaxFiles; // Maximum number of files (default 256 or 8K)
383  int Options; // Options as defined below (default r/o cache)
384  short minPages; // Minum number of pages (default 256)
385  short Reserve1; // Reserved for future use
386  int Reserve2; // Reserved for future use
387 
388  Parms() : CacheSize(104857600), PageSize(32768),
389  Max2Cache(0), MaxFiles(0), Options(0),
390  minPages(0), Reserve1(0), Reserve2(0) {}
391  };
392 
393 // Valid option values in Parms::Options
394 //
395 static const int
396 isServer = 0x0010; // This is server application (as opposed to a user app).
397  // Appropriate internal optimizations will be used.
398 static const int
399 isStructured = 0x0020; // Optimize for structured files (e.g. root).
400 
401 static const int
402 canPreRead = 0x0040; // Enable pre-read operations (o/w ignored)
403 
404 static const int
405 logStats = 0x0080; // Display statistics upon detach
406 
407 static const int
408 Serialized = 0x0004; // Caller ensures MRSW semantics
409 
410 static const int
411 ioMTSafe = 0x0008; // CacheIO object is MT-safe
412 
413 static const int
414 Debug = 0x0003; // Produce some debug messages (levels 0, 1, 2, or 3)
415 
416 /* Create() Creates an instance of a cache using the specified parameters.
417  You must pass the cache parms and optionally any automatic
418  pre-read parameters that will be used as future defaults.
419  Upon success, returns a pointer to the cache. Otherwise, a null
420  pointer is returned with errno set to indicate the problem.
421 */
422 virtual
423 XrdOucCache *Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0) = 0;
424 
425 
426 // Propagate Unlink client request from posix layer to cache.
427 virtual
428 int Unlink(const char* /*path*/) { return 0; }
429 
430 // Propagate Rmdir client request from posix layer to cache.
431 virtual
432 int Rmdir(const char* /*path*/) { return 0; }
433 
434 // Propagate Rename client request from posix layer to cache.
435 virtual
436 int Rename(const char* /*path*/, const char* /*newPath*/) { return 0; }
437 
438 // Propagate Truncate client request from posix layer to cache.
439 virtual
440 int Truncate(const char* /*path*/, off_t /*size*/) { return 0; }
441 
442 /* The following holds statistics for the cache itself. It is updated as
443  associated cacheIO objects are deleted and their statistics are added.
444 */
446 
448 virtual ~XrdOucCache() {}
449 };
450 
451 /******************************************************************************/
452 /* C r e a t i n g C a c h e P l u g - I n s */
453 /******************************************************************************/
454 
455 /* You can create a cache plug-in for those parts of the xrootd system that
456  allow a dynamically selectable cache implementation (e.g. the proxy server
457  plug-in supports cache plug-ins via the pss.cachelib directive).
458 
459  Your plug-in must exist in a shared library and have the following extern C
460  function defined:
461 
462  extern "C"
463  {
464  XrdOucCache *XrdOucGetCache(XrdSysLogger *Logger, // Where messages go
465  const char *Config, // Config file used
466  const char *Parms); // Optional parm string
467  }
468 
469  When Logger is null, you should use cerr to output messages. Otherwise,
470  tie an instance XrdSysError to the passed logger.
471  When Config is null, no configuration file is present. Otherwise, you need
472  additional configuration information you should get it
473  from that file in order to support single configuration.
474  When Parms is null, no parameter string was specified.
475 
476  The call should return an instance of an XrdOucCache object upon success and
477  a null pointer otherwise. The instance is used to create actual caches using
478  the object's Create() method.
479 */
480 #endif
XrdOucCacheStats()
Definition: XrdOucCache.hh:133
virtual XrdOucCacheIO * Base()
Definition: XrdOucCache.hh:258
long long BytesPass
Definition: XrdOucCache.hh:99
virtual XrdOucCacheIO * Attach(XrdOucCacheIO *ioP, int Options=0)=0
virtual void Preread(aprParms &Parms)
Definition: XrdOucCache.hh:320
Parms()
Definition: XrdOucCache.hh:388
static const int ioMTSafe
Definition: XrdOucCache.hh:411
static const int Debug
Definition: XrdOucCache.hh:414
~XrdOucCacheStats()
Definition: XrdOucCache.hh:137
static const int isStructured
Definition: XrdOucCache.hh:399
static const int SingleUse
Definition: XrdOucCache.hh:289
aprParms()
Definition: XrdOucCache.hh:314
virtual int Truncate(const char *, off_t)
Definition: XrdOucCache.hh:440
XrdOucCache()
Definition: XrdOucCache.hh:447
static const int logStats
Definition: XrdOucCache.hh:405
Definition: XrdOucCache.hh:185
virtual int Read(char *Buffer, long long Offset, int Length)=0
int Reserve2
Definition: XrdOucCache.hh:386
virtual int Rmdir(const char *)
Definition: XrdOucCache.hh:432
static const int optNEW
Definition: XrdOucCache.hh:358
void Add(XrdOucCacheStats &Src)
Definition: XrdOucCache.hh:117
virtual int Trunc(long long Offset)=0
int Max2Cache
Definition: XrdOucCache.hh:381
int MaxFiles
Definition: XrdOucCache.hh:382
virtual int Write(char *Buffer, long long Offset, int Length)=0
long long BytesGet
Definition: XrdOucCache.hh:98
XrdOucCacheStats Stats
Definition: XrdOucCache.hh:445
int Options
Definition: XrdOucCache.hh:383
void Get(XrdOucCacheStats &Dst)
Definition: XrdOucCache.hh:107
short minPages
Definition: XrdOucCache.hh:309
short Reserve1
Definition: XrdOucCache.hh:385
static const int optFIU
Definition: XrdOucCache.hh:356
Definition: XrdSysPthread.hh:140
long long BytesRead
Definition: XrdOucCache.hh:97
int Hits
Definition: XrdOucCache.hh:102
Definition: XrdOucCache.hh:340
int Miss
Definition: XrdOucCache.hh:103
static const int optFIS
Definition: XrdOucCache.hh:355
virtual const char * Path()=0
virtual int Rename(const char *, const char *)
Definition: XrdOucCache.hh:436
virtual int ReadV(const XrdOucIOVec *readV, int n)
Definition: XrdOucCache.hh:218
int HitsPR
Definition: XrdOucCache.hh:104
Definition: XrdOucIOVec.hh:40
int Reserve4
Definition: XrdOucCache.hh:308
long long BytesPut
Definition: XrdOucCache.hh:101
virtual ~XrdOucCacheIO()
Definition: XrdOucCache.hh:327
long long CacheSize
Definition: XrdOucCache.hh:379
Definition: XrdOucCache.hh:305
static const int optADB
Definition: XrdOucCache.hh:354
static const int canPreRead
Definition: XrdOucCache.hh:402
static const int isServer
Definition: XrdOucCache.hh:396
virtual bool ioActive()
Definition: XrdOucCache.hh:278
Definition: XrdOucCache.hh:151
int PageSize
Definition: XrdOucCache.hh:380
virtual int Unlink(const char *)
Definition: XrdOucCache.hh:428
char Reserve1
Definition: XrdOucCache.hh:312
virtual XrdOucCacheIO * Detach()
Definition: XrdOucCache.hh:272
void Lock()
Definition: XrdSysPthread.hh:149
long long BytesPead
Definition: XrdOucCache.hh:96
virtual int isAttached()
Definition: XrdOucCache.hh:369
virtual int Sync()=0
int Trigger
Definition: XrdOucCache.hh:306
int MissPR
Definition: XrdOucCache.hh:105
void UnLock()
Definition: XrdOucCache.hh:131
XrdSysMutex sMutex
Definition: XrdOucCache.hh:139
static const int optWIN
Definition: XrdOucCache.hh:359
void Lock()
Definition: XrdOucCache.hh:130
static const int optRW
Definition: XrdOucCache.hh:357
long long BytesWrite
Definition: XrdOucCache.hh:100
Definition: XrdOucCache.hh:93
virtual ~XrdOucCache()
Definition: XrdOucCache.hh:448
virtual void Preread(long long Offset, int Length, int Opts=0)
Definition: XrdOucCache.hh:292
virtual long long FSize()=0
Definition: XrdOucCache.hh:378
void UnLock()
Definition: XrdSysPthread.hh:151
int prRecalc
Definition: XrdOucCache.hh:307
short minPages
Definition: XrdOucCache.hh:384
void Add(long long &Dest, int &Val)
Definition: XrdOucCache.hh:127
signed char minPerf
Definition: XrdOucCache.hh:311
virtual XrdOucCache * Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0)=0
static const int Serialized
Definition: XrdOucCache.hh:408
virtual ~XrdOucCacheIOCB()
Definition: XrdOucCache.hh:166
XrdOucCacheStats Statistics
Definition: XrdOucCache.hh:325
XrdOucCacheIOCB()
Definition: XrdOucCache.hh:165
virtual void Done(int result)=0