diff options
author | Arne Georg Gleditsch <argggh@lxr.linpro.no> | 2007-07-05 00:51:08 +0200 |
---|---|---|
committer | Arne Georg Gleditsch <argggh@lxr.linpro.no> | 2007-07-05 00:51:08 +0200 |
commit | e9fa4c98bb5f084739d3418ade3f0c51e34a0aa1 (patch) | |
tree | fec1d635625e031cde7cba1b0a1d95ee92ac760b /lib/LXRng/Cached.pm |
Rebase tree.
Diffstat (limited to 'lib/LXRng/Cached.pm')
-rw-r--r-- | lib/LXRng/Cached.pm | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/LXRng/Cached.pm b/lib/LXRng/Cached.pm new file mode 100644 index 0000000..f11a749 --- /dev/null +++ b/lib/LXRng/Cached.pm @@ -0,0 +1,63 @@ +package LXRng::Cached; + +use strict; +require Exporter; +use vars qw($memcached @ISA @EXPORT); +@ISA = qw(Exporter); +@EXPORT = qw(cached); + +BEGIN { + eval { require Cache::Memcached; + require Storable; + require Digest::SHA1; + }; + if ($@ eq '') { + $memcached = Cache::Memcached->new({ + 'servers' => ['127.0.0.1:11211']}); + $memcached = undef + unless ($memcached->set(':lxrng_caching' => 1)) + } +} + +# Caches result from block enclosed by cache { ... }. File/linenumber +# of the "cache" keyword is used as the caching key. If additional +# arguments are given after the sub to cache, they are used to further +# specify the caching key. Otherwise, the arguments supplied to the +# function containing the call to cached are used. + +sub cached(&;@); +*cached = \&DB::LXRng_Cached_cached; + +package DB; + +sub LXRng_Cached_cached(&;@) { + my ($func, @args) = @_; + if ($LXRng::Cached::memcached) { + my ($pkg, $file, $line) = caller(0); + my $params; + if (@args > 0) { + $params = Storable::freeze(\@args); + } + else { + my @caller = caller(1); + $params = Storable::freeze(\@DB::args); + } + my $key = ':lxrng:'. + Digest::SHA1::sha1_hex(join("\0", $file, $line, $params)); + my $val = $LXRng::Cached::memcached->get($key); + unless ($val) { + $val = [$func->()]; + $LXRng::Cached::memcached->set($key, $val); + warn "cache miss for $key"; + } + else { + warn "cache hit for $key"; + } + return @$val; + } + else { + return $func->(); + } +} + +1; |