File Coverage

lib/Sub/Contract/Cache.pm
Criterion Covered Total %
statement 42 42 100.0
branch 7 12 58.3
condition 2 6 33.3
subroutine 10 10 100.0
pod 5 5 100.0
total 66 75 88.0


line stmt bran cond sub pod time code
1             #-------------------------------------------------------------------
2             #
3             # Sub::Contract::Cache - Implement a subroutine's cache
4             #
5             # $Id: Cache.pm,v 1.3 2009/06/16 12:23:58 erwan_lemonnier Exp $
6             #
7              
8             package Sub::Contract::Cache;
9              
10 22     22   1046 use strict;
  22         43  
  22         702  
11 22     22   107 use warnings;
  22         45  
  22         579  
12 22     22   103 use Carp qw(croak confess);
  22         39  
  22         1242  
13 22     22   1148 use Data::Dumper;
  22         6990  
  22         1002  
14 22     22   822 use Symbol;
  22         868  
  22         13396  
15              
16             our $VERSION = '0.12';
17              
18             # NOTE: to speed up things, we do very little sanity control of method
19             # arguments, so that a key can for example be undefined though it
20             # should be an error. This class is to be used internally by
21             # Sub::Contract only. If you attempt to use it directly for other
22             # purpose, make sure you really need to do that, and if so, don't rely
23             # on Sub::Contract::Cache to validate them for you.
24              
25             sub new {
26 8     8 1 32 my ($class,%args) = @_;
27 8   33     31 $class = ref $class || $class;
28 8 50       36 my $size = delete $args{size} or croak "BUG: missing max_size";
29 8 50       27 my $namespace = delete $args{namespace} or croak "BUG: missing namespace";
30              
31 8 50       26 croak "BUG: new() got unknown arguments: ".Dumper(%args) if (%args);
32 8 50 33     48 croak "BUG: size should be a number" if (!defined $size || $size !~ /^\d+$/);
33              
34             # NOTE: $contract->reset() deletes this cache
35             # TODO: do we want to keep previous content of cache?
36 8         36 my $self = bless({},$class);
37 8         26 $self->{cache} = {};
38 8         18 $self->{cache_max_size} = $size;
39 8         15 $self->{cache_size} = 0;
40 8         19 $self->{namespace} = $namespace;
41              
42 8         29 return $self;
43             }
44              
45             sub clear {
46 1     1 1 2 my $self = shift;
47             # a fast way to delete all keys in a hash
48 1         29 delete @{$self->{cache}}{keys %{$self->{cache}}};
  1         5  
  1         25  
49 1         4 $self->{cache_size} = 0;
50             }
51              
52             sub has {
53 71     71 1 108 my ($self,$key) = @_;
54 71         1455 return exists $self->{cache}->{$key};
55             }
56              
57             sub set {
58 31     31 1 59 my ($self,$key,$value) = @_;
59              
60 31 50       86 croak "BUG: undefined cache key".Dumper($key,$value)
61             if (!defined $key);
62              
63 31 100       87 if ($self->{cache_size} >= $self->{cache_max_size}) {
64 1         4 $self->clear;
65             }
66              
67 31         101 $self->{cache}->{$key} = $value;
68 31         568 $self->{cache_size}++;
69             }
70              
71              
72             sub get {
73 40     40 1 57 my ($self,$key) = @_;
74 40         184 return $self->{cache}->{$key};
75             }
76              
77             1;
78              
79             =pod
80              
81             =head1 NAME
82              
83             Sub::Contract::Cache - A data cache
84              
85             =head1 SYNOPSIS
86              
87             my $cache = new Sub::Contract::Cache(max_size => 10000, namespace => 'foo');
88              
89             if ($cache->has($key)) {
90             return $cache->get($key);
91             } else {
92             my $value = foo(@args);
93             $cache->set($key,$value);
94             return $value;
95             }
96              
97             =head1 DESCRIPTION
98              
99             A Sub::Contract::Cache is just a data cache used by contracts to
100             memoize subroutine's results. Sub::Contract has its own cache
101             implementation for efficiency reasons.
102              
103             =head1 API
104              
105             =over 4
106              
107             =item C<< my $cache = new(max_size => $max_size, namespace => $name) >>
108              
109             Return an empty cache object that may contain up to C<$max_size>
110             elements and caches results from the subroutine C<$name>.
111              
112             =item C<< $contract->clear([size => $max_size]) >>
113              
114             Empty this cache of all its elements.
115              
116             =item C<< $contract->set($key,$ref_result) >>
117              
118             Add a cache entry for the key C<$key> with result C<$result>.
119              
120             =item C<< $contract->has($key) >>
121              
122             Return true if the cache contains a result for this key, false if not.
123              
124             =item C<< $contract->get($key) >>
125              
126             Return the cached result associated with key C<$key>. You must call
127             C first to ensure that there really is a cached result for this
128             key. C on an unknown key will return undef and not fail.
129              
130             =back
131              
132             =head1 SEE ALSO
133              
134             See 'Sub::Contract'.
135              
136             =head1 VERSION
137              
138             $Id: Cache.pm,v 1.3 2009/06/16 12:23:58 erwan_lemonnier Exp $
139              
140             =head1 AUTHOR
141              
142             Erwan Lemonnier C<< >>
143              
144             =head1 LICENSE
145              
146             See Sub::Contract.
147              
148             =cut
149              
150              
151