File Coverage

blib/lib/CHI.pm
Criterion Covered Total %
statement 87 89 97.7
branch 25 28 89.2
condition 19 21 90.4
subroutine 18 19 94.7
pod 2 6 33.3
total 151 163 92.6


line stmt bran cond sub pod time code
1             package CHI;
2             $CHI::VERSION = '0.60';
3 21     27   26347 use 5.006;
  21         58  
  21         845  
4 21     21   104 use Carp;
  21         28  
  21         1573  
5 21     21   8402 use CHI::Stats;
  21         68  
  21         888  
6 21     21   11867 use String::RewritePrefix;
  21         216992  
  21         142  
7 21     21   3562 use Module::Runtime qw(require_module);
  21         37  
  21         175  
8 21     21   13224 use Moo::Role ();
  21         150216  
  21         597  
9 21     21   135 use strict;
  21         34  
  21         657  
10 21     21   90 use warnings;
  21         32  
  21         3248  
11              
12             my ( %final_class_seen, %memoized_cache_objects, %stats );
13             my %valid_config_keys =
14             map { ( $_, 1 ) } qw(defaults memoize_cache_objects namespace storage);
15              
16             sub logger {
17 0     0 0 0 warn
18             "CHI now uses Log::Any for logging - see Log::Any documentation for details";
19             }
20              
21             sub config {
22 914     914 1 1915 my $class = shift;
23 914 100       2608 $class->_set_config(@_) if @_;
24 914         2528 return $class->_get_config();
25             }
26              
27             sub _set_config {
28 24     24   42 my ( $class, $config ) = @_;
29 24 50       100 if ( my @bad_keys = grep { !$valid_config_keys{$_} } keys(%$config) ) {
  10         19  
30 0         0 croak "unknown keys in config hash: " . join( ", ", @bad_keys );
31             }
32              
33             # set class specific configuration
34 21     21   104 no strict 'refs';
  21         35  
  21         631  
35 21     21   88 no warnings 'redefine';
  21         59  
  21         1547  
36 24     914   79 *{"$class\::_get_config"} = sub { $config };
  24         127  
  914         12353  
37             }
38              
39 21     21   119 BEGIN { __PACKAGE__->config( {} ) }
40              
41             sub memoized_cache_objects {
42 4     4 0 5 my ($class) = @_;
43              
44             # Each CHI root class gets its hash of memoized objects
45             #
46 4   100     11 $memoized_cache_objects{$class} ||= {};
47 4         5 return $memoized_cache_objects{$class};
48             }
49              
50             sub clear_memoized_cache_objects {
51 1     1 0 2 my ($class) = @_;
52              
53 1         3 $memoized_cache_objects{$class} = {};
54             }
55              
56             sub stats {
57 883     883 0 1486 my ($class) = @_;
58              
59             # Each CHI root class gets its own stats object
60             #
61 883   66     3421 $stats{$class} ||= CHI::Stats->new( chi_root_class => $class );
62 883         2772 return $stats{$class};
63             }
64              
65             sub new {
66 890     890 1 3868 my ( $chi_root_class, %params ) = @_;
67              
68 890         3174 my $config = $chi_root_class->config;
69              
70             # Cache object memoization: See if cache object with these parameters
71             # has already been created, and return it if so. Only for parameters
72             # with 0 or 1 keys.
73             #
74 890         1173 my ( $cache_object_key, $cache_objects );
75 890 100 100     3278 if ( $config->{memoize_cache_objects} && keys(%params) <= 1 ) {
76 4         9 $cache_object_key = join chr(28), %params;
77 4         10 $cache_objects = $chi_root_class->memoized_cache_objects;
78 4 100       9 if ( my $cache_object = $cache_objects->{$cache_object_key} ) {
79 2         5 return $cache_object;
80             }
81             }
82              
83             # Gather defaults
84             #
85 888   100     5049 my $core_defaults = $config->{defaults} || {};
86 888   100     5977 my $namespace_defaults =
87             $config->{namespace}->{ $params{namespace} || 'Default' } || {};
88 888   66     16035 my $storage =
89             $params{storage}
90             || $namespace_defaults->{storage}
91             || $core_defaults->{storage};
92 888         1332 my $storage_defaults = {};
93 888 100       2261 if ( defined($storage) ) {
94 16 50       38 $storage_defaults = $config->{storage}->{$storage}
95             or croak "no config for storage type '$storage'";
96             }
97              
98             # Combine passed params with defaults
99             #
100             %params =
101 888         6830 ( %$core_defaults, %$storage_defaults, %$namespace_defaults, %params );
102              
103             # Get driver class from driver or driver_class parameters
104             #
105 888         1782 my $driver_class;
106 888 100       3102 if ( my $driver = delete( $params{driver} ) ) {
107 805         6428 ($driver_class) =
108             String::RewritePrefix->rewrite( { '' => 'CHI::Driver::', '+' => '' },
109             $driver );
110             }
111             else {
112 83         200 $driver_class = delete( $params{driver_class} );
113             }
114 888 50       49443 croak "missing required param 'driver' or 'driver_class'"
115             unless defined $driver_class;
116              
117             # Load driver class if it hasn't been loaded or defined in-line already
118             #
119 888 100       10451 unless ( $driver_class->can('fetch') ) {
120 15         82 require_module($driver_class);
121             }
122              
123             # Select roles depending on presence of certain arguments. Everyone gets
124             # the Universal role. Accept both 'roles' and 'traits' for backwards
125             # compatibility. Add CHI::Driver::Role:: unless prefixed with '+'.
126             #
127 885         2289 my @roles = ('Universal');
128 885         1680 foreach my $param_name (qw(roles traits)) {
129 1770 100       4532 if ( exists( $params{$param_name} ) ) {
130 182         200 push( @roles, @{ delete( $params{$param_name} ) } );
  182         626  
131             }
132             }
133 885 100 100     5213 if ( exists( $params{max_size} ) || exists( $params{is_size_aware} ) ) {
134 140         322 push( @roles, 'IsSizeAware' );
135             }
136 885 100 100     5124 if ( exists( $params{l1_cache} ) || exists( $params{mirror_cache} ) ) {
137 138         327 push( @roles, 'HasSubcaches' );
138             }
139 885 100       2194 if ( $params{is_subcache} ) {
140 146         295 push( @roles, 'IsSubcache' );
141             }
142 885         4603 @roles = String::RewritePrefix->rewrite(
143             { '' => 'CHI::Driver::Role::', '+' => '' }, @roles );
144              
145             # Select a final class based on the driver class and roles, creating it
146             # if necessary - adapted from MooseX::Traits
147             #
148 885         44944 my $final_class =
149             Moo::Role->create_class_with_roles( $driver_class, @roles );
150              
151 885         204266 my $cache_object = $final_class->new(
152             chi_root_class => $chi_root_class,
153             driver_class => $driver_class,
154             %params
155             );
156              
157             # Memoize if appropriate
158             #
159 882 100       7740 if ($cache_object_key) {
160 2         5 $cache_objects->{$cache_object_key} = $cache_object;
161             }
162              
163 882         9665 return $cache_object;
164             }
165              
166             1;
167              
168             __END__