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{
95public:
96
97//------------------------------------------------------------------------------
103//------------------------------------------------------------------------------
104virtual
105void Done(int result) = 0;
106
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.
124 Finally, each object carries with it a XrdOucCacheStats object.
125*/
126
128{
129public:
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.
135virtual
136long long FSize() = 0;
137
138// Path() returns the path name associated with this object.
140virtual
141const 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.
148virtual
149int 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.
159virtual
160int 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.
179virtual
180int Sync() = 0;
181
182// Trunc() truncates the file to the specified offset.
183
184// Success: return 0.
185// Failure: -errno associated with the error.
186virtual
187int 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.
195virtual
196int Write(char *Buffer, long long Offset, int Length) = 0;
197
198// Base() returns the underlying XrdOucCacheIO object being used.
199//
200virtual 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//
214virtual XrdOucCacheIO *Detach() {return this;}
215
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.
220virtual 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//
231static const int SingleUse = 0x0001; // Mark pages for single use
232
233virtual
234void 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//
248 {int Trigger; // preread if (rdln < Trigger) (0 -> pagesize+1)
249 int prRecalc; // Recalc pr efficiency every prRecalc bytes (0->50M)
251 short minPages; // If rdln/pgsz < min, preread minPages (0->off)
252 signed
253 char minPerf; // Minimum auto preread performance required (0->n/a)
255
257 minPages(0), minPerf(90), Reserve1(0)
258 {}
259 };
260
261virtual
262void 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
269virtual ~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{
284public:
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*/
296static const int optADB = 0x1000; // Automatically delete underlying CacheIO
297static const int optFIS = 0x0001; // File is Structured (e.g. root file)
298static const int optFIU = 0x0002; // File is Unstructured (e.g. unix file)
299static const int optRW = 0x0004; // File is read/write (o/w read/only)
300static const int optNEW = 0x0014; // File is new -> optRW (o/w read to write)
301static const int optWIN = 0x0024; // File is new -> optRW use write-in cache
302
303virtual
304XrdOucCacheIO *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*/
310virtual
311int 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*/
320struct 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//
337static const int
338isServer = 0x0010; // This is server application (as opposed to a user app).
339 // Appropriate internal optimizations will be used.
340static const int
341isStructured = 0x0020; // Optimize for structured files (e.g. root).
342
343static const int
344canPreRead = 0x0040; // Enable pre-read operations (o/w ignored)
345
346static const int
347logStats = 0x0080; // Display statistics upon detach
348
349static const int
350Serialized = 0x0004; // Caller ensures MRSW semantics
351
352static const int
353ioMTSafe = 0x0008; // CacheIO object is MT-safe
354
355static const int
356Debug = 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*/
364virtual
366
367
368// Propagate Unlink client request from posix layer to cache.
369virtual
370int Unlink(const char* /*path*/) { return 0; }
371
372// Propagate Rmdir client request from posix layer to cache.
373virtual
374int Rmdir(const char* /*path*/) { return 0; }
375
376// Propagate Rename client request from posix layer to cache.
377virtual
378int Rename(const char* /*path*/, const char* /*newPath*/) { return 0; }
379
380// Propagate Truncate client request from posix layer to cache.
381virtual
382int 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
390virtual ~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
Definition: XrdOucCache.hh:94
virtual void Done(int result)=0
XrdOucCacheIOCB()
Definition: XrdOucCache.hh:107
virtual ~XrdOucCacheIOCB()
Definition: XrdOucCache.hh:108
Definition: XrdOucCache.hh:128
virtual int Sync()=0
virtual XrdOucCacheIO * Detach()
Definition: XrdOucCache.hh:214
static const int SingleUse
Definition: XrdOucCache.hh:231
XrdOucCacheStats Statistics
Definition: XrdOucCache.hh:267
virtual long long FSize()=0
virtual const char * Path()=0
virtual int Read(char *Buffer, long long Offset, int Length)=0
virtual void Preread(aprParms &Parms)
Definition: XrdOucCache.hh:262
virtual ~XrdOucCacheIO()
Definition: XrdOucCache.hh:269
virtual void Preread(long long Offset, int Length, int Opts=0)
Definition: XrdOucCache.hh:234
virtual int Write(char *Buffer, long long Offset, int Length)=0
virtual int ReadV(const XrdOucIOVec *readV, int n)
Definition: XrdOucCache.hh:160
virtual XrdOucCacheIO * Base()
Definition: XrdOucCache.hh:200
virtual int Trunc(long long Offset)=0
virtual bool ioActive()
Definition: XrdOucCache.hh:220
Definition: XrdOucCacheStats.hh:41
Definition: XrdOucCache.hh:283
static const int optFIU
Definition: XrdOucCache.hh:298
static const int optRW
Definition: XrdOucCache.hh:299
virtual int Unlink(const char *)
Definition: XrdOucCache.hh:370
virtual XrdOucCache * Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0)=0
XrdOucCache()
Definition: XrdOucCache.hh:389
static const int isStructured
Definition: XrdOucCache.hh:341
static const int isServer
Definition: XrdOucCache.hh:338
static const int canPreRead
Definition: XrdOucCache.hh:344
virtual XrdOucCacheIO * Attach(XrdOucCacheIO *ioP, int Options=0)=0
XrdOucCacheStats Stats
Definition: XrdOucCache.hh:387
virtual int isAttached()
Definition: XrdOucCache.hh:311
static const int optADB
Definition: XrdOucCache.hh:296
virtual ~XrdOucCache()
Definition: XrdOucCache.hh:390
static const int Serialized
Definition: XrdOucCache.hh:350
virtual int Truncate(const char *, off_t)
Definition: XrdOucCache.hh:382
static const int logStats
Definition: XrdOucCache.hh:347
static const int optWIN
Definition: XrdOucCache.hh:301
virtual int Rename(const char *, const char *)
Definition: XrdOucCache.hh:378
virtual int Rmdir(const char *)
Definition: XrdOucCache.hh:374
static const int Debug
Definition: XrdOucCache.hh:356
static const int ioMTSafe
Definition: XrdOucCache.hh:353
static const int optNEW
Definition: XrdOucCache.hh:300
static const int optFIS
Definition: XrdOucCache.hh:297
Definition: XrdOucCache.hh:248
aprParms()
Definition: XrdOucCache.hh:256
short minPages
Definition: XrdOucCache.hh:251
int Reserve4
Definition: XrdOucCache.hh:250
signed char minPerf
Definition: XrdOucCache.hh:253
char Reserve1
Definition: XrdOucCache.hh:254
int prRecalc
Definition: XrdOucCache.hh:249
int Trigger
Definition: XrdOucCache.hh:248
Definition: XrdOucCache.hh:321
long long CacheSize
Definition: XrdOucCache.hh:321
Parms()
Definition: XrdOucCache.hh:330
int PageSize
Definition: XrdOucCache.hh:322
int MaxFiles
Definition: XrdOucCache.hh:324
short Reserve1
Definition: XrdOucCache.hh:327
int Max2Cache
Definition: XrdOucCache.hh:323
short minPages
Definition: XrdOucCache.hh:326
int Reserve2
Definition: XrdOucCache.hh:328
int Options
Definition: XrdOucCache.hh:325
Definition: XrdOucIOVec.hh:41