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 "XrdSys/XrdSysPthread.hh"
34 
35 /* The classes defined here can be used to implement a general cache for
36  data from an arbitrary source (e.g. files, sockets, etc); as follows:
37 
38  1. Create an instance of XrdOucCacheIO. This object is used to actually
39  bring in missing data into the cache or write out dirty cache pages.
40  There can be many instances of this class, as needed. However, make sure
41  that there is a 1-to-1 unique correspondence between data and its CacheIO
42  object. Violating this may cause the same data to be cached multiple
43  times and if the cache is writable the data may be inconsistent!
44 
45  2. Create an instance of XrdOucCache. You can specify various cache
46  handling parameters (see the class definition). You can also define
47  additional instances if you want more than one cache. The specific cache
48  you create will be defined by an implementation that derives from these
49  classes. For instance, an implementation of a memory cache is defined
50  in "XrdOucCacheDram.hh".
51 
52  3. Use the Attach() method in XrdOucCache to attach your XrdOucCacheIO
53  object with a cache instance. The method returns a remanufactured
54  XrdOucCacheIO object that interposes the cache in front of the original
55  XrdOucCacheIO. This allows you to transparently use the cache.
56 
57  4. When finished using the remanufactured XrdOucCacheIO object, use its
58  Detach() method to remove the association from the cache. Other actions
59  are defined by the actual implementation. For instance XrdOucCacheDram
60  also releases any assigned cache pages, writes out any dirty pages, and
61  may optionally delete the object when all references have been removed.
62 
63  5. You may delete cache instances as well. Just be sure that no associations
64  still exist using the XrdOucCache::isAttached() method. Otherwise, the
65  cache destructor will wait until all attached objects are detached.
66 
67  Example:
68  class physIO : public XrdOucCacheIO {...}; // Define required methods
69  class xCache : public XrdOucCache {...}; // The cache implementation
70  XrdOucCache::Parms myParms; // Set any desired parameters
71  XrdOucCache *myCache;
72  XrdOucCacheIO *cacheIO;
73  xCache theCache; // Implementation instance
74 
75  myCache = theCache.Create(myParms); // Create a cache instance
76  cacheIO = myCache->Attach(physIO); // Interpose the cache
77 
78  // Use cacheIO (fronted by myCache) instead of physIO. When done...
79 
80  delete cacheIO->Detach(); // Deletes cacheIO and physIO
81 */
82 
83 /******************************************************************************/
84 /* C l a s s X r d O u c C a c h e S t a t s */
85 /******************************************************************************/
86 
87 /* The XrdOucCacheStats object holds statistics on cache usage. It is available
88  in for each XrdOucCacheIO and each XrdOucCache object. The former usually
89  identifies a specific file while the latter provides summary information.
90 */
91 
93 {
94 public:
95 long long BytesPead; // Bytes read via preread (not included in BytesRead)
96 long long BytesRead; // Total number of bytes read into the cache
97 long long BytesGet; // Number of bytes delivered from the cache
98 long long BytesPass; // Number of bytes read but not cached
99 long long BytesWrite; // Total number of bytes written from the cache
100 long long BytesPut; // Number of bytes updated in the cache
101 int Hits; // Number of times wanted data was in the cache
102 int Miss; // Number of times wanted data was *not* in the cache
103 int HitsPR; // Number of pages wanted data was just preread
104 int MissPR; // Number of pages wanted data was just read
105 
106 inline void Get(XrdOucCacheStats &Dst)
107  {sMutex.Lock();
108  Dst.BytesRead = BytesPead; Dst.BytesGet = BytesRead;
109  Dst.BytesPass = BytesPass;
110  Dst.BytesWrite = BytesWrite; Dst.BytesPut = BytesPut;
111  Dst.Hits = Hits; Dst.Miss = Miss;
112  Dst.HitsPR = HitsPR; Dst.MissPR = MissPR;
113  sMutex.UnLock();
114  }
115 
116 inline void Add(XrdOucCacheStats &Src)
117  {sMutex.Lock();
118  BytesRead += Src.BytesPead; BytesGet += Src.BytesRead;
119  BytesPass += Src.BytesPass;
120  BytesWrite += Src.BytesWrite; BytesPut += Src.BytesPut;
121  Hits += Src.Hits; Miss += Src.Miss;
122  HitsPR += Src.HitsPR; MissPR += Src.MissPR;
123  sMutex.UnLock();
124  }
125 
126 inline void Add(long long &Dest, int &Val)
127  {sMutex.Lock(); Dest += Val; sMutex.UnLock();}
128 
129 inline void Lock() {sMutex.Lock();}
130 inline void UnLock() {sMutex.UnLock();}
131 
133  BytesPass(0), BytesWrite(0), BytesPut(0),
134  Hits(0), Miss(0),
135  HitsPR(0), MissPR(0) {}
137 private:
139 };
140 
141 /******************************************************************************/
142 /* C l a s s X r d O u c C a c h e I O */
143 /******************************************************************************/
144 
145 /* The XrdOucCacheIO object is responsible for interacting with the original
146  data source/target. It can be used with or without a front-end cache.
147 
148  Six abstract methods are provided FSize(), Path(), Read(), Sync(), Trunc(),
149  and Write(). You must provide implementations for each as described below.
150 
151  Four additional virtual methods are pre-defined: Base(), Detach(), and
152  Preread() (2x). Normally, there is no need to over-ride these methods.
153 
154  Finally, each object carries with it a XrdOucCacheStats object.
155 */
156 
158 {
159 public:
160 
161 // FSize() returns the current size of the file associated with this object.
162 
163 // Success: size of the file in bytes.
164 // Failure: -errno associated with the error.
165 virtual
166 long long FSize() = 0;
167 
168 // Path() returns the path name associated with this object.
169 //
170 virtual
171 const char *Path() = 0;
172 
173 // Read() places Length bytes in Buffer from a data source at Offset.
174 // When fronted by a cache, the cache is inspected first.
175 
176 // Success: actual number of bytes placed in Buffer.
177 // Failure: -errno associated with the error.
178 virtual
179 int Read (char *Buffer, long long Offset, int Length) = 0;
180 
181 // Sync() copies any outstanding modified bytes to the target.
182 
183 // Success: return 0.
184 // Failure: -errno associated with the error.
185 virtual
186 int Sync() = 0;
187 
188 // Trunc() truncates the file to the specified offset.
189 
190 // Success: return 0.
191 // Failure: -errno associated with the error.
192 virtual
193 int Trunc(long long Offset) = 0;
194 
195 
196 // Write() takes Length bytes in Buffer and writes to a data target at Offset.
197 // When fronted by a cache, the cache is updated as well.
198 
199 // Success: actual number of bytes copied from the Buffer.
200 // Failure: -errno associated with the error.
201 virtual
202 int Write(char *Buffer, long long Offset, int Length) = 0;
203 
204 // Base() returns the underlying XrdOucCacheIO object being used.
205 //
206 virtual XrdOucCacheIO *Base() {return this;}
207 
208 // Detach() detaches the object from the cache. It must be called instead of
209 // using the delete operator since CacheIO objects may have multiple
210 // outstanding references and actual deletion may need to be defered.
211 // Detach() returns the underlying CacheIO object when the last
212 // reference has been removed and 0 otherwise. This allows to say
213 // something like "delete ioP->Detach()" if you want to make sure you
214 // delete the underlying object as well. Alternatively, use the optADB
215 // option when attaching a CacheIO object to a cache. This will delete
216 // underlying object and always return 0 to avoid a double delete.
217 // When not fronted by a cache, Detach() always returns itself. This
218 // makes its use consistent whether or not a cache is employed.
219 //
220 virtual XrdOucCacheIO *Detach() {return this;}
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 // The following structure describes automatic preread parameters. These can be
237 // set at any time for each XrdOucCacheIO object. It can also be specified when
238 // creating a cache to establish the defaults (see XrdOucCache::Create()).
239 // Generally, an implementation that supports prereads should disable small
240 // prereads when minPages or loBound is set to zero; and should disable large
241 // prereads when maxiRead or maxPages is set to zero. Refer to the actual
242 // derived class implementation on how the cache handles prereads.
243 //
244 struct aprParms
245  {int Trigger; // preread if (rdln < Trigger) (0 -> pagesize+1)
246  int prRecalc; // Recalc pr efficiency every prRecalc bytes (0->50M)
247  int Reserve4;
248  short minPages; // If rdln/pgsz < min, preread minPages (0->off)
249  char minPerf; // Minimum auto preread performance required (0->n/a)
250  char Reserve1;
251 
253  minPages(0), minPerf(90), Reserve1(0)
254  {}
255  };
256 
257 virtual
258 void Preread(aprParms &Parms) {}
259 
260 // Here is where the stats about cache and I/O usage reside. There
261 // is a summary object in the associated cache as well.
262 //
264 
265 virtual ~XrdOucCacheIO() {} // Always use Detach() instead of direct delete!
266 };
267 
268 /******************************************************************************/
269 /* C l a s s X r d O u c C a c h e */
270 /******************************************************************************/
271 
272 /* The XrdOucCache class is used to define an instance of a cache. There can
273  be many such instances. Each instance is associated with one or more
274  XrdOucCacheIO objects. Use the Attach() method in this class to create
275  such associations.
276 */
277 
279 {
280 public:
281 
282 /* Attach() must be called to obtain a new XrdOucCacheIO object that fronts an
283  existing XrdOucCacheIO object with this cache.
284  Upon success a pointer to a new XrdOucCacheIO object is returned
285  and must be used to read and write data with the cache interposed.
286  Upon failure, the original XrdOucCacheIO object is returned with
287  errno set. You can continue using the object without any cache.
288  The following Attach() options are available and, when specified,
289  override the default options associated with the cache, except for
290  optRW, optNEW, and optWIN which are valid only for a r/w cache.
291 */
292 static const int optADB = 0x1000; // Automatically delete underlying CacheIO
293 static const int optFIS = 0x0001; // File is Structured (e.g. root file)
294 static const int optFIU = 0x0002; // File is Unstructured (e.g. unix file)
295 static const int optRW = 0x0004; // File is read/write (o/w read/only)
296 static const int optNEW = 0x0014; // File is new -> optRW (o/w read to write)
297 static const int optWIN = 0x0024; // File is new -> optRW use write-in cache
298 
299 virtual
300 XrdOucCacheIO *Attach(XrdOucCacheIO *ioP, int Options=0) = 0;
301 
302 /* isAttached()
303  Returns the number of CacheIO objects attached to this cache.
304  Hence, 0 (false) if none and true otherwise.
305 */
306 virtual
307 int isAttached() {return 0;}
308 
309 /* You must first create an instance of a cache using the Create() method.
310  The Parms structure is used to pass parameters about the cache and should
311  be filled in with values meaningful to the type of cache being created.
312  The fields below, while oriented toward a memory cache, are sufficiently
313  generic to apply to almost any kind of cache. Refer to the actual
314  implementation in the derived class to see how these values are used.
315 */
316 struct Parms
317  {long long CacheSize; // Size of cache in bytes (default 100MB)
318  int PageSize; // Size of each page in bytes (default 32KB)
319  int Max2Cache; // Largest read to cache (default PageSize)
320  int MaxFiles; // Maximum number of files (default 256 or 8K)
321  int Options; // Options as defined below (default r/o cache)
322  int Reserve1; // Reserved for future use
323  int Reserve2; // Reserved for future use
324 
325  Parms() : CacheSize(104857600), PageSize(32768),
326  Max2Cache(0), MaxFiles(0), Options(0),
327  Reserve1(0), Reserve2(0) {}
328  };
329 
330 // Valid option values in Parms::Options
331 //
332 static const int
333 isServer = 0x0010; // This is server application (as opposed to a user app).
334  // Appropriate internal optimizations will be used.
335 static const int
336 isStructured = 0x0020; // Optimize for structured files (e.g. root).
337 
338 static const int
339 canPreRead = 0x0040; // Enable pre-read operations (o/w ignored)
340 
341 static const int
342 logStats = 0x0080; // Display statistics upon detach
343 
344 static const int
345 Serialized = 0x0004; // Caller ensures MRSW semantics
346 
347 static const int
348 ioMTSafe = 0x0008; // CacheIO object is MT-safe
349 
350 static const int
351 Debug = 0x0003; // Produce some debug messages (levels 0, 1, 2, or 3)
352 
353 /* Create() Creates an instance of a cache using the specified parameters.
354  You must pass the cache parms and optionally any automatic
355  pre-read parameters that will be used as future defaults.
356  Upon success, returns a pointer to the cache. Otherwise, a null
357  pointer is returned with errno set to indicate the problem.
358 */
359 virtual
360 XrdOucCache *Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0) = 0;
361 
362 /* The following holds statistics for the cache itself. It is updated as
363  associated cacheIO objects are deleted and their statistics are added.
364 */
366 
368 virtual ~XrdOucCache() {}
369 };
370 
371 /******************************************************************************/
372 /* C r e a t i n g C a c h e P l u g - I n s */
373 /******************************************************************************/
374 
375 /* You can create a cache plug-in for those parts of the xrootd system that
376  allow a dynamically selectable cache implementation (e.g. the proxy server
377  plug-in supports cache plug-ins via the pss.cachelib directive).
378 
379  Your plug-in must exist in a shared library and have the following extern C
380  function defined:
381 
382  extern "C"
383  {
384  XrdOucCache *XrdOucGetCache(XrdSysLogger *Logger, // Where messages go
385  const char *Config, // Config file used
386  const char *Parms); // Optional parm string
387  }
388 
389  When Logger is null, you should use cerr to output messages. Otherwise,
390  tie an instance XrdSysError to the passed logger.
391  When Config is null, no configuration file is present. Otherwise, you need
392  additional configuration information you should get it
393  from that file in order to support single configuration.
394  When Parms is null, no parameter string was specified.
395 
396  The call should return an instance of an XrdOucCache object upon success and
397  a null pointer otherwise. The instance is used to create actual caches using
398  the object's Create() method.
399 */
400 #endif
XrdOucCacheStats()
Definition: XrdOucCache.hh:132
virtual XrdOucCacheIO * Base()
Definition: XrdOucCache.hh:206
long long BytesPass
Definition: XrdOucCache.hh:98
virtual XrdOucCacheIO * Attach(XrdOucCacheIO *ioP, int Options=0)=0
virtual void Preread(aprParms &Parms)
Definition: XrdOucCache.hh:258
Parms()
Definition: XrdOucCache.hh:325
static const int ioMTSafe
Definition: XrdOucCache.hh:348
static const int Debug
Definition: XrdOucCache.hh:351
~XrdOucCacheStats()
Definition: XrdOucCache.hh:136
static const int isStructured
Definition: XrdOucCache.hh:336
static const int SingleUse
Definition: XrdOucCache.hh:231
aprParms()
Definition: XrdOucCache.hh:252
XrdOucCache()
Definition: XrdOucCache.hh:367
static const int logStats
Definition: XrdOucCache.hh:342
Definition: XrdOucCache.hh:157
virtual int Read(char *Buffer, long long Offset, int Length)=0
int Reserve2
Definition: XrdOucCache.hh:323
static const int optNEW
Definition: XrdOucCache.hh:296
void Add(XrdOucCacheStats &Src)
Definition: XrdOucCache.hh:116
virtual int Trunc(long long Offset)=0
int Max2Cache
Definition: XrdOucCache.hh:319
int MaxFiles
Definition: XrdOucCache.hh:320
virtual int Write(char *Buffer, long long Offset, int Length)=0
long long BytesGet
Definition: XrdOucCache.hh:97
XrdOucCacheStats Stats
Definition: XrdOucCache.hh:365
int Options
Definition: XrdOucCache.hh:321
void Get(XrdOucCacheStats &Dst)
Definition: XrdOucCache.hh:106
short minPages
Definition: XrdOucCache.hh:248
static const int optFIU
Definition: XrdOucCache.hh:294
Definition: XrdSysPthread.hh:140
long long BytesRead
Definition: XrdOucCache.hh:96
int Hits
Definition: XrdOucCache.hh:101
Definition: XrdOucCache.hh:278
int Miss
Definition: XrdOucCache.hh:102
static const int optFIS
Definition: XrdOucCache.hh:293
virtual const char * Path()=0
int HitsPR
Definition: XrdOucCache.hh:103
int Reserve4
Definition: XrdOucCache.hh:247
long long BytesPut
Definition: XrdOucCache.hh:100
virtual ~XrdOucCacheIO()
Definition: XrdOucCache.hh:265
long long CacheSize
Definition: XrdOucCache.hh:317
Definition: XrdOucCache.hh:244
static const int optADB
Definition: XrdOucCache.hh:292
static const int canPreRead
Definition: XrdOucCache.hh:339
static const int isServer
Definition: XrdOucCache.hh:333
int PageSize
Definition: XrdOucCache.hh:318
char Reserve1
Definition: XrdOucCache.hh:250
virtual XrdOucCacheIO * Detach()
Definition: XrdOucCache.hh:220
void Lock()
Definition: XrdSysPthread.hh:149
long long BytesPead
Definition: XrdOucCache.hh:95
int Reserve1
Definition: XrdOucCache.hh:322
virtual int isAttached()
Definition: XrdOucCache.hh:307
virtual int Sync()=0
int Trigger
Definition: XrdOucCache.hh:245
int MissPR
Definition: XrdOucCache.hh:104
void UnLock()
Definition: XrdOucCache.hh:130
XrdSysMutex sMutex
Definition: XrdOucCache.hh:138
static const int optWIN
Definition: XrdOucCache.hh:297
void Lock()
Definition: XrdOucCache.hh:129
static const int optRW
Definition: XrdOucCache.hh:295
long long BytesWrite
Definition: XrdOucCache.hh:99
char minPerf
Definition: XrdOucCache.hh:249
Definition: XrdOucCache.hh:92
virtual ~XrdOucCache()
Definition: XrdOucCache.hh:368
virtual void Preread(long long Offset, int Length, int Opts=0)
Definition: XrdOucCache.hh:234
virtual long long FSize()=0
Definition: XrdOucCache.hh:316
void UnLock()
Definition: XrdSysPthread.hh:151
int prRecalc
Definition: XrdOucCache.hh:246
void Add(long long &Dest, int &Val)
Definition: XrdOucCache.hh:126
virtual XrdOucCache * Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0)=0
static const int Serialized
Definition: XrdOucCache.hh:345
XrdOucCacheStats Statistics
Definition: XrdOucCache.hh:263