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 
34 #include "XrdOuc/XrdOucIOVec.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 /* X r d O u c C a c h e I O C B */
86 /******************************************************************************/
87 
88 //-----------------------------------------------------------------------------
91 //-----------------------------------------------------------------------------
92 
94 {
95 public:
96 
97 //------------------------------------------------------------------------------
103 //------------------------------------------------------------------------------
104 virtual
105 void Done(int result) = 0;
106 
108 virtual ~XrdOucCacheIOCB() {}
109 };
110 
111 /******************************************************************************/
112 /* C l a s s X r d O u c C a c h e I O */
113 /******************************************************************************/
114 
115 /* The XrdOucCacheIO object is responsible for interacting with the original
116  data source/target. It can be used with or without a front-end cache.
117 
118  Six abstract methods are provided FSize(), Path(), Read(), Sync(), Trunc(),
119  and Write(). You must provide implementations for each as described below.
120 
121  Four additional virtual methods are pre-defined: Base(), Detach(), and
122  Preread() (2x). Normally, there is no need to over-ride these methods.
123 
124  Finally, each object carries with it a XrdOucCacheStats object.
125 */
126 
128 {
129 public:
130 
131 // FSize() returns the current size of the file associated with this object.
132 
133 // Success: size of the file in bytes.
134 // Failure: -errno associated with the error.
135 virtual
136 long long FSize() = 0;
137 
138 // Path() returns the path name associated with this object.
139 //
140 virtual
141 const char *Path() = 0;
142 
143 // Read() places Length bytes in Buffer from a data source at Offset.
144 // When fronted by a cache, the cache is inspected first.
145 
146 // Success: actual number of bytes placed in Buffer.
147 // Failure: -errno associated with the error.
148 virtual
149 int Read (char *Buffer, long long Offset, int Length) = 0;
150 
151 // ReadV() Performs a vector of read requests. When fronted by a cache,
152 // the cache is inspected first. By batching requests, it provides
153 // us the ability to skip expensive network round trips.
154 // If any reads fail or return short, the entire operation should
155 // fail.
156 
157 // Success: actual number of bytes read.
158 // Failure: -errno associated with the read error.
159 virtual
160 int ReadV(const XrdOucIOVec *readV, int n)
161  {int nbytes = 0, curCount = 0;
162  for (int i=0; i<n; i++)
163  {curCount = Read(readV[i].data,
164  readV[i].offset,
165  readV[i].size);
166  if (curCount != readV[i].size)
167  {if (curCount < 0) return curCount;
168  return -ESPIPE;
169  }
170  nbytes += curCount;
171  }
172  return nbytes;
173  }
174 
175 // Sync() copies any outstanding modified bytes to the target.
176 
177 // Success: return 0.
178 // Failure: -errno associated with the error.
179 virtual
180 int Sync() = 0;
181 
182 // Trunc() truncates the file to the specified offset.
183 
184 // Success: return 0.
185 // Failure: -errno associated with the error.
186 virtual
187 int Trunc(long long Offset) = 0;
188 
189 
190 // Write() takes Length bytes in Buffer and writes to a data target at Offset.
191 // When fronted by a cache, the cache is updated as well.
192 
193 // Success: actual number of bytes copied from the Buffer.
194 // Failure: -errno associated with the error.
195 virtual
196 int Write(char *Buffer, long long Offset, int Length) = 0;
197 
198 // Base() returns the underlying XrdOucCacheIO object being used.
199 //
200 virtual XrdOucCacheIO *Base() {return this;}
201 
202 // Detach() detaches the object from the cache. It must be called instead of
203 // using the delete operator since CacheIO objects may have multiple
204 // outstanding references and actual deletion may need to be defered.
205 // Detach() returns the underlying CacheIO object when the last
206 // reference has been removed and 0 otherwise. This allows to say
207 // something like "delete ioP->Detach()" if you want to make sure you
208 // delete the underlying object as well. Alternatively, use the optADB
209 // option when attaching a CacheIO object to a cache. This will delete
210 // underlying object and always return 0 to avoid a double delete.
211 // When not fronted by a cache, Detach() always returns itself. This
212 // makes its use consistent whether or not a cache is employed.
213 //
214 virtual XrdOucCacheIO *Detach() {return this;}
215 
216 
217 // ioActive() returns true if there is any ongoing IO operation. The function is
218 // used in XrdPosixXrootd::Close() to check if destruction od PosixFile
219 // has to be done in a separate task.
220 virtual bool ioActive() { return false; }
221 
222 // Preread() places Length bytes into the cache from a data source at Offset.
223 // When there is no cache or the associated cache does not support or
224 // allow pre-reads, it's a no-op. Cache placement limits do not apply.
225 // To maximize parallelism, Peread() should called *after* obtaining
226 // the wanted bytes using Read(). If the cache implementation supports
227 // automatic prereads; you can setup parameters on how this should be
228 // done using the next the next structure and method. The following
229 // options can be specified:
230 //
231 static const int SingleUse = 0x0001; // Mark pages for single use
232 
233 virtual
234 void Preread (long long Offset, int Length, int Opts=0)
235 {
236  (void)Offset; (void)Length; (void)Opts;
237 }
238 
239 // The following structure describes automatic preread parameters. These can be
240 // set at any time for each XrdOucCacheIO object. It can also be specified when
241 // creating a cache to establish the defaults (see XrdOucCache::Create()).
242 // Generally, an implementation that supports prereads should disable small
243 // prereads when minPages or loBound is set to zero; and should disable large
244 // prereads when maxiRead or maxPages is set to zero. Refer to the actual
245 // derived class implementation on how the cache handles prereads.
246 //
247 struct aprParms
248  {int Trigger; // preread if (rdln < Trigger) (0 -> pagesize+1)
249  int prRecalc; // Recalc pr efficiency every prRecalc bytes (0->50M)
250  int Reserve4;
251  short minPages; // If rdln/pgsz < min, preread minPages (0->off)
252  signed
253  char minPerf; // Minimum auto preread performance required (0->n/a)
254  char Reserve1;
255 
257  minPages(0), minPerf(90), Reserve1(0)
258  {}
259  };
260 
261 virtual
262 void Preread(aprParms &Parms) { (void)Parms; }
263 
264 // Here is where the stats about cache and I/O usage reside. There
265 // is a summary object in the associated cache as well.
266 //
268 
269 virtual ~XrdOucCacheIO() {} // Always use Detach() instead of direct delete!
270 };
271 
272 /******************************************************************************/
273 /* C l a s s X r d O u c C a c h e */
274 /******************************************************************************/
275 
276 /* The XrdOucCache class is used to define an instance of a cache. There can
277  be many such instances. Each instance is associated with one or more
278  XrdOucCacheIO objects. Use the Attach() method in this class to create
279  such associations.
280 */
281 
283 {
284 public:
285 
286 /* Attach() must be called to obtain a new XrdOucCacheIO object that fronts an
287  existing XrdOucCacheIO object with this cache.
288  Upon success a pointer to a new XrdOucCacheIO object is returned
289  and must be used to read and write data with the cache interposed.
290  Upon failure, the original XrdOucCacheIO object is returned with
291  errno set. You can continue using the object without any cache.
292  The following Attach() options are available and, when specified,
293  override the default options associated with the cache, except for
294  optRW, optNEW, and optWIN which are valid only for a r/w cache.
295 */
296 static const int optADB = 0x1000; // Automatically delete underlying CacheIO
297 static const int optFIS = 0x0001; // File is Structured (e.g. root file)
298 static const int optFIU = 0x0002; // File is Unstructured (e.g. unix file)
299 static const int optRW = 0x0004; // File is read/write (o/w read/only)
300 static const int optNEW = 0x0014; // File is new -> optRW (o/w read to write)
301 static const int optWIN = 0x0024; // File is new -> optRW use write-in cache
302 
303 virtual
304 XrdOucCacheIO *Attach(XrdOucCacheIO *ioP, int Options=0) = 0;
305 
306 /* isAttached()
307  Returns the number of CacheIO objects attached to this cache.
308  Hence, 0 (false) if none and true otherwise.
309 */
310 virtual
311 int isAttached() {return 0;}
312 
313 /* You must first create an instance of a cache using the Create() method.
314  The Parms structure is used to pass parameters about the cache and should
315  be filled in with values meaningful to the type of cache being created.
316  The fields below, while oriented toward a memory cache, are sufficiently
317  generic to apply to almost any kind of cache. Refer to the actual
318  implementation in the derived class to see how these values are used.
319 */
320 struct Parms
321  {long long CacheSize; // Size of cache in bytes (default 100MB)
322  int PageSize; // Size of each page in bytes (default 32KB)
323  int Max2Cache; // Largest read to cache (default PageSize)
324  int MaxFiles; // Maximum number of files (default 256 or 8K)
325  int Options; // Options as defined below (default r/o cache)
326  short minPages; // Minum number of pages (default 256)
327  short Reserve1; // Reserved for future use
328  int Reserve2; // Reserved for future use
329 
330  Parms() : CacheSize(104857600), PageSize(32768),
331  Max2Cache(0), MaxFiles(0), Options(0),
332  minPages(0), Reserve1(0), Reserve2(0) {}
333  };
334 
335 // Valid option values in Parms::Options
336 //
337 static const int
338 isServer = 0x0010; // This is server application (as opposed to a user app).
339  // Appropriate internal optimizations will be used.
340 static const int
341 isStructured = 0x0020; // Optimize for structured files (e.g. root).
342 
343 static const int
344 canPreRead = 0x0040; // Enable pre-read operations (o/w ignored)
345 
346 static const int
347 logStats = 0x0080; // Display statistics upon detach
348 
349 static const int
350 Serialized = 0x0004; // Caller ensures MRSW semantics
351 
352 static const int
353 ioMTSafe = 0x0008; // CacheIO object is MT-safe
354 
355 static const int
356 Debug = 0x0003; // Produce some debug messages (levels 0, 1, 2, or 3)
357 
358 /* Create() Creates an instance of a cache using the specified parameters.
359  You must pass the cache parms and optionally any automatic
360  pre-read parameters that will be used as future defaults.
361  Upon success, returns a pointer to the cache. Otherwise, a null
362  pointer is returned with errno set to indicate the problem.
363 */
364 virtual
365 XrdOucCache *Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0) = 0;
366 
367 
368 // Propagate Unlink client request from posix layer to cache.
369 virtual
370 int Unlink(const char* /*path*/) { return 0; }
371 
372 // Propagate Rmdir client request from posix layer to cache.
373 virtual
374 int Rmdir(const char* /*path*/) { return 0; }
375 
376 // Propagate Rename client request from posix layer to cache.
377 virtual
378 int Rename(const char* /*path*/, const char* /*newPath*/) { return 0; }
379 
380 // Propagate Truncate client request from posix layer to cache.
381 virtual
382 int Truncate(const char* /*path*/, off_t /*size*/) { return 0; }
383 
384 /* The following holds statistics for the cache itself. It is updated as
385  associated cacheIO objects are deleted and their statistics are added.
386 */
388 
390 virtual ~XrdOucCache() {}
391 };
392 
393 /******************************************************************************/
394 /* C r e a t i n g C a c h e P l u g - I n s */
395 /******************************************************************************/
396 
397 /* You can create a cache plug-in for those parts of the xrootd system that
398  allow a dynamically selectable cache implementation (e.g. the proxy server
399  plug-in supports cache plug-ins via the pss.cachelib directive).
400 
401  Your plug-in must exist in a shared library and have the following extern C
402  function defined:
403 
404  extern "C"
405  {
406  XrdOucCache *XrdOucGetCache(XrdSysLogger *Logger, // Where messages go
407  const char *Config, // Config file used
408  const char *Parms); // Optional parm string
409  }
410 
411  When Logger is null, you should use cerr to output messages. Otherwise,
412  tie an instance XrdSysError to the passed logger.
413  When Config is null, no configuration file is present. Otherwise, you need
414  additional configuration information you should get it
415  from that file in order to support single configuration.
416  When Parms is null, no parameter string was specified.
417 
418  The call should return an instance of an XrdOucCache object upon success and
419  a null pointer otherwise. The instance is used to create actual caches using
420  the object's Create() method.
421 */
422 #endif
XrdOucCache::ioMTSafe
static const int ioMTSafe
Definition: XrdOucCache.hh:353
XrdOucCache::Create
virtual XrdOucCache * Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0)=0
XrdOucCache::optNEW
static const int optNEW
Definition: XrdOucCache.hh:300
XrdOucCacheIOCB::XrdOucCacheIOCB
XrdOucCacheIOCB()
Definition: XrdOucCache.hh:107
XrdOucCache::Truncate
virtual int Truncate(const char *, off_t)
Definition: XrdOucCache.hh:382
XrdOucCacheIO
Definition: XrdOucCache.hh:127
XrdOucCache::Parms::PageSize
int PageSize
Definition: XrdOucCache.hh:322
XrdOucCacheIO::~XrdOucCacheIO
virtual ~XrdOucCacheIO()
Definition: XrdOucCache.hh:269
XrdOucCache::Attach
virtual XrdOucCacheIO * Attach(XrdOucCacheIO *ioP, int Options=0)=0
XrdOucCache
Definition: XrdOucCache.hh:282
XrdOucCache::Parms::Parms
Parms()
Definition: XrdOucCache.hh:330
XrdOucCache::isStructured
static const int isStructured
Definition: XrdOucCache.hh:341
XrdOucCacheIO::Path
virtual const char * Path()=0
XrdOucCacheIO::Trunc
virtual int Trunc(long long Offset)=0
XrdOucCacheIO::FSize
virtual long long FSize()=0
XrdOucCacheIO::Detach
virtual XrdOucCacheIO * Detach()
Definition: XrdOucCache.hh:214
XrdOucCache::Parms::minPages
short minPages
Definition: XrdOucCache.hh:326
XrdOucCache::Parms::MaxFiles
int MaxFiles
Definition: XrdOucCache.hh:324
XrdOucCache::XrdOucCache
XrdOucCache()
Definition: XrdOucCache.hh:389
XrdOucIOVec
Definition: XrdOucIOVec.hh:40
XrdOucCacheIO::ioActive
virtual bool ioActive()
Definition: XrdOucCache.hh:220
XrdOucCache::Parms::CacheSize
long long CacheSize
Definition: XrdOucCache.hh:321
XrdOucCache::optFIU
static const int optFIU
Definition: XrdOucCache.hh:298
XrdOucCacheIO::aprParms::Trigger
int Trigger
Definition: XrdOucCache.hh:248
XrdOucCache::Rmdir
virtual int Rmdir(const char *)
Definition: XrdOucCache.hh:374
XrdOucCache::Stats
XrdOucCacheStats Stats
Definition: XrdOucCache.hh:387
XrdOucCache::logStats
static const int logStats
Definition: XrdOucCache.hh:347
XrdOucCacheIO::ReadV
virtual int ReadV(const XrdOucIOVec *readV, int n)
Definition: XrdOucCache.hh:160
XrdOucCacheIO::SingleUse
static const int SingleUse
Definition: XrdOucCache.hh:231
XrdOucCache::Parms::Options
int Options
Definition: XrdOucCache.hh:325
XrdOucIOVec.hh
XrdOucCache::Unlink
virtual int Unlink(const char *)
Definition: XrdOucCache.hh:370
XrdOucCacheIO::aprParms::Reserve1
char Reserve1
Definition: XrdOucCache.hh:254
XrdOucCacheIO::aprParms::minPages
short minPages
Definition: XrdOucCache.hh:251
XrdOucCache::Rename
virtual int Rename(const char *, const char *)
Definition: XrdOucCache.hh:378
XrdOucCacheIO::Preread
virtual void Preread(aprParms &Parms)
Definition: XrdOucCache.hh:262
XrdOucCache::canPreRead
static const int canPreRead
Definition: XrdOucCache.hh:344
XrdOucCacheStats.hh
XrdOucCache::Parms::Reserve2
int Reserve2
Definition: XrdOucCache.hh:328
XrdOucCache::isAttached
virtual int isAttached()
Definition: XrdOucCache.hh:311
XrdOucCache::Parms::Max2Cache
int Max2Cache
Definition: XrdOucCache.hh:323
XrdOucCacheIO::aprParms
Definition: XrdOucCache.hh:247
XrdOucCacheStats
Definition: XrdOucCacheStats.hh:40
XrdOucCacheIO::Read
virtual int Read(char *Buffer, long long Offset, int Length)=0
XrdOucCache::optFIS
static const int optFIS
Definition: XrdOucCache.hh:297
XrdOucCacheIO::aprParms::prRecalc
int prRecalc
Definition: XrdOucCache.hh:249
XrdOucCacheIO::Base
virtual XrdOucCacheIO * Base()
Definition: XrdOucCache.hh:200
XrdOucCache::~XrdOucCache
virtual ~XrdOucCache()
Definition: XrdOucCache.hh:390
XrdOucCacheIO::aprParms::minPerf
signed char minPerf
Definition: XrdOucCache.hh:253
XrdOucCacheIOCB::Done
virtual void Done(int result)=0
XrdOucCache::optADB
static const int optADB
Definition: XrdOucCache.hh:296
XrdOucCache::isServer
static const int isServer
Definition: XrdOucCache.hh:338
XrdOucCacheIO::Preread
virtual void Preread(long long Offset, int Length, int Opts=0)
Definition: XrdOucCache.hh:234
XrdOucCacheIO::Write
virtual int Write(char *Buffer, long long Offset, int Length)=0
XrdOucCache::Parms::Reserve1
short Reserve1
Definition: XrdOucCache.hh:327
XrdOucCacheIO::Sync
virtual int Sync()=0
XrdOucCacheIOCB
Definition: XrdOucCache.hh:93
XrdOucCache::Parms
Definition: XrdOucCache.hh:320
XrdOucCacheIO::Statistics
XrdOucCacheStats Statistics
Definition: XrdOucCache.hh:267
XrdOucCache::optWIN
static const int optWIN
Definition: XrdOucCache.hh:301
XrdOucCacheIOCB::~XrdOucCacheIOCB
virtual ~XrdOucCacheIOCB()
Definition: XrdOucCache.hh:108
XrdOucCache::Debug
static const int Debug
Definition: XrdOucCache.hh:356
XrdOucCache::optRW
static const int optRW
Definition: XrdOucCache.hh:299
XrdOucCacheIO::aprParms::Reserve4
int Reserve4
Definition: XrdOucCache.hh:250
XrdOucCache::Serialized
static const int Serialized
Definition: XrdOucCache.hh:350
XrdOucCacheIO::aprParms::aprParms
aprParms()
Definition: XrdOucCache.hh:256