File Coverage

blib/lib/Cache/Range.pm
Criterion Covered Total %
statement 15 60 25.0
branch 0 12 0.0
condition n/a
subroutine 5 8 62.5
pod 3 3 100.0
total 23 83 27.7


line stmt bran cond sub pod time code
1             package Cache::Range;
2              
3 1     1   28310 use strict;
  1         3  
  1         36  
4 1     1   5 use warnings;
  1         2  
  1         27  
5              
6 1     1   885 use Tree::R;
  1         24178  
  1         60  
7 1     1   1118 use Storable qw(freeze thaw);
  1         4090  
  1         66  
8              
9 1     1   863 use namespace::clean;
  1         17409  
  1         7  
10              
11             our $VERSION = '0.01';
12              
13             sub new {
14 0     0 1   my ( $class, $cache ) = @_;
15            
16 0           return bless \$cache, $class;
17             }
18              
19             sub set {
20 0     0 1   my $self = shift;
21 0           my $key = shift;
22 0           my $start = shift;
23 0           my $data = shift;
24 0           my $cache = $$self;
25 0           my $end = $start + $#$data;
26              
27 0           $cache->set(join('_', $key, $start, $end), freeze($data), @_);
28 0           $data = {
29             end => $end,
30             start => $start,
31             };
32 0           my $rtree = $cache->get($key . '_rtree');
33 0 0         if($rtree) {
34 0           $rtree = thaw($rtree);
35             } else {
36 0           $rtree = Tree::R->new;
37             }
38 0           $rtree->insert($data, $start, 0, $end, 0);
39 0           $cache->set($key . '_rtree', freeze($rtree), $Cache::EXPIRES_NEVER);
40             }
41              
42             sub get {
43 0     0 1   my ( $self, $key, $start, $end ) = @_;
44              
45 0           my $cache = $$self;
46 0           my $rtree = $cache->get($key . '_rtree');
47 0           my $dirty = 0;
48              
49 0 0         return unless $rtree;
50 0           $rtree = thaw($rtree);
51              
52 0           my @results;
53             my @retval;
54 0           $rtree->query_partly_within_rect($start, 0, $end, 0, \@results);
55 0           @results = sort { $a->{'start'} <=> $b->{'start'} } @results;
  0            
56              
57 0           foreach my $entry (@results) {
58 0           my ( $e, $s ) = @{$entry}{qw/end start/};
  0            
59 0           my $data = $cache->get(join('_', $key, $s, $e));
60              
61 0 0         unless($data) {
62 0           $rtree->remove($entry);
63 0           $dirty = 1;
64 0           next;
65             }
66 0           $data = thaw($data);
67              
68 0           $data = [ @$data ];
69              
70 0 0         if($s < $start) {
71 0           splice @$data, 0, $start - $s;
72 0           $s = $start;
73             }
74 0 0         if($e > $end) {
75 0           splice @$data, $end - $e;
76             }
77              
78 0           push @retval, $s, $data;
79             }
80 0 0         if($dirty) {
81 0           $cache->set($key . '_rtree', freeze($rtree), $Cache::EXPIRES_NEVER);
82             }
83 0           return @retval;
84             }
85              
86             1;
87              
88             __END__