root/feedmelinks/lib/Cache.pm

Revision 1448, 14.1 kB (checked in by jm3, 2 years ago)

new spammer blacklist, perl libs, and better splinker hunting tools

Line 
1 =head1 NAME
2
3 Cache - the Cache interface
4
5 =head1 DESCRIPTION
6
7 The Cache modules are designed to assist a developer in persisting data for a
8 specified period of time.  Often these modules are used in web applications to
9 store data locally to save repeated and redundant expensive calls to remote
10 machines or databases.
11
12 The Cache interface is implemented by derived classes that store cached data
13 in different manners (such as as files on a filesystem, or in memory).
14
15 =head1 USAGE
16
17 To use the Cache system, a cache implementation must be chosen to suit your
18 needs.  The most common is Cache::File, which is suitable for sharing data
19 between multiple invocations and even between concurrent processes.
20
21 Using a cache is simple.  Here is some very simple sample code for
22 instantiating and using a file system based cache.
23
24   use Cache::File;
25
26   my $cache = Cache::File->new( cache_root => '/tmp/cacheroot' );
27   my $customer = $cache->get( $name );
28
29   unless ($customer) {
30       $customer = get_customer_from_db( $name );
31       $cache->set( $name, $customer, '10 minutes' );
32   }
33
34   return $customer;
35
36 Of course, far more powerful methods are available for accessing cached data.
37 Also see the TIE INTERFACE below.
38
39 =head1 METHODS
40
41 =over
42
43 =cut
44 package Cache;
45
46 require 5.006;
47 use strict;
48 use warnings::register;
49 use Carp;
50 use Date::Parse;
51
52 use base qw(Tie::Hash);
53 use fields qw(
54         default_expires removal_strategy size_limit
55         load_callback validate_callback);
56
57 our $VERSION = '2.04';
58
59 our $EXPIRES_NOW = 'now';
60 our $EXPIRES_NEVER = 'never';
61
62 # map of expiration formats to their respective time in seconds
63 my %_Expiration_Units = ( map(($_,             1), qw(s second seconds sec)),
64                           map(($_,            60), qw(m minute minutes min)),
65                           map(($_,         60*60), qw(h hour hours)),
66                           map(($_,      60*60*24), qw(d day days)),
67                           map(($_,    60*60*24*7), qw(w week weeks)),
68                           map(($_,   60*60*24*30), qw(M month months)),
69                           map(($_,  60*60*24*365), qw(y year years)) );
70
71
72 sub new {
73     my Cache $self = shift;
74     my $args = $#_? { @_ } : shift;
75
76     ref $self or croak 'Must use a subclass of Cache';
77
78     $self->set_default_expires($args->{default_expires});
79
80         # set removal strategy
81     my $strategy = $args->{removal_strategy} || 'Cache::RemovalStrategy::LRU';
82     unless (ref($strategy)) {
83         eval "require $strategy" or die @_;
84         $strategy = $strategy->new();
85     }
86     $self->{removal_strategy} = $strategy;
87
88     # set size limit
89     $self->{size_limit} = $args->{size_limit};
90
91     # set load callback
92     $self->set_load_callback($args->{load_callback});
93
94     # set load callback
95     $self->set_validate_callback($args->{validate_callback});
96
97     return $self;
98 }
99
100 =item my $cache_entry = $c->entry( $key )
101
102 Return a 'Cache::Entry' object for the given key.  This object can then be
103 used to manipulate the cache entry in various ways.  The key can be any scalar
104 string that will uniquely identify an entry in the cache.
105
106 =cut
107
108 sub entry;
109
110 =item $c->purge()
111
112 Remove all expired data from the cache.
113
114 =cut
115
116 sub purge;
117
118 =item $c->clear()
119
120 Remove all entries from the cache - regardless of their expiry time.
121
122 =cut
123
124 sub clear;
125
126 =item my $num = $c->count()
127
128 Returns the number of entries in the cache.
129
130 =cut
131
132 sub count;
133
134 =item my $size = $c->size()
135
136 Returns the size (in bytes) of the cache.
137
138 =cut
139
140 # if an argument is provided, then the target is the 'shortcut' method set($key)
141 sub size {
142     my Cache $self = shift;
143     return @_? $self->entry_size(@_) : $self->cache_size();
144 }
145
146 # implement this method instead
147 sub cache_size;
148
149
150 =back
151
152 =head1 PROPERTIES
153
154 When a cache is constructed these properties can be supplied as options to the
155 new() method.
156
157 =over
158
159 =item default_expires
160
161 The current default expiry time for new entries into the cache.  This property
162 can also be reset at any time.
163
164  my $time = $c->default_expires();
165  $c->set_default_expires( $expiry );
166
167 =cut
168
169 sub default_expires {
170     my Cache $self = shift;
171     return Canonicalize_Expiration_Time($self->{default_expires});
172 }
173
174 sub set_default_expires {
175     my Cache $self = shift;
176     my ($time) = @_;
177     # This could be made more efficient by converting to unix time here,
178     # except that special handling would be required for relative times.
179     # For now default_expires() does all the conversion.
180     $self->{default_expires} = $time;
181 }
182
183 =item removal_strategy
184
185 The removal strategy object for the cache.  This is used to remove
186 object from the cache in order to maintain the cache size limit.
187
188 When setting the removal strategy in new(), the name of a strategy package or
189 a blessed strategy object reference should be provided  (in the former case an
190 object is constructed by calling the new() method of the named package).
191
192 The strategies 'Cache::RemovalStrategy::LRU' and
193 'Cache::RemovalStrategy::FIFO' are available by default.
194
195  my $strategy = $c->removal_strategy();
196
197 =cut
198
199 sub removal_strategy {
200     my Cache $self = shift;
201     return $self->{removal_strategy};
202 }
203
204 =item size_limit
205
206 The size limit for the cache.
207
208  my $limit = $c->size_limit();
209
210 =cut
211
212 sub size_limit {
213     my Cache $self = shift;
214     return $self->{size_limit};
215 }
216
217 =item load_callback
218
219 The load callback for the cache.  This may be set to a function that will get
220 called anytime a 'get' is issued for data that does not exist in the cache.
221
222  my $limit = $c->load_callback();
223  $c->set_load_callback($callback_func);
224
225 =cut
226
227 sub load_callback {
228     my Cache $self = shift;
229     return $self->{load_callback};
230 }
231
232 sub set_load_callback {
233     my Cache $self = shift;
234     my ($load_callback) = @_;
235     $self->{load_callback} = $load_callback;
236 }
237
238 =item validate_callback
239
240 The validate callback for the cache.  This may be set to a function that will
241 get called anytime a 'get' is issued for data that does not exist in the
242 cache.
243
244  my $limit = $c->validate_callback();
245  $c->set_validate_callback($callback_func);
246
247 =cut
248
249 sub validate_callback {
250     my Cache $self = shift;
251     return $self->{validate_callback};
252 }
253
254 sub set_validate_callback {
255     my Cache $self = shift;
256     my ($validate_callback) = @_;
257     $self->{validate_callback} = $validate_callback;
258 }
259
260
261 =back
262
263 =head1 SHORTCUT METHODS
264
265 These methods all have counterparts in the Cache::Entry package, but are
266 provided here as shortcuts.  They all default to just wrappers that do
267 '$c->entry($key)->method_name()'.  For documentation, please refer to
268 Cache::Entry.
269
270 =over
271
272 =item my $bool = $c->exists( $key )
273
274 =cut
275
276 sub exists {
277     my Cache $self = shift;
278     my $key = shift;
279     return $self->entry($key)->exists();
280 }
281
282 =item $c->set( $key, $data, [ $expiry ] )
283
284 =cut
285
286 sub set {
287     my Cache $self = shift;
288     my $key = shift;
289     return $self->entry($key)->set(@_);
290 }
291
292 =item my $data = $c->get( $key )
293
294 =cut
295
296 sub get {
297     my Cache $self = shift;
298     my $key = shift;
299     return $self->entry($key)->get();
300 }
301
302 =item my $data = $c->size( $key )
303
304 =cut
305
306 # method is called 'entry_size' as the size() method is also a normal Cache
307 # method for returning the size of the entire cache.  It calls this instead if
308 # given an argument.
309 sub entry_size {
310     my Cache $self = shift;
311     my $key = shift;
312     return $self->entry($key)->size();
313 }
314
315 =item $c->remove( $key )
316
317 =cut
318
319 sub remove {
320     my Cache $self = shift;
321     my $key = shift;
322     return $self->entry($key)->remove();
323 }
324
325 =item $c->expiry( $key )
326
327 =cut
328
329 sub expiry {
330     my Cache $self = shift;
331     my $key = shift;
332     return $self->entry($key)->expiry();
333 }
334 sub get_expiry { shift->expiry(@_); }
335
336 =item $c->set_expiry( $key, $time )
337
338 =cut
339
340 sub set_expiry {
341     my Cache $self = shift;
342     my $key = shift;
343     return $self->entry($key)->set_expiry(@_);
344 }
345
346 =item $c->handle( $key, [$mode, [$expiry] ] )
347
348 =cut
349
350 sub handle {
351     my Cache $self = shift;
352     my $key = shift;
353     return $self->entry($key)->handle();
354 }
355
356 =item $c->validity( $key )
357
358 =cut
359
360 sub validity {
361     my Cache $self = shift;
362     my $key = shift;
363     return $self->entry($key)->validity();
364 }
365 sub get_validity { shift->validity(@_); }
366
367 =item $c->set_validity( $key, $data )
368
369 =cut
370
371 sub set_validity {
372     my Cache $self = shift;
373     my $key = shift;
374     return $self->entry($key)->set_validity(@_);
375 }
376
377 =item $c->freeze( $key, $data, [ $expiry ] )
378
379 =cut
380
381 sub freeze {
382     my Cache $self = shift;
383     my $key = shift;
384     return $self->entry($key)->freeze(@_);
385 }
386
387 =item $c->thaw( $key )
388
389 =cut
390
391 sub thaw {
392     my Cache $self = shift;
393     my $key = shift;
394     return $self->entry($key)->thaw();
395 }
396
397
398 =back
399
400 =head1 TIE INTERFACE
401
402   tie %hash, 'Cache::File', { cache_root => $tempdir };
403
404   $hash{'key'} = 'some data';
405   $data = $hash{'key'};
406
407 The Cache classes can be used via the tie interface, as shown in the synopsis.
408 This allows the cache to be accessed via a hash.  All the standard methods
409 for accessing the hash are supported , with the exception of the 'keys' or
410 'each' call.
411
412 The tie interface is especially useful with the load_callback to automatically
413 populate the hash.
414
415 =head1 REMOVAL STRATEGY METHODS
416
417 These methods are only for use internally (by concrete Cache implementations).
418
419 These methods define the interface by which the removal strategy object can
420 manipulate the cache (the Cache is the 'context' of the strategy).  By
421 default, methods need to be provided to remove the oldest or stalest objects
422 in the cache - thus allowing support for the default FIFO and LRU removal
423 strategies.  All derived Cache implementations should support these methods
424 and may also introduce additional methods (and additional removal strategies
425 to match).
426
427 =over
428
429 =item my $size = $c->remove_oldest()
430
431 Removes the oldest entry in the cache and returns its size.
432
433 =cut
434
435 sub remove_oldest;
436
437 =item my $size = $c->remove_stalest()
438
439 Removes the 'stalest' (least used) object in the cache and returns its
440 size.
441
442 =cut
443
444 sub stalest;
445
446 =item $c->check_size( $size )
447
448 This method isn't actually part of the strategy interface, nor does it need
449 to be defined by Cache implementations.  Instead it should be called by
450 implementations whenever the size of the cache increases.  It will take care
451 of checking the size limit and invoking the removal strategy if required.  The
452 size argument should be the new size of the cache.
453
454 =cut
455
456 sub check_size {
457     my Cache $self = shift;
458     my ($size) = @_;
459
460     defined $self->{size_limit} or return;
461
462     if ($size > $self->{size_limit}) {
463         $self->{removal_strategy}->remove_size(
464                 $self, $size - $self->{size_limit});
465     }
466 }
467
468
469 =back
470
471 =head1 UTILITY METHODS
472
473 These methods are only for use internally (by concrete Cache implementations).
474
475 =over
476
477 =item my $time = Cache::Canonicalize_Expiration_Time($timespec)
478
479 Converts a timespec as described for Cache::Entry::set_expiry() into a unix
480 time.
481
482 =cut
483
484 sub Canonicalize_Expiration_Time {
485     my $timespec = lc($_[0])
486         or return undef;
487
488     my $time;
489
490     if ($timespec =~ /^\s*\d+\s*$/) {
491         $time = $timespec;
492     }
493     elsif ($timespec eq $EXPIRES_NOW) {
494         $time = 0;
495     }
496     elsif ($timespec eq $EXPIRES_NEVER) {
497         $time = undef;
498     }
499     elsif ($timespec =~ /^\s*-/) {
500         # negative time?
501         $time = 0;
502     }
503     elsif ($timespec =~ /^\s*\+(\d+)\s*$/) {
504         $time = $1 + time();
505     }
506     elsif ($timespec =~ /^\s*(\+?\d+)\s*(\w*)\s*$/
507         and exists($_Expiration_Units{$2}))
508     {
509         $time = $_Expiration_Units{$2} * $1 + time();
510     }
511     else {
512         $time = str2time($timespec)
513             or croak "invalid expiration time '$timespec'";
514     }
515
516     return $time;
517 }
518
519
520 # Hash tie methods
521
522 sub TIEHASH {
523     my Cache $class = shift;
524     return $class->new(@_);
525 }
526
527 sub STORE {
528     my Cache $self = shift;
529     my ($key, $value) = @_;
530     return $self->set($key, $value);
531 }
532
533 sub FETCH {
534     my Cache $self = shift;
535     my ($key) = @_;
536     return $self->get($key);
537 }
538
539 # NOT SUPPORTED
540 sub FIRSTKEY {
541     my Cache $self = shift;
542     return undef;
543 }
544
545 # NOT SUPPORTED
546 sub NEXTKEY {
547     my Cache $self = shift;
548     #my ($lastkey) = @_;
549     return undef;
550 }
551
552 sub EXISTS {
553     my Cache $self = shift;
554     my ($key) = @_;
555     return $self->exists($key);
556 }
557
558 sub DELETE {
559     my Cache $self = shift;
560     my ($key) = @_;
561     return $self->remove($key);
562 }
563
564 sub CLEAR {
565     my Cache $self = shift;
566     return $self->clear();
567 }
568
569
570 1;
571 __END__
572
573 =head1 SEE ALSO
574
575 Cache::Entry, Cache::File, Cache::RemovalStrategy
576
577 =head1 DIFFERENCES FROM CACHE::CACHE
578
579 The Cache modules are a total redesign and reimplementation of Cache::Cache
580 and thus not directly compatible.  It would be, however, quite possible to
581 write a wrapper module that provides an identical interface to Cache::Cache.
582
583 The semantics of use are very similar to Cache::Cache, with the following
584 exceptions:
585
586 =over
587
588 =item The get/set methods DO NOT serialize complex data types.  Use
589 freeze/thaw instead (but read the notes in Cache::Entry).
590
591 =item The get_object / set_object methods are not available, but have been
592 superseded by the more flexible entry method and Cache::Entry class.
593
594 =item There is no concept of 'namespace' in the basic cache interface,
595 although implementations (eg. Cache::Memory) may choose to provide them.  For
596 instance, File::Cache does not provide this - but different namespaces can be
597 created by varying cache_root.
598
599 =item In the current Cache implementations purging is done automatically -
600 there is no need to explicitly enable auto purge on get/set.  The purging
601 algorithm is no longer implemented in the base Cache class, but is left up to
602 the implementations and may thus be implemented in the most efficient way for
603 the storage medium.
604
605 =item Cache::SharedMemory is not yet available.
606
607 =item Cache::File no longer supports separate masks for entries and
608 directories.  It is not a very secure configuration and presents numerous
609 issues for cache consistency and is hence depricated.  There is still some
610 work to be done to ensure cache consistency between accesses by different
611 users.
612
613 =back
614
615 =head1 AUTHOR
616
617  Chris Leishman <chris@leishman.org>
618  Based on work by DeWitt Clinton <dewitt@unto.net>
619
620 =head1 COPYRIGHT
621
622  Copyright (C) 2003-2006 Chris Leishman.  All Rights Reserved.
623
624 This module is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
625 either expressed or implied. This program is free software; you can
626 redistribute or modify it under the same terms as Perl itself.
627
628 $Id: Cache.pm,v 1.7 2006/01/31 15:23:58 caleishm Exp $
629
630 =cut
631
Note: See TracBrowser for help on using the browser.