File Coverage

blib/lib/Cache/CacheFactory/Expiry/Size.pm
Criterion Covered Total %
statement 84 98 85.7
branch 22 42 52.3
condition 4 15 26.6
subroutine 19 21 90.4
pod 11 11 100.0
total 140 187 74.8


line stmt bran cond sub pod time code
1             ###############################################################################
2             # Purpose : Cache Size Expiry Policy Class.
3             # Author : Sam Graham
4             # Created : 25 Jun 2008
5             # CVS : $Id: Size.pm,v 1.9 2010-02-16 12:25:41 illusori Exp $
6             ###############################################################################
7              
8             package Cache::CacheFactory::Expiry::Size;
9              
10 2     2   1448 use warnings;
  2         4  
  2         65  
11 2     2   10 use strict;
  2         4  
  2         46  
12              
13 2     2   8 use Scalar::Util;
  2         2  
  2         71  
14              
15 2     2   8 use Cache::Cache;
  2         2  
  2         52  
16 2     2   8 use Cache::BaseCache;
  2         4  
  2         60  
17              
18 2     2   10 use Cache::CacheFactory;
  2         3  
  2         49  
19 2     2   1240 use Cache::CacheFactory::Expiry::Base;
  2         6  
  2         64  
20              
21 2     2   12 use base qw/Cache::CacheFactory::Expiry::Base/;
  2         4  
  2         297  
