NAME
Cache::CacheFactory - factory class for Cache::Cache and other modules.
SYNOPSIS
use Cache::CacheFactory;
my $cache = Cache::CacheFactory->new( storage => 'file' );
$cache->set( 'customer', 'Fred' );
... Later ...
print $cache->get( 'customer' );
... prints "Fred"
DESCRIPTION
Cache::CacheFactory is a drop-in replacement for the Cache::Cache subclasses allowing you to access a variety of caching policies from a single place, mixing and matching as you choose rather than having to search for the cache module that provides the exact combination you want.
In a nutshell you specify a policy for storage, for pruning and for validity checks and CacheFactory hooks you up with the right modules to provide that behaviour while providing you with the same API you're used to from Cache::Cache - the only thing you need to change is your call to the constructor.
More advanced use allows you to set multiple policies for pruning and validity checks, and even for storage although that's currently of limited use.
METHODS
- $cache = Cache::CacheFactory->new( %options )
- $cache = Cache::CacheFactory->new( $options )
-
Construct a new cache object with the specified options supplied as either a hash or a hashref.
Errors during construction are usually fatal and reported via
die
, some havenonfatal_*
options to override this behaviour in which case anundef
value will be returned fromnew()
.See "OPTIONS" below for more details on possible options.
- $cache->set( key => $key, data => $data, [ expires_in => $expires_in, %additional_args ] )
- $cache->add( key => $key, data => $data, [ expires_in => $expires_in, %additional_args ] )
- $cache->replace( key => $key, data => $data, [ expires_in => $expires_in, %additional_args ] )
- $cache->set( $key, $data, [ $expires_in ] ) (only in compat-mode)
- $cache->add( $key, $data, [ $expires_in ] ) (only in compat-mode)
- $cache->replace( $key, $data, [ $expires_in ] ) (only in compat-mode)
-
Associates
$data
with$key
in the cache.$cache->add()
is a special form of$cache->set()
that will set the key if-and-only-if it doesn't already exist in the cache.$cache->replace()
is a special form of$cache->set()
that will set the key if-and-only-if it does already exist in the cache.Note: the existence test and set in
$cache->add()
and$cache->replace()
is NOT an atomic operation, if you have a shared cache you will need to implement your own locking mechanism if you need to rely on this behaviour.A deep copy of
$data
will automatically be taken if it is a reference, you can turn this behaviour off with the cache optionno_deep_copy
detailed in "OPTIONS" below.$expires_in
indicates the time in seconds until this data should be erased, or the constant$EXPIRES_NOW
, or the constant$EXPIRES_NEVER
. Defaults to$EXPIRES_NEVER
. This variable can also be in the extended format of "[number] [unit]", e.g., "10 minutes". The valid units are s, second, seconds, sec, m, minute, minutes, min, h, hour, hours, d, day, days, w, week, weeks, M, month, months, y, year, and years. Additionally,$EXPIRES_NOW
can be represented as "now" and$EXPIRES_NEVER
can be represented as "never".$expires_in
is silently ignored (future versions may warn) if the cache didn't choose a 'time' pruning or validity policy at setup.Any additional args will be passed on to the policies chosen at setup time (and documented by those policy modules.)
IMPORTANT: The positional args version of this method is only available if the compat flag
positional_set
was supplied as an option when the cache was created.If
positional_set
is a true value but not set to'auto'
then the hash format is disabled andset()
acts as if it is always given positional args - this will do unwanted things if you pass it hash args.If
positional_set
was given'auto'
as a value thenset()
will attempt to auto-detect when you're supplying positional args and when you're supplying hash args, it does this by the rather-breakable means of asking if the first arg is called 'key', if so then it assumes you're passing a hash, otherwise it'll fall back to using positional args.Examples:
$cache->set( key => 'customer', data => 'Fred', expires_in => '10 minutes', ); $created_at = time(); $template = build_my_template( '/path/to/webpages/index.html' ); $cache->set( key => 'index', data => $template, created_at => $time, dependencies => [ '/path/to/webpages/index.html', ], );
- $data = $cache->get( $key );
-
Gets the data associated with
$key
from the first storage policy that contains a fresh cached copy. - $cache->remove( $key );
-
Removes the data associated with
$key
from each of the storage policies in this cache. - $cache->delete( $key );
-
This is a convenience alias for
$cache->remove( $key )
. - $boolean = $cache->exists( $key );
-
Returns true if data associated with
$key
exists in the cache and false if there is no data associated with that key.This method makes no assumption about the form of the data stored: if you store a value of
undef
you will still get a true return from$cache->exists()
. - $object = $cache->get_object( $key );
-
Returns the Cache::CacheFactory::Object used to store the underlying data associated with
$key
. This behaves much the same as the Cache::Object returned byCache::Cache->get_object()
. - $cache->set_object( $key, $object );
-
Associates
$key
with Cache::CacheFactory::Object$object
. If you supply a Cache::Object in$object
instead, Cache::CacheFactory will create a new Cache::CacheFactory::Object instance as a copy before storing the copy. - @keys = $cache->get_keys();
-
Returns a list of all keys in this instance's namespace across all storage policies.
- @keys = $cache->get_identifiers();
-
This method is deprecated. Behaves identically to
$cache->get_keys()
, use that instead. Provided only for backwards compatibility. - $cache->set_namespace( $namespace );
-
Sets the cache's namespace as per the
namespace
option. This does NOT move any existing cache contents over to the new namespace, it simply points the cache object at the new namespace. - $namespace = $cache->get_namespace();
-
Returns the current namespace as set either by
$cache->set_namespace()
or thenamespace
option. - $cache->Clear();
-
Clears all caches using each of the storage policies. This does not just clear caches with the exact same policies: it calls
Clear()
on each policy in turn. - $cache->clear();
-
Removes all cached data for this instance's namespace from each of the storage policies.
- $cache->Purge();
-
COMPAT BUSTER:
Purge()
now does the same thing aspurge()
since it isn't clear quite what it should do with multiple caches with different pruning and storage policies. Its use is strongly deprecated. - $cache->purge();
-
Applies the pruning policy to all data in this namespace.
- $size = $cache->Size();
-
Returns the total size of all objects in all caches with any of the storage policies of this cache.
- $size = $cache->size();
-
Returns the total size of all objects in this namespace in any of the storage policies of this cache.
- @namespaces = $cache->get_namespaces();
-
Returns a list of all namespaces in any of the storage policies of this cache.
- $cache->set_positional_set( 0 | 1 | 'auto' );
- $positional_set = $cache->get_positional_set();
-
These two methods allow you to alter the behaviour of the
positional_set
compatibility option.See the documentation on
$cache->set()
or "OPTIONS" for more information on this setting. - $cache->set_default_expires_in( $expires_in );
- $expires_in = $cache->get_default_expires_in();
-
These two methods allow you to alter the
expires_in
compatibility option.See the documentation on
$cache->set()
or "OPTIONS" for more information on this setting.Note that when you have both a pruning and validity policy of 'time' the
default_expires_in
of the validity policy is returned in preference to the pruning policy. Both will most likely be identical unless you're intentionally setting them differently via the new API, in which case: use the new API to get the value you want. - $cache->set_last_auto_purge( 0 | 'now' | $seconds_since_epoch );
- $seconds_since_epoch = $cache->get_last_auto_purge();
-
Sets or gets the timestamp of the last auto-purge.
See the documention for
last_auto_purge
in "OPTIONS" for further details. - $cache->set_auto_purge_on_set( 0 | 1 );
- $cache->set_auto_purge_on_get( 0 | 1 );
- $boolean = $cache->get_auto_purge_on_set();
- $boolean = $cache->get_auto_purge_on_get();
-
Turns auto-purging on/off for
$cache->set()
or$cache->get()
, or returns the current state of auto-purging for each.See the documention for
auto_purge_on_set
andauto_purge_on_get
in "OPTIONS" for further details. - $cache->set_auto_purge_interval( $seconds );
- $cache->set_auto_purge_on_set_interval( $seconds );
- $cache->set_auto_purge_on_get_interval( $seconds );
- $seconds = $cache->get_auto_purge_interval();
- $seconds = $cache->get_auto_purge_on_set_interval();
- $seconds = $cache->get_auto_purge_on_get_interval();
-
Set or get the appropriate auto-purge interval as per the
auto_purge_interval
,auto_purge_on_set_interval
orauto_purge_on_get_interval
options.Look at "OPTIONS" for further details.
- $cache->limit_size( $size );
-
Only available if a pruning policy of 'size' has been set, this method will allow you to perform a one-off prune of the storage policies to
$size
size or below.This behaves like the
limit_size()
method of Cache::SizeAwareCache.
NON-OBJECT-ORIENTATED FUNCTIONS
- $policy = best_available_storage_policy( @policies );
- $policy = best_available_pruning_policy( @policies );
- $policy = best_available_validity_policy( @policies );
-
These helper functions take a list of policies in the order you prefer them and returns the first one that is installed on the running system. This is useful if you don't know which packages are installed on the target system and have a list of alternatives you want to check against.
For example:
use Cache::CacheFactory qw/:best_available/; my $cache = Cache::CacheFactory->new( storage => best_available_storage_policy( qw/sharedmemory memory file/ ), );
This would produce either: a shared-memory cache if Cache::SharedMemoryCache was available, failing that it would try a memory cache if Cache::MemoryCache was available, and finally it would try Cache::FileCache if the other two failed.
By default these functions are not exported, you will need to supply
:best_available
on the use line to import them.
CONSTANTS
You can export the following constants:
- $NO_MAX_SIZE
-
You can export this with
use Cache::CacheFactory qw/$NO_MAX_SIZE/;
and supply it to themax_size
option of a 'size' pruning policy.This value of
$NO_MAX_SIZE
is compatible with that defined by Cache::SizeAwareCache, so you can use either source.See Cache::CacheFactory::Expiry::Size for further details.
OPTIONS
The following options may be passed to the new()
constructor:
- storage => $storage_policy
- storage => { $storage_policy1 => $policy1_options, $storage_policy2 => $policy2_options, ... }
- storage => [ $storage_policy1 => $policy1_options, $storage_policy2 => $policy2_options, ... ]
- pruning => $pruning_policy
- pruning => { $pruning_policy1 => $policy1_options, $pruning_policy2 => $policy2_options, ... }
- pruning => [ $pruning_policy1 => $policy1_options, $pruning_policy2 => $policy2_options, ... ]
- validity => $validity_policy
- validity => { $validity_policy1 => $policy1_options, $validity_policy2 => $policy2_options, ... }
- validity => [ $validity_policy1 => $policy1_options, $validity_policy2 => $policy2_options, ... ]
-
Chooses a storage, pruning, or validity policy (or policies) possibly passing in a hashref of options to each policy.
Passing a hashref of policies is probably a bad idea since you have no control over the order in which policies are processed, if you supply them as an arrayref then they will be run in order.
See "POLICIES" below for more information on policies.
- namespace => $namespace
-
The namespace associated with this cache. Defaults to "Default" if not explicitly set. All keys are unique within a given namespace, you will risk key-clashes with other applications if you use a persistent or shared storage policy and do not set a namespace to something unique to do with your application.
- auto_purge_on_set => 0 | 1
- auto_purge_on_get => 0 | 1
-
If set to a true value turns auto-purging on, if set to a false value turns auto-purging off.
auto_purge_on_set
determines if calling$cache->set()
can trigger an auto-purge, andauto_purge_on_get
does the same for$cache->get()
.Since a purge can be an expensive operation you will usually want to enable only
auto_purge_on_set
if you're in the usual read-often write-seldom environment, although see the example below inauto_purge_interval
for an alternative strategy. - auto_purge_interval => $interval
- auto_purge_on_set_interval => $interval
- auto_purge_on_get_interval => $interval
-
Sets the interval between auto-purges to
$interval
seconds.When checking whether an auto-purge should occur, the last purge time is compared to the current time, if it is more than
$interval
seconds in the past, a newpurge()
will be triggered.By use of
auto_purge_on_set_interval
andauto_purge_on_get_interval
you can tune the interval independently for each.This may be useful in some situations:
my $cache = Cache::CacheFactory->new( storage => 'memory', pruning => { 'time' => { default_prune_after => '1 m' } }, auto_purge_on_set => 1, auto_purge_on_get => 1, auto_purge_on_set_interval => 5, auto_purge_on_get_interval => 30, );
This will set a cache that prunes items older than 1 minute and will auto-purge after a
$cache->set()
if there hasn't been an auto-purge in the past 5 seconds. It will also auto-purge after a$cache->get()
if there hasn't been an auto-purge in the past 30 seconds.This means that the expense of the auto-purge will usually be added to the (relatively) expensive
set()
most of the time, and only delay the usually cheapget()
if there hasn't been a recentset()
to trigger the auto-purge.auto_purge_interval
sets bothauto_purge_on_set_interval
andauto_purge_on_get_interval
to the same value.Note that for the auto-purge intervals to be used you will need to turn on either
auto_purge_on_set
orauto_purge_on_get
. - default_expires_in => $expiry_time
-
This option is for backwards compatibility with Cache::Cache.
If set it is passed on to the
'time'
pruning and/or validity policy if you have chosen either of them.WARNING: if you do NOT have an pruning or validity policy of 'time', this option is silently ignored. This may raise a warning in future versions.
You can also manipulate this option via
$cache->set_default_expires_in()
and$cache->get_default_expires_in()
after cache creation. - positional_set => 0 | 1 | 'auto'
-
This option is for backwards compatibility with Cache::Cache.
If set to a true value that isn't 'auto' it indicates that
$cache->set()
should behave exactly as that in Cache::Cache, accepting only positional parameters. If you set this option you will be unable to supply parameters to policies other thanexpires_in
to the'time'
pruning or validity policy.If set to a value of 'auto' Cache::CacheFactory will attempt to auto-detect whether you're supplying positional or named parameters to
$cache->set()
. This mechanism is not very robust: it simply looks to see if the first parameter is the value 'key', if so it assumes you're supplying named parameters.The default behaviour, or if you set
positional_set
to a false value, is to assume that named parameters are being supplied.Generally speaking, if you know for sure that all your code is using positional parameters you should set it to true, if you know all your code is using the new named parameters syntax you should set it false (or leave it undefined), and if you're uncertain or migrating from one to the other, you should set it to 'auto' and be careful that you always supply the
key
param first.You can also manipulate this option via
$cache->set_positional_set()
and$cache->get_positional_set()
after cache creation. - last_auto_purge => 0 | 'now' | $seconds_since_epoch
-
This option grants you initial control of when the cache should consider the most recent auto-purge to have occurred, by default this is set to 0 meaning no auto-purge has occurred and one should run as soon as it is triggered.
If you set it to 'now' then the cache will "pretend" that an auto-purge occurred at the same time as the cache creation and won't run another until the auto-purge interval has expired (
auto_purge_interval
,auto_purge_on_set_interval
, orauto_purge_on_get_interval
as appropriate).You can also supply a number of seconds since the epoch, as returned by
time()
, if you want more precise control - such as if your application stores the last auto-purge time in some external manner. - nonfatal_missing_policies => 0 | 1
- nonwarning_missing_policies => 0 | 1
-
Setting
nonfatal_missing_policies
to a true value will suppress the defaultdie
behaviour when a requested policy is missing and will instead generate awarn
.If you also set
nonwarning_missing_policies
to a true value, thiswarn
will also be surpressed. - no_deep_clone => 0 | 1
-
Setting
no_deep_clone
to a true value will prevent the default behaviour of taking a deep clone of the data provided to$cache->set()
.This can be a performance gain if you don't need to be paranoid about the cache sharing references with whatever handed them in, or if you want to handle the cloning yourself within your application.
Regretfully
no_deep_clone
on the cache can only act in an advisory capacity to storage policies, they may choose to disregard the flag and many of the Cache::Cache modules will do just this. (Not unreasonably: they predate Cache::CacheFactory considerably.) Cache::CacheFactory tries hard to convince them to avoid taking clones but may or may not succeed depending on precisely what you're attempting, you'll have to suck it and see I'm afraid.Using this option with a storage policy of 'memory' will provide you with similar behaviour to Cache::FastMemoryCache, with the exception that, unavoidably, a deep clone is always created on
$cache->get()
. If this is undesirable, install Cache::FastMemoryCache and use a storage policy of 'fastmemory' in conjunction with settingno_deep_clone
.
POLICIES
There are three types of policy you can set: storage, pruning and validity.
Storage determines what mechanism is used to store the data.
Pruning determines what mechanism is used to reap or prune the cache.
Validity determines what mechanism is used to determine if a cache entry is still up-to-date.
Storage Policies
Some common storage policies:
- file
-
Implemented using Cache::FileCache, this provides on-disk caching.
- memory
-
Implemented using Cache::MemoryCache, this provides per-process in-memory caching.
-
Implemented using Cache::SharedMemoryCache, this provides in-memory caching with the cache shared between processes.
- fastmemory
-
Implemented using Cache::FastMemoryCache, this provides in-memory caching like the 'memory' policy but with all the deep-copies of data stripped out, best used in conjunction with the
no_deep_clone
option set on the cache. - null
-
Implemented using Cache::NullCache, this cache is used to provide a fake cache that never stores anything.
Pruning and Validity Policies
All pruning and validity policies are interchangable, the difference between the two is when the policy is applied:
A pruning policy is applied when you purge()
or periodically if auto_purge_on_set
or autopurge_on_get
is set, it removes all entries that fail the policy from the cache. Note that an item can be eligible to be pruned but still be in the cache and fetched successfully from the cache - it won't be removed until purge()
is called either manually or automatically.
A validity policy is applied when an entry is retreived to ensure that it's still valid (or fresh or up-to-date if you prefer). If the entry isn't still valid then it's ignored as if it was never in the cache. Unlike pruning, validity always applies - you will never be able to fetch an item from the cache if it is invalid according to the policies you have chosen.
A handy shorthand is that pruning determines how long we keep the data lying around in case we need it again, validity determines whether we trust that it's still accurate.
- time
-
This provides pruning and validity policies similar to those built into Cache::Cache using the
expires_at
param.It allows you to check for entries that are over a certain age.
- size
-
This policy prunes the cache to attempt to keep it under a supplied size, much like Cache::SizeAwareFileCache and the other
Cache::SizeAware*
modules.This policy probably doesn't make much sense as a validity policy, although you can use it.
- lastmodified
-
This policy compares the created date of the cache entry to the last-modified date of a list of file dependencies.
If the create date is older than any of the file last-modified dates the entry is pruned or regarded as invalid.
This is useful if you have data compiled or parsed from source data-files that may change, such as HTML templates or XML files.
- forever
-
This debugging policy never regards items as invalid or prunable, it's implemented as the default behaviour in Cache::CacheFactory::Expiry::Base.
WRITING NEW POLICIES
It's possible to write custom policy modules of your own, all policies are constructed using the Cache::CacheFactory::Storage or Cache::CacheFactory::Expiry class factories. Storage
provides the storage policies and Expiry
provides both the pruning and validity policies.
New storage policies should conform to the Cache::Cache API, in particular they need to implement set_object
and get_object
.
New expiry policies (both pruning and validity) should follow the API defined by Cache::CacheFactory::Expiry::Base, ideally by subclassing it.
Once you've written your new policy module you'll need to register it with Cache::CacheFactory as documented in Class::Factory, probably by placing one of the the following lines (depending on type) somewhere in your module:
Cache::CacheFactory::Storage->register_factory_type(
mypolicyname => 'MyModules::MyPolicyName' );
Cache::CacheFactory::Expiry->register_factory_type(
mypolicyname => 'MyModules::MyPolicyName' );
Then you just need to make sure that your application has a
use MyModules::MyPolicyName;
before you ask Cache::CacheFactory to create a cache with 'mypolicyname' as a policy.
INTERNAL METHODS
The following methods are mostly for internal use, but may be useful to redefine if you're subclassing Cache::CacheFactory for some reason.
- $object = $cache->new_cache_entry_object();
-
Returns a new and uninitialized object to use for a cache entry, by default this object will be a Cache::CacheFactory::Object, if for some reason you want to overrule that decision you can return your own object.
- $cache->set_policy( $policytype, $policies );
-
Used as part of the
new()
constructor, this sets the policy type$policytype
to use the policies defined in$policies
, this may do strange things if you do it to an already used cache instance. - $cache->set_storage_policies( $policies );
- $cache->set_pruning_policies( $policies );
- $cache->set_validity_policies( $policies );
-
Convenience wrappers around
set_policy
. - $cache->get_policy_driver( $policytype, $policy );
-
Gets the driver object instance for the matching
$policytype
and$policy
, useful if it has non-standard extensions to the API that you can't access through Cache::CacheFactory. - $cache->get_policy_drivers( $policytype );
-
Returns a hashref of policies to driver object instances for policy type
$policytype
, you should probably useget_policy_driver()
instead to get a specific driver though. - $cache->foreach_policy( $policytype, $closure );
-
Runs the closure/coderef
$closure
over each policy of type$policytype
supplying args:Cache::CacheFactory
instance, policy name, and policy driver.The closure is run over each policy in order, or until the closure calls the
last()
method on theCache::CacheFactory
instance.use Data::Dumper; use Cache::CacheFactory; $cache = Cache::CacheFactory->new( ... ); $cache->foreach_policy( 'storage', sub { my ( $cache, $policy, $driver ) = @_; print "Storage policy '$policy' has driver: ", Data::Dumper::Dumper( $driver ), "\n"; return $cache->last() if $policy eq 'file'; } );
This will print the policy name and driver object for each storage policy in turn until it encounters a
'file'
policy. - $cache->foreach_driver( $policytype, $method, @args );
-
Much like
foreach_policy()
above, this method iterates over each policy, this time invoking method$method
on the driver with the arguments specified in@args
.$cache->foreach_driver( 'storage', 'do_something', 'with', 'args' );
will call:
$driver->do_something( 'with', 'args' );
on each storage driver in turn.
The return value of the method called is discarded, if it's important to you then you should use
foreach_policy
and call the method on the driver arg provided, collating the results however you wish. - $cache->last();
-
Indicates that
foreach_policy()
orforeach_driver
should exit at the end of the current iteration.last()
does NOT exit your closure for you, if you want it to behave like perl'slast
construct you will want to doreturn $cache->last()
. - $cache->auto_purge( 'set' | 'get' );
-
Attempts an auto-purge according to the
auto_purge_on_set
andauto_purge_on_get
settings and the$cache->get_last_auto_purge()
value. - $cache->error( $error_message );
-
Raise a fatal error with message given by
$error_message
. - $cache->warning( $warning_message );
-
Raise a warning with message given by
$warning_message
.
KNOWN ISSUES AND BUGS
- Pruning and validity policies are per-cache rather than per-storage
-
Pruning and validity policies are set on a per-cache basis rather than on a per-storage-policy basis, this makes multiple storage policies largely pointless for most purposes where you'd find it useful.
If you wanted the cache to transparently use a small fast memory cache first and fall back to a larger slower file cache as backup: you can't do it, because the size pruning policy would be the same for both storage policies.
About the only current use of multiple storage policies is to have a memory cache and a file cache so that processes that haven't pulled a copy into their memory cache yet will retreive it from the copy another process has placed in the file cache. This might be slightly more useful than a shared memory cache since the on-file cache will persist even if there's no running processes unlike the shared memory cache.
Per-storage pruning and validity settings may make it into a future version if they prove useful and won't over-complicate matters - for now it's best to create a wrapper module that internally creates the caches seperately but presents the Cache::Cache API externally.
- Add/replace aren't atomic
-
The
$cache->add/replace()
methods aren't atomic, this mostly defeats their purpose in a shared-cache situation. This could be considered a bug. - Aren't there a million Cache::Cache replacements already?
-
At the time I started writing Cache::CacheFactory I'd been trying to find a caching solution that had the combination of features I needed, I had no luck in finding one.
Since then I've found a couple of other similar modules, and more have been written and released, you may or may not find them suiting your needs more closely, so I suggest taking a good look:
CHI - this module appears to have much the same motivation and strategy as Cache::CacheFactory in terms of storage policies, however, from what I can gather, it doesn't appear to split validity/pruning policies into seperate and/or combinable modules.
Cache - not sure how I missed this one when I was researching, it's a mature module that gives you flexibile validity/pruning policies but doesn't have such a wide range of storage policies available.
Please note that these descriptions are from my own imperfect understanding of the modules concerned, by no means take them as an authorative description of their functionality. Please feel free to contact me if I've included any inaccuracies. :)
SEE ALSO
Cache::Cache, Cache::CacheFactory::Object, Cache::CacheFactory::Expiry::Base, Cache::CacheFactory::Expiry::Time, Cache::CacheFactory::Expiry::Size, Cache::CacheFactory::Expiry::LastModified, Cache::FastMemoryCache
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Cache::CacheFactory
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
AUTHORS
Original author: Sam Graham <libcache-cachefactory-perl BLAHBLAH illusori.co.uk>
Last author: $Author: illusori $
ACKNOWLEDGEMENTS
DeWitt Clinton for the original Cache::Cache, most of the hard work is done by this module and its subclasses.
Chris Winters for Class::Factory, saving me the trouble of finding out what policy modules are or aren't available.
John Millaway for Cache::FastMemoryCache, which inspired the no_deep_clone
option.
COPYRIGHT & LICENSE
Copyright 2008-2009 Sam Graham, all rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.