File Coverage

blib/lib/CHI.pm
Criterion Covered Total %
statement 86 88 97.7
branch 25 28 89.2
condition 19 21 90.4
subroutine 18 19 94.7
pod 2 6 33.3
total 150 162 92.5


line stmt bran cond sub pod time code
1             package CHI;
2             $CHI::VERSION = '0.61';
3 21     21   78498 use 5.006;
  21         82  
4 21     21   121 use Carp;
  21         39  
  21         5857  
5 21     21   9553 use CHI::Stats;
  21         71  
  21         948  
6 21     21   10984 use String::RewritePrefix;
  21         278212  
  21         164  
7 21     21   4800 use Module::Runtime qw(require_module);
  21         55  
  21         182  
8 21     21   13027 use Moo::Role ();
  21         189838  
  21         645  
9 21     21   183 use strict;
  21         51  
  21         458  
10 21     21   115 use warnings;
  21         43  
  21         3809  
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 1030     1030 1 2168 my $class = shift;
23 1030 100       2909 $class->_set_config(@_) if @_;
24 1030         2516 return $class->_get_config();
25             }
26              
27             sub _set_config {
28 24     24   75 my ( $class, $config ) = @_;
29 24 50       207 if ( my @bad_keys = grep { !$valid_config_keys{$_} } keys(%$config) ) {
  10         30  
30 0         0 croak "unknown keys in config hash: " . join( ", ", @bad_keys );
31             }
32              
33             # set class specific configuration
34 21     21   170 no strict 'refs';
  21         46  
  21         799  
35 21     21   132 no warnings 'redefine';
  21         46  
  21         2055  
36 24     1030   116 *{"$class\::_get_config"} = sub { $config };
  24         167  
  1030         15436  
37             }
38              
39 21     21   157 BEGIN { __PACKAGE__->config( {} ) }
40              
41             sub memoized_cache_objects {
42 4     4 0 9 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         9 return $memoized_cache_objects{$class};
48             }
49              
50             sub clear_memoized_cache_objects {
51 1     1 0 4 my ($class) = @_;
52              
53 1         3 $memoized_cache_objects{$class} = {};
54             }
55              
56             sub stats {
57 999     999 0 2181 my ($class) = @_;
58              
59             # Each CHI root class gets its own stats object
60             #
61 999   66     3730 $stats{$class} ||= CHI::Stats->new( chi_root_class => $class );
62 999         2649 return $stats{$class};
63             }
64              
65             sub new {
66 1006     1006 1 4968 my ( $chi_root_class, %params ) = @_;
67              
68 1006         3218 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 1006         2046 my ( $cache_object_key, $cache_objects );
75 1006 100 100     3791 if ( $config->{memoize_cache_objects} && keys(%params) <= 1 ) {
76 4         14 $cache_object_key = join chr(28), %params;
77 4         12 $cache_objects = $chi_root_class->memoized_cache_objects;
78 4 100       12 if ( my $cache_object = $cache_objects->{$cache_object_key} ) {
79 2         8 return $cache_object;
80             }
81             }
82              
83             # Gather defaults
84             #
85 1004   100     4822 my $core_defaults = $config->{defaults} || {};
86             my $namespace_defaults =
87 1004   100     6382 $config->{namespace}->{ $params{namespace} || 'Default' } || {};
88             my $storage =
89             $params{storage}
90             || $namespace_defaults->{storage}
91 1004   66     5660 || $core_defaults->{storage};
92 1004         1811 my $storage_defaults = {};
93 1004 100       2467 if ( defined($storage) ) {
94 16 50       42 $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 1004         6553 ( %$core_defaults, %$storage_defaults, %$namespace_defaults, %params );
102              
103             # Get driver class from driver or driver_class parameters
104             #
105 1004         2043 my $driver_class;
106 1004 100       3119 if ( my $driver = delete( $params{driver} ) ) {
107 910         7354 ($driver_class) =
108             String::RewritePrefix->rewrite( { '' => 'CHI::Driver::', '+' => '' },
109             $driver );
110             }
111             else {
112 94         232 $driver_class = delete( $params{driver_class} );
113             }
114 1004 50       63809 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 1004 100       8775 unless ( $driver_class->can('fetch') ) {
120 17         97 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 1001         2687 my @roles = ('Universal');
128 1001         2213 foreach my $param_name (qw(roles traits)) {
129 2002 100       5140 if ( exists( $params{$param_name} ) ) {
130 182         305 push( @roles, @{ delete( $params{$param_name} ) } );
  182         585  
131             }
132             }
133 1001 100 100     4910 if ( exists( $params{max_size} ) || exists( $params{is_size_aware} ) ) {
134 161         371 push( @roles, 'IsSizeAware' );
135             }
136 1001 100 100     4082 if ( exists( $params{l1_cache} ) || exists( $params{mirror_cache} ) ) {
137 150         299 push( @roles, 'HasSubcaches' );
138             }
139 1001 100       2776 if ( $params{is_subcache} ) {
140 165         373 push( @roles, 'IsSubcache' );
141             }
142 1001         4461 @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 1001         60656 my $final_class =
149             Moo::Role->create_class_with_roles( $driver_class, @roles );
150              
151 1001         322231 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 998 100       25848 if ($cache_object_key) {
160 2         7 $cache_objects->{$cache_object_key} = $cache_object;
161             }
162              
163 998         11784 return $cache_object;
164             }
165              
166             1;
167              
168             __END__