line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Cache::Entry - interface for a cache entry |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
my Cache::Entry $entry = $cache->entry( $key ) |
8
|
|
|
|
|
|
|
my $data; |
9
|
|
|
|
|
|
|
if ($entry->exists()) { |
10
|
|
|
|
|
|
|
$data = $entry->get(); |
11
|
|
|
|
|
|
|
} |
12
|
|
|
|
|
|
|
else { |
13
|
|
|
|
|
|
|
$data = get_some_data($key); |
14
|
|
|
|
|
|
|
$entry->set($data, '10 minutes'); |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 DESCRIPTION |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Objects derived from Cache::Entry represent an entry in a Cache. Methods are |
20
|
|
|
|
|
|
|
provided that act upon the data in the entry, and allow you to set things like |
21
|
|
|
|
|
|
|
the expiry time. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Users should not create instances of Cache::Entry directly, but instead use |
24
|
|
|
|
|
|
|
the entry($key) method of a Cache instance. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 METHODS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=over |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=cut |
31
|
|
|
|
|
|
|
package Cache::Entry; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
require 5.006; |
34
|
7
|
|
|
7
|
|
874
|
use strict; |
|
7
|
|
|
|
|
9
|
|
|
7
|
|
|
|
|
242
|
|
35
|
7
|
|
|
7
|
|
28
|
use warnings; |
|
7
|
|
|
|
|
7
|
|
|
7
|
|
|
|
|
172
|
|
36
|
7
|
|
|
7
|
|
2419
|
use Cache; |
|
7
|
|
|
|
|
17
|
|
|
7
|
|
|
|
|
201
|
|
37
|
7
|
|
|
7
|
|
1224
|
use Storable; |
|
7
|
|
|
|
|
5206
|
|
|
7
|
|
|
|
|
436
|
|
38
|
7
|
|
|
7
|
|
32
|
use Carp; |
|
7
|
|
|
|
|
33
|
|
|
7
|
|
|
|
|
306
|
|
39
|
|
|
|
|
|
|
|
40
|
7
|
|
|
7
|
|
29
|
use fields qw(cache key); |
|
7
|
|
|
|
|
6
|
|
|
7
|
|
|
|
|
40
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
our $VERSION = '2.11'; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub new { |
46
|
242
|
|
|
242
|
0
|
269
|
my Cache::Entry $self = shift; |
47
|
242
|
|
|
|
|
234
|
my ($cache, $key) = @_; |
48
|
|
|
|
|
|
|
|
49
|
242
|
50
|
|
|
|
425
|
ref $self or croak 'Must use a subclass of Cache::Entry'; |
50
|
|
|
|
|
|
|
|
51
|
242
|
|
|
|
|
334
|
$self->{cache} = $cache; |
52
|
242
|
|
|
|
|
279
|
$self->{key} = $key; |
53
|
|
|
|
|
|
|
|
54
|
242
|
|
|
|
|
364
|
return $self; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=item my $cache = $e->cache() |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Returns a reference to the cache object this entry is from. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=cut |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub cache { |
64
|
0
|
|
|
0
|
1
|
0
|
my Cache::Entry $self = shift; |
65
|
0
|
|
|
|
|
0
|
return $self->{cache}; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item my $key = $e->key() |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Returns the cache key this entry is associated with. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=cut |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub key { |
75
|
5
|
|
|
5
|
1
|
210
|
my Cache::Entry $self = shift; |
76
|
5
|
|
|
|
|
24
|
return $self->{key}; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item my $bool = $e->exists() |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Returns a boolean value (1 or 0) to indicate whether there is any data |
82
|
|
|
|
|
|
|
present in the cache for this entry. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=cut |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub exists; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item $e->set( $data, [ $expiry ] ) |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Stores the data into the cache. The data must be a scalar (if you want to |
91
|
|
|
|
|
|
|
store more complex data types, see freeze and thaw below). |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
The expiry time may be provided as an optional 2nd argument and is in the same |
94
|
|
|
|
|
|
|
form as for 'set_expiry($time)'. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=cut |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# ensure expiry is normalized then call _set |
99
|
|
|
|
|
|
|
sub set { |
100
|
247
|
|
|
247
|
1
|
320
|
my Cache::Entry $self = shift; |
101
|
247
|
|
|
|
|
255
|
my ($data, $expiry) = @_; |
102
|
|
|
|
|
|
|
|
103
|
247
|
50
|
|
|
|
418
|
unless (defined $data) { |
104
|
0
|
|
|
|
|
0
|
return $self->remove(); |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
247
|
50
|
|
|
|
352
|
ref($data) and warnings::warnif('Cache','Reference passed to set'); |
108
|
|
|
|
|
|
|
|
109
|
247
|
100
|
|
|
|
456
|
if ($#_ < 1) { |
110
|
244
|
|
|
|
|
619
|
$expiry = $self->{cache}->default_expires(); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
else { |
113
|
3
|
|
|
|
|
10
|
$expiry = Cache::Canonicalize_Expiration_Time($expiry); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
247
|
100
|
100
|
|
|
509
|
if (defined $expiry and $expiry == 0) { |
117
|
1
|
|
|
|
|
4
|
return $self->remove(); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
246
|
|
|
|
|
485
|
return $self->_set($data, $expiry); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# Implement this method instead of set |
124
|
|
|
|
|
|
|
sub _set; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=item my $data = $e->get() |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Returns the data from the cache, or undef if the entry doesn't exist. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=cut |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# ensure load_callback and validity callback is issued |
133
|
|
|
|
|
|
|
sub get { |
134
|
17
|
|
|
17
|
1
|
30
|
my Cache::Entry $self = shift; |
135
|
17
|
|
|
|
|
27
|
my Cache $cache = $self->{cache}; |
136
|
|
|
|
|
|
|
|
137
|
17
|
|
|
|
|
64
|
my $result = $self->_get(@_); |
138
|
|
|
|
|
|
|
|
139
|
17
|
100
|
|
|
|
41
|
if (defined $result) { |
140
|
14
|
|
|
|
|
24
|
my $validate_callback = $cache->{validate_callback}; |
141
|
14
|
100
|
|
|
|
62
|
$validate_callback or return $result; |
142
|
1
|
50
|
|
|
|
4
|
$validate_callback->($self) and return $result; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
3
|
100
|
|
|
|
13
|
my $load_callback = $cache->{load_callback} |
146
|
|
|
|
|
|
|
or return undef; |
147
|
2
|
|
|
|
|
3
|
my @options; |
148
|
2
|
|
|
|
|
7
|
($result, @options) = $load_callback->($self); |
149
|
2
|
50
|
|
|
|
9
|
$self->set($result, @options) if defined $result; |
150
|
|
|
|
|
|
|
|
151
|
2
|
|
|
|
|
20
|
return $result; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Implement this method instead of get |
155
|
|
|
|
|
|
|
sub _get; |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item my $size = $e->size() |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
Returns the size of the entry data, or undef if the entry doesn't exist. |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=cut |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub size; |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=item $e->remove() |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Clear the data for this entry from the cache. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=cut |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub remove; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=item my $expiry = $e->expiry() |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Returns the expiry time of the entry, in seconds since the epoch. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=cut |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub expiry; |
180
|
0
|
|
|
0
|
0
|
0
|
sub get_expiry { shift->expiry(@_); } |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=item $e->set_expiry( $time ) |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Set the expiry time in seconds since the epoch, or alternatively using a |
185
|
|
|
|
|
|
|
string like '10 minutes'. Valid units are s, second, seconds, sec, m, minute, |
186
|
|
|
|
|
|
|
minutes, min, h, hour, hours, w, week, weeks, M, month, months, y, year and |
187
|
|
|
|
|
|
|
years. You can also specify an absolute time, such as '16 Nov 94 22:28:20' or |
188
|
|
|
|
|
|
|
any other time that Date::Parse can understand. Finally, the strings 'now' |
189
|
|
|
|
|
|
|
and 'never' may also be used. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=cut |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# ensure time is normalized then call _set_expiry |
194
|
|
|
|
|
|
|
sub set_expiry { |
195
|
2
|
|
|
2
|
1
|
12
|
my Cache::Entry $self = shift; |
196
|
2
|
|
|
|
|
3
|
my ($time) = @_; |
197
|
|
|
|
|
|
|
|
198
|
2
|
|
|
|
|
8
|
my $expiry = Cache::Canonicalize_Expiration_Time($time); |
199
|
|
|
|
|
|
|
|
200
|
2
|
100
|
66
|
|
|
15
|
if (defined $expiry and $expiry == 0) { |
201
|
1
|
|
|
|
|
7
|
return $self->remove(); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
1
|
|
|
|
|
3
|
$self->_set_expiry($expiry); |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# Implement this method instead of set_expiry |
208
|
|
|
|
|
|
|
sub _set_expiry; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=item my $fh = $e->handle( [$mode, [$expiry] ] ) |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
Returns an IO::Handle by which data can be read, or written, to the cache. |
213
|
|
|
|
|
|
|
This is useful if you are caching a large amount of data - although it should |
214
|
|
|
|
|
|
|
be noted that only some cache implementations (such as Cache::File) provide an |
215
|
|
|
|
|
|
|
efficient mechanism for implementing this. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
The optional mode argument can be any of the perl mode strings as used for the |
218
|
|
|
|
|
|
|
open function '<', '+<', '>', '+>', '>>' and '+>>'. Alternatively it can be |
219
|
|
|
|
|
|
|
the corresponding fopen(3) modes of 'r', 'r+', 'w', 'w+', 'a' and 'a+'. The |
220
|
|
|
|
|
|
|
default mode is '+<' (or 'r+') indicating reading and writing. |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
The second argument is used to set the expiry time for the entry if it doesn't |
223
|
|
|
|
|
|
|
exist already and the handle is opened for writing. It is also used to reset |
224
|
|
|
|
|
|
|
the expiry time if the entry is truncated by opening in the '>' or '+>' modes. |
225
|
|
|
|
|
|
|
If the expiry is not provided in these situations then the default expiry time |
226
|
|
|
|
|
|
|
for the cache is applied. |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
Cache implementations will typically provide locking around cache entries, so |
229
|
|
|
|
|
|
|
that writers will have have an exclusive lock and readers a shared one. Thus |
230
|
|
|
|
|
|
|
the method get() (or obtaining another handle) should be avoided whilst a |
231
|
|
|
|
|
|
|
write handle is held. Using set() or remove(), however, should be supported. |
232
|
|
|
|
|
|
|
These clear the current entry and whilst they do not invalidate open handles, |
233
|
|
|
|
|
|
|
those handle will from then on refer to old data and any changes to the data |
234
|
|
|
|
|
|
|
will be discarded. |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=cut |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# ensure mode and expiry are normalized then call _handle |
239
|
|
|
|
|
|
|
sub handle { |
240
|
11
|
|
|
11
|
1
|
17
|
my Cache::Entry $self = shift; |
241
|
11
|
|
|
|
|
15
|
my ($mode, $expiry) = @_; |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# normalize mode |
244
|
11
|
100
|
|
|
|
24
|
if ($mode) { |
245
|
8
|
|
|
|
|
1409
|
require IO::Handle; |
246
|
8
|
|
|
|
|
11140
|
$mode = IO::Handle::_open_mode_string($mode); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
else { |
249
|
3
|
|
|
|
|
5
|
$mode = '+<'; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
11
|
50
|
|
|
|
100
|
if ($#_ < 1) { |
253
|
11
|
|
|
|
|
47
|
$self->_handle($mode, $self->{cache}->default_expires()); |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
else { |
256
|
0
|
|
|
|
|
0
|
$self->_handle($mode, Cache::Canonicalize_Expiration_Time($expiry)); |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# Implement this method instead of handle |
261
|
|
|
|
|
|
|
sub _handle; |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=back |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head1 STORING VALIDITY OBJECTS |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
There are two additional set & get methods that can be used to store a |
269
|
|
|
|
|
|
|
validity object that is associated with the data in question. Typically this |
270
|
|
|
|
|
|
|
is useful in conjunction with a validate_callback, and may be used to store a |
271
|
|
|
|
|
|
|
timestamp or similar to validate against. The validity data stored may be any |
272
|
|
|
|
|
|
|
complex data that can be serialized via Storable. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=over |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=item $e->validity() |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=cut |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub validity; |
281
|
0
|
|
|
0
|
0
|
0
|
sub get_validity { shift->validity(@_); } |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
=item $e->set_validity( $data ) |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=cut |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub set_validity; |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=back |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 STORING COMPLEX OBJECTS |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
The set and get methods only allow for working with simple scalar types, but |
295
|
|
|
|
|
|
|
if you want to store more complex types they need to be serialized first. To |
296
|
|
|
|
|
|
|
assist with this, the freeze and thaw methods are provided. They are simple |
297
|
|
|
|
|
|
|
wrappers to get & set that use Storable to do the serialization and |
298
|
|
|
|
|
|
|
de-serialization of the data. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Note, however, that you must be careful to ONLY use 'thaw' on data that was |
301
|
|
|
|
|
|
|
stored via 'freeze'. Otherwise the stored data wont actually be in Storable |
302
|
|
|
|
|
|
|
format and it will complain loudly. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=over |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item $e->freeze( $data, [ $expiry ] ) |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Identical to 'set', except that data may be any complex data type that can be |
309
|
|
|
|
|
|
|
serialized via Storable. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=cut |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub freeze { |
314
|
1
|
|
|
1
|
1
|
1
|
my Cache::Entry $self = shift; |
315
|
1
|
|
|
|
|
2
|
my ($data, @args) = @_; |
316
|
1
|
50
|
|
|
|
3
|
ref($data) or warnings::warnif('Cache','Non-reference passed to freeze'); |
317
|
1
|
|
|
|
|
4
|
return $self->set(Storable::nfreeze($data), @args); |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=item $e->thaw() |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Identical to 'get', except that it will return a complex data type that was |
323
|
|
|
|
|
|
|
set via 'freeze'. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=cut |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
sub thaw { |
328
|
1
|
|
|
1
|
1
|
2
|
my Cache::Entry $self = shift; |
329
|
1
|
|
|
|
|
3
|
my $data = $self->get(@_); |
330
|
1
|
50
|
|
|
|
6
|
defined $data or return undef; |
331
|
1
|
|
|
|
|
5
|
return Storable::thaw($data); |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=back |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=cut |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
1; |
340
|
|
|
|
|
|
|
__END__ |