File Coverage

blib/lib/Iterator/Flex/Cache.pm
Criterion Covered Total %
statement 67 67 100.0
branch 8 12 66.6
condition 6 6 100.0
subroutine 19 19 100.0
pod 1 2 50.0
total 101 106 95.2


line stmt bran cond sub pod time code
1             package Iterator::Flex::Cache;
2              
3             # ABSTRACT: Cache Iterator Class
4              
5 3     3   306390 use v5.28;
  3         31  
6 3     3   52 use strict;
  3         9  
  3         96  
7 3     3   22 use warnings;
  3         7  
  3         198  
8 3     3   600 use experimental qw( signatures postderef );
  3         1817  
  3         51  
9              
10             our $VERSION = '0.33';
11              
12 3     3   825 use parent 'Iterator::Flex::Base';
  3         9  
  3         38  
13 3     3   323 use Iterator::Flex::Utils qw( STATE :IterAttrs :IterStates throw_failure );
  3         76  
  3         802  
14 3     3   638 use Iterator::Flex::Factory 'to_iterator';
  3         7  
  3         274  
15 3     3   23 use Scalar::Util;
  3         7  
  3         161  
16 3     3   32 use Ref::Util;
  3         7  
  3         137  
17              
18 3     3   18 use namespace::clean;
  3         7  
  3         57  
19              
20              
21              
22              
23              
24              
25              
26              
27              
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41              
42              
43              
44              
45              
46              
47              
48              
49              
50              
51              
52              
53              
54              
55              
56              
57              
58              
59              
60              
61 9     9 1 20 sub new ( $class, $iterable, $pars = {} ) {
  9         19  
  9         18  
  9         18  
  9         15  
62              
63 9 50       35 throw_failure( parameter => 'q{pars} argument must be a hash' )
64             unless Ref::Util::is_hashref( $pars );
65              
66 9         33 my %pars = $pars->%*;
67              
68 9   100     46 my $capacity = delete $pars{capacity} // 2;
69              
70 9         52 $class->SUPER::new( {
71             capacity => $capacity,
72             depends => [ to_iterator( $iterable ) ],
73             },
74             \%pars,
75             );
76             }
77              
78              
79              
80              
81              
82              
83              
84              
85              
86              
87 11     11 0 20 sub construct ( $class, $state ) {
  11         21  
  11         21  
  11         18  
88              
89 11 50       36 throw_failure( parameter => q{state must be a HASH reference} )
90             unless Ref::Util::is_hashref( $state );
91              
92 11         27 my ( $src, $capacity, $idx, $cache ) = @{$state}{qw[ depends capacity idx cache ]};
  11         45  
93 11         23 $src = $src->[0];
94 11   100     55 $idx //= -1;
95 11   100     49 $cache //= [];
96              
97 11         17 my $self;
98 11         49 my $is_exhausted = $src->can( 'is_exhausted' );
99 11         20 my $iterator_state;
100              
101             return {
102              
103             ( +_SELF ) => \$self,
104              
105             ( +STATE ) => \$iterator_state,
106              
107             ( +RESET ) => sub {
108 2     2   5 $idx = -1;
109 2         4 @{$cache} = ();
  2         7  
110             },
111              
112       2     ( +REWIND ) => sub {
113             },
114              
115             ( +PREV ) => sub {
116 34 50   34   180 return defined $idx ? $cache->[ ( $idx - 1 ) % $capacity ] : undef;
117             },
118              
119             ( +CURRENT ) => sub {
120 34 50   34   154 return defined $idx ? $cache->[ $idx % $capacity ] : undef;
121             },
122              
123             ( +NEXT ) => sub {
124              
125 95 100   95   271 return $self->signal_exhaustion
126             if $iterator_state == IterState_EXHAUSTED;
127              
128 83         155 $idx = ++$idx % $capacity;
129 83         289 my $current = $cache->[$idx] = $src->();
130              
131 83 100       228 return $self->signal_exhaustion
132             if $src->$is_exhausted;
133              
134 72         285 return $current;
135             },
136              
137 110         169 ( +METHODS ) => {
138 110     110   208 at => sub ( $, $at ) {
  110         169  
139 110         353 $cache->[ ( $idx - $at ) % $capacity ];
140             },
141             },
142              
143             ( +FREEZE ) => sub {
144 2     2   13 return [ $class, { idx => $idx, capacity => $capacity, cache => $cache } ];
145             },
146              
147 11         307 ( +_DEPENDS ) => $src,
148             };
149             }
150              
151              
152              
153             __PACKAGE__->_add_roles( qw[
154             State::Closure
155             Next::ClosedSelf
156             Rewind::Closure
157             Reset::Closure
158             Prev::Closure
159             Current::Closure
160             Freeze
161             ] );
162              
163              
164             1;
165              
166             #
167             # This file is part of Iterator-Flex
168             #
169             # This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
170             #
171             # This is free software, licensed under:
172             #
173             # The GNU General Public License, Version 3, June 2007
174             #
175              
176             __END__