File Coverage

blib/lib/XML/LibXML/Cache/Base.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package XML::LibXML::Cache::Base;
2             {
3             $XML::LibXML::Cache::Base::VERSION = '0.12';
4             }
5 2     2   11 use strict;
  2         4  
  2         67  
6              
7             # ABSTRACT: Base class for XML::LibXML caches
8              
9 2     2   1843 use URI;
  2         9923  
  2         68  
10 2     2   1003 use XML::LibXML 1.59;
  0            
  0            
11              
12             our $input_callbacks = XML::LibXML::InputCallback->new();
13             $input_callbacks->register_callbacks([
14             \&_match_cb,
15             \&_open_cb,
16             \&_read_cb,
17             \&_close_cb,
18             ]);
19              
20             my $deps_found;
21              
22             sub new {
23             my $class = shift;
24              
25             my $self = {
26             cache => {},
27             hits => 0,
28             };
29              
30             return bless($self, $class);
31             }
32              
33             sub cache_hits {
34             my $self = shift;
35              
36             return $self->{hits};
37             }
38              
39             sub _cache_lookup {
40             my ($self, $filename, $get_item) = @_;
41              
42             my $item = $self->_cache_read($filename);
43              
44             if ($item) {
45             ++$self->{hits};
46             return $item;
47             }
48              
49             $deps_found = {};
50              
51             $item = $get_item->($filename);
52              
53             $self->_cache_write($filename, $item);
54              
55             $deps_found = undef;
56              
57             return $item;
58             }
59              
60             sub _cache_read {
61             my ($self, $filename) = @_;
62              
63             my $cache_rec = $self->{cache}{$filename}
64             or return ();
65              
66             my ($item, $deps) = @$cache_rec;
67              
68             # check sizes and mtimes of deps_found
69              
70             while (my ($path, $attrs) = each(%$deps)) {
71             my @stat = stat($path);
72             my ($size, $mtime) = @stat ? ($stat[7], $stat[9]) : (-1, -1);
73              
74             return () if $size != $attrs->[0] || $mtime != $attrs->[1];
75             }
76              
77             return $item;
78             }
79              
80             sub _cache_write {
81             my ($self, $filename, $item) = @_;
82              
83             my $cache = $self->{cache};
84              
85             if ($deps_found) {
86             $cache->{$filename} = [ $item, $deps_found ];
87             }
88             else {
89             delete($cache->{$filename});
90             }
91             }
92              
93             # Handling of dependencies
94              
95             # We register an input callback that never matches but records all URIs
96             # that are accessed during parsing.
97              
98             sub _match_cb {
99             my $uri_str = shift;
100              
101             return undef if !$deps_found;
102              
103             my $uri = URI->new($uri_str, 'file');
104             my $scheme = $uri->scheme;
105              
106             if (!defined($scheme) || $scheme eq 'file') {
107             my $path = $uri->path;
108             my @stat = stat($path);
109             $deps_found->{$path} = @stat ?
110             [ $stat[7], $stat[9] ] :
111             [ -1, -1 ];
112             }
113             else {
114             # Unsupported URI, disable caching
115             $deps_found = undef;
116             }
117              
118             return undef;
119             }
120              
121             # should never be called
122             sub _open_cb { die('open callback called unexpectedly'); }
123             sub _read_cb { die('read callback called unexpectedly'); }
124             sub _close_cb { die('close callback called unexpectedly'); }
125              
126             1;
127              
128              
129              
130             =pod
131              
132             =head1 NAME
133              
134             XML::LibXML::Cache::Base - Base class for XML::LibXML caches
135              
136             =head1 VERSION
137              
138             version 0.12
139              
140             =head1 DESCRIPTION
141              
142             Base class for the document and style sheet caches.
143              
144             =head1 METHODS
145              
146             =head2 new
147              
148             Only used by subclasses.
149              
150             =head2 cache_hits
151              
152             my $hits = $cache->cache_hits;
153              
154             Return the number of cache hits.
155              
156             =head1 AUTHOR
157              
158             Nick Wellnhofer
159              
160             =head1 COPYRIGHT AND LICENSE
161              
162             This software is copyright (c) 2012 by Nick Wellnhofer.
163              
164             This is free software; you can redistribute it and/or modify it under
165             the same terms as the Perl 5 programming language system itself.
166              
167             =cut
168              
169              
170             __END__