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;  | 
