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