22              
23             $Cache::CacheFactory::Expiry::Size::VERSION = '1.10';
24              
25             @Cache::CacheFactory::Expiry::Size::EXPORT_OK = qw/$NO_MAX_SIZE/;
26              
27             my ( $use_devel_size );
28              
29             BEGIN
30             {
31             # TODO: check for configurations with known Devel::Size issues?
32             # See if we have Devel::Size available. We don't make it a requirement
33             # because it doesn't seem to work with 5.6 perls.
34 2     2   190 eval "use Devel::Size";
  2     2   980  
  0         0  
  0         0  
35 2 50       2095 $use_devel_size = 1 unless $@;
36             }
37              
38             sub read_startup_options
39             {
40 2     2 1 6 my ( $self, $param ) = @_;
41              
42             $self->{ max_size } = $param->{ max_size }
43 2 50       21 if exists $param->{ max_size };
44             $self->{ no_devel_size } = $param->{ no_devel_size }
45 2 50       7 if exists $param->{ no_devel_size };
46             $self->{ no_overrule_memorycache_size } =
47             $param->{ no_overrule_memorycache_size }
48 2 50       8 if exists $param->{ no_overrule_memorycache_size };
49             $self->{ no_cache_cache_size_during_purge } =
50             $param->{ no_cache_cache_size_during_purge }
51 2 50       9 if exists $param->{ no_cache_cache_size_during_purge };
52              
53             $self->{ max_size } = $Cache::CacheFactory::NO_MAX_SIZE
54 2 50       50 unless defined $self->{ max_size };
55             }
56              
57             sub set_object_validity
58             {
59 0     0 1 0 my ( $self, $key, $object, $param ) = @_;
60              
61             }
62              
63             sub set_object_pruning
64             {
65 4     4 1 10 my ( $self, $key, $object, $param ) = @_;
66              
67             }
68              
69             sub using_devel_size
70             {
71 9     9 1 17 my ( $self ) = @_;
72              
73 9 50 33     28 return( 1 ) if $use_devel_size and not $self->{ no_devel_size };
74 9         30 return( 0 );
75             }
76              
77             sub guestimate_size
78             {
79 8     8 1 14 my ( $self, $data ) = @_;
80 8         9 my ( $totalsize, @queue, %seen );
81              
82 8 50       19 return( Devel::Size::total_size( $data ) )
83             if $self->using_devel_size();
84              
85             # Fallback in case we're on a system without Devel::Size.
86             # These are highly invented numbers just to give something
87             # better than that in Cache::MemoryCache.
88             # ie: the result may be wrong but it should at least be
89             # somewhat consistently proportional to the right value.
90              
91 8         14 $totalsize = 0;
92 8         13 %seen = ();
93 8         14 @queue = ( $data );
94              
95 8         21 while( @queue )
96             {
97 72         75 my ( $item, $type );
98              
99 72         83 $item = shift( @queue );
100 72         130 $type = Scalar::Util::reftype( $item );
101              
102             # Each value has some overhead, let's say twenty bytes,
103             # this is total invention on my part but seems roughly
104             # what Devel::Size is telling me. :)
105 72         73 $totalsize += 20;
106              
107 72 100       104 if( !defined( $type ) )
108             {
109             # Yep, wrong if it's a number, tough.
110 64         159 $totalsize += length( $item );
111             }
112             else
113             {
114             # Only count size of contents of circular references the once.
115 8 50       31 next if $seen{ $item }++;
116 8 50       21 if( $type eq 'ARRAY' )
    50          
117             {
118 0         0 push @queue, @{$item};
  0         0  
119             }
120             elsif( $type eq 'HASH' )
121             {
122 8         11 push @queue, keys( %{$item} ), values( %{$item} );
  8         23  
  8         43  
123             }
124             else
125             {
126             # HellifIknow.
127             }
128             }
129             }
130              
131 8         33 return( $totalsize );
132             }
133              
134             sub overrule_size
135             {
136 4     4 1 7 my ( $self, $storage ) = @_;
137 4         5 my ( $totalsize );
138              
139 4         6 $totalsize = 0;
140             # Get every object in the cache, not expensive at all, nooooo. :)
141 4         22 foreach my $key ( $storage->get_keys() )
142             {
143 4         68 my ( $ob );
144              
145 4         14 $ob = $storage->get_object( $key );
146 4         389 $totalsize += $self->guestimate_size( $ob );
147             }
148              
149 4         16 return( $totalsize );
150             }
151              
152             sub should_keep
153             {
154 4     4 1 8 my ( $self, $cache, $storage, $policytype, $object ) = @_;
155 4         7 my ( $cachesize, $itemsize );
156              
157             return( 1 )
158 4 50       13 if $self->{ max_size } == $Cache::CacheFactory::NO_MAX_SIZE;
159              
160 4 50 33     34 if( not $self->{ no_overrule_memorycache_size } and
161             $storage->isa( 'Cache::MemoryCache' ) )
162             {
163             $cachesize =
164 4   33     14 $self->{ _cache_size } || $self->overrule_size( $storage );
165             $itemsize = $self->guestimate_size( $object )
166 4 50       18 if exists $self->{ _cache_size };
167             }
168             else
169             {
170 0   0     0 $cachesize = $self->{ _cache_size } || $storage->size();
171             $itemsize = $object->get_size()
172 0 0       0 if exists $self->{ _cache_size };
173             }
174              
175 4 100       29 return( 1 ) if $cachesize <= $self->{ max_size };
176              
177             # We're assuming that a remove will be triggered and succeed
178             # this is potentially risky, but probably ok.
179 2 50       10 $self->{ _cache_size } -= $itemsize if exists $self->{ _cache_size };
180 2         23 return( 0 );
181             }
182              
183             sub pre_purge_hook
184             {
185 4     4 1 7 my ( $self, $cache ) = @_;
186              
187             return( 0 )
188 4 50       15 if $self->{ max_size } == $Cache::CacheFactory::NO_MAX_SIZE;
189              
190 4         22 return( $self->SUPER::pre_purge_hook( $cache ) );
191             }
192              
193             sub pre_purge_per_storage_hook
194             {
195 4     4 1 7 my ( $self, $cache, $storage ) = @_;
196              
197             # Locally cache the cache-size so we don't keep recalculating it
198             # for each key, this is a bit of a hack and assumes nothing but
199             # the purge is going to change the size while we're purging.
200             # If something else does, we might over or under prune.
201             # Without locking this will always be a risk for shared caches
202             # anyway.
203 4 50       12 unless( $self->{ no_cache_cache_size_during_purge } )
204             {
205 4 50 33     53 if( not $self->{ no_overrule_memorycache_size } and
206             $storage->isa( 'Cache::MemoryCache' ) )
207             {
208 4         13 $self->{ _cache_size } = $self->overrule_size( $storage );
209             }
210             else
211             {
212 0         0 $self->{ _cache_size } = $storage->size();
213             }
214             }
215              
216 4         27 return( $self->SUPER::pre_purge_per_storage_hook( $cache, $storage ) );
217             }
218              
219             sub post_purge_per_storage_hook
220             {
221 4     4 1 8 my ( $self, $cache, $storage ) = @_;
222              
223             # Clear our local caching of the cache size.
224 4         8 delete $self->{ _cache_size };
225 4         22 $self->SUPER::post_purge_per_storage_hook( $cache, $storage );
226             }
227              
228             sub limit_size
229             {
230 0     0 1   my ( $self, $cache, $size ) = @_;
231 0           my ( $old_max_size );
232              
233 0           $old_max_size = $self->{ max_size };
234 0           $self->{ max_size } = $size;
235              
236 0           $self->purge( $cache );
237              
238 0           $self->{ max_size } = $old_max_size;
239             }
240              
241             1;
242              
243             =pod
244              
245             =head1 NAME
246              
247             Cache::CacheFactory::Expiry::Size - Size-based expiry policy for Cache::CacheFactory.
248              
249             =head1 DESCRIPTION
250              
251             L
252             is a size-based expiry (pruning and validity) policy for
253             L.
254              
255             It provides similar functionality and backwards-compatibility with
256             the C option of L and variants.
257              
258             It's highly recommended that you B use this policy as a
259             validity policy, as calculating the size of the contents of the
260             cache on each read can be quite expensive, and it's semantically
261             ambiguous as to just what behaviour is intended by it anyway.
262              
263             Note that in its current implementation L
264             is "working but highly inefficient" when it comes to purging.
265             It is provided mostly for completeness while a revised version
266             is being worked on.
267              
268             =head1 SIZE SPECIFICATIONS
269              
270             Currently all size values must be specified as numbers and will be
271             interpreted as bytes. Future versions reserve the right to supply
272             the size as a string '10 M' for ease of use, but this is not currently
273             implemented.
274              
275             =head1 STARTUP OPTIONS
276              
277             The following startup options may be supplied to
278             L,
279             see the L documentation for
280             how to pass options to a policy.
281              
282             =over
283              
284             =item max_size => $size
285              
286             This sets the maximum size that the cache strives to keep under,
287             any items that take the cache over this size will be pruned (for
288             a pruning policy) at the next C<< $cache->purge() >>.
289              
290             See the L section above for details on
291             what values you can pass in as C<$size>.
292              
293             You can also use C to indicate
294             that there is no size limit automatically applied, this is generally
295             a bit pointless with a 'size' policy unless you are going to call
296             C manually every so often.
297              
298             Note that by default pruning policies are not immediately enforced,
299             they are only applied when a C<< $cache->purge() >> occurs. This
300             means that it is possible (likely even) for the size of the cache
301             to exceed C at least on a temporary basis. When the next
302             C<< $cache->purge() >> occurs, the cache will be reduced back down
303             below C.
304              
305             If you make use of the C option to
306             L, you'll cause a C<< $cache->purge() >>
307             on a regular basis depending on the value of C.
308              
309             However, even with the most aggressive values of C
310             there will still be a best-case scenario of the cache entry being
311             written to the cache, taking it over C, and the purge
312             then reducing the cache to or below C. This is essentially
313             unavoidable since it's impossible to know the size an entry will
314             take in the cache until it has been written.
315              
316             Also note that for each C the cache will need to call
317             C once (or more if C is set),
318             which on most storage policies will involve inspecting
319             the size of every key in that namespace. Needless to say this can
320             be quite an expensive operation.
321              
322             With these points in mind you may consider setting C to
323             C<$NO_MAX_SIZE> and manually calling C<< $cache->limit_size( $size ) >>
324             periodically at a time that's under your control.
325              
326             =item no_cache_cache_size_during_purge => 0 | 1
327              
328             By default, to reduce the number of calls to C<< $storage->size() >>
329             during a purge, the size of the cache will be stored locally at
330             the start of a purge and estimated as keys are purged.
331              
332             For the most part this is reasonable behaviour, however if the
333             estimated reduction from deleting a key is wrong (this "shouldn't
334             happen") the size estimate will be inaccurate and the cache will
335             either be overpurged or underpurged.
336              
337             The other issue however is with shared caches, since there is no
338             locking during a purge, it's possible for another thread or process
339             to add or remove from the cache (or even C), altering the
340             size of the cache during the purge, and this will not be noticed,
341             resulting in either an overpurge or an underpurge.
342              
343             Neither of these cases will cause a problem for the majority of
344             applications (or even occur in the first place), however you can
345             disable this caching of C by setting
346             C to a true value
347             if it does cause you problems.
348              
349             Please note however that this will mean that C will need
350             to be called when every key is inspected (not just removed!) for
351             pruning. Read the notes for C above as this is likely to
352             have a dramatic performance degredation.
353              
354             =item no_overrule_memorycache_size => 0 | 1
355              
356             By default L will attempt a
357             workaround for the problems mentioned in "Memory cache inaccuracies"
358             in the L section.
359              
360             If this behaviour is undesirable, supply a true value to the
361             C option.
362              
363             =item no_devel_size => 0 | 1
364              
365             If the above workaround is in effect it will attempt to use L
366             if it is available, since this module delves into the internals of perl
367             it can be fragile on perl version changes and you may wish to disable
368             it if this is causing you problems, to do that set the C
369             option to a true value.
370              
371             =back
372              
373             =head1 STORE OPTIONS
374              
375             There are no per-key options for this policy.
376              
377             =head1 METHODS
378              
379             You shouldn't need to call any of these methods directly.
380              
381             =over
382              
383             =item $size = $policy->overrule_size( $storage );
384              
385             This method is used to overrule the usual C<< $storage->size() >>
386             method when comparing against C, it attempts to
387             analyze every object in the cache and sum their memory footprint
388             via C<< $policy->guestimate_size() >>.
389              
390             By default this is used when trying to workaround issues with
391             the C method of L.
392              
393             =item $size = $policy->guestimate_size( $data );
394              
395             This method provides a rough (very rough sometimes) estimate of
396             the memory footprint of the data structure C<$data>.
397              
398             This is used internally by the L workaround.
399              
400             =item $boolean = $policy->using_devel_size();
401              
402             Return true or false depending on whether this policy instance
403             will use Devel::Size in C<< $policy->guestimate_size() >>.
404              
405             NOTE: this does not imply that C<< $policy->guestimate_size() >>
406             will itself be being used.
407              
408             Mostly this is a debug method is so I can write saner regression
409             tests.
410              
411             =item $policy->limit_size( $cache, $size );
412              
413             Called by C<< $cache->limit_size() >>, this does a one-time prune
414             of the cache to C<$size> size or below.
415              
416             =back
417              
418             =head1 KNOWN ISSUES AND BUGS
419              
420             =over
421              
422             =item Memory cache inaccuracies
423              
424             Due to the way that L and L
425             implement the C method, the values returned do not actually
426             reflect the memory used by a cache entry, in fact it's likely to return
427             a somewhat arbitrary value linear to the number of entries in the cache
428             and independent of the size of the data in the entries.
429              
430             This means that a 'size' pruning policy applied to storage policies of
431             'memory' or 'sharedmemory' would not keep the size of the cache
432             under C bytes.
433              
434             So, by default L will ignore and overrule
435             the value of C<< Cache::MemoryCache->size() >> or
436             C<< CacheSharedMemoryCache->size() >> when checking against C and
437             will attempt to use its own guestimate of the memory taken up.
438              
439             To do this it will make use of L if available, or
440             failing that use a very simplistic calculation that should at least be
441             proportional to the size of the data in the cache rather than the number
442             of entries.
443              
444             Since L doesn't appear to be successfully tested on
445             perls of 5.6 vintage or earlier and the bug only effects memory
446             caches, L hasn't been made a requirement of this module.
447              
448             This may all be considered as a bug, or at the least a gotcha.
449              
450             =back
451              
452             =head1 SEE ALSO
453              
454             L, L, L,
455             L, L,
456             L
457              
458             =head1 AUTHORS
459              
460             Original author: Sam Graham
461              
462             Last author: $Author: illusori $
463              
464             =head1 COPYRIGHT
465              
466             Copyright 2008-2010 Sam Graham.
467              
468             This library is free software; you can redistribute it and/or
469             modify it under the same terms as Perl itself.
470              
471             =cut