File Coverage

blib/lib/DWH_File/Tie/Array.pm
Criterion Covered Total %
statement 121 135 89.6
branch 21 36 58.3
condition 11 18 61.1
subroutine 24 26 92.3
pod 0 8 0.0
total 177 223 79.3


line stmt bran cond sub pod time code
1             package DWH_File::Tie::Array;
2              
3 9     9   56 use warnings;
  9         19  
  9         476  
4 9     9   49 use strict;
  9         18  
  9         367  
5 9     9   126 use vars qw( @ISA $VERSION );
  9         17  
  9         885  
6              
7 9     9   13665 use DWH_File::Subscript;
  9         302  
  9         104  
8 9     9   261 use DWH_File::Value::Factory;
  9         20  
  9         105  
9 9     9   9366 use DWH_File::Tie::Subscripted;
  9         29  
  9         105  
10 9     9   6723 use DWH_File::Tie::Array::Node;
  9         25  
  9         71  
11              
12             @ISA = qw( DWH_File::Tie::Subscripted );
13             $VERSION = 0.01;
14              
15             sub TIEARRAY {
16 28     28   53 my $this = shift;
17 28         226 my $self = $this->perform_tie( @_ );
18             #$self->{ cache } = DWH_File::Cache->new;
19             }
20              
21             sub FETCHSIZE {
22 125     125   150 my ( $self ) = @_;
23 125   100     639 return $self->{ size } || 0;
24             }
25              
26             sub STORESIZE {
27 68     68   78 my ( $self, $size ) = @_;
28 68   100     179 my $oldsize = $self->{ size } || 0;
29 68         105 $self->{ size } = $size;
30 68         88 my $kernel = $self->{ kernel };
31             # make lazy
32 68         192 $kernel->save_custom_grounding( $self );
33 68         139 my $nc = $self->node_class;
34 68         299 for ( my $i = $size; $i < $oldsize; $i++ ) {
35 0         0 my $subscript = DWH_File::Subscript->from_input( $self, $i );
36 0         0 my $data = $kernel->delete( $subscript );
37 0 0       0 if ( $data ) {
38 0         0 $nc->from_stored( $kernel, $data )->release;
39             }
40             }
41             }
42              
43 0     0   0 sub CLEAR { $_[ 0 ]->STORESIZE( 0 ) }
44              
45             sub POP {
46 2     2   6 my ( $self ) = @_;
47 2 50       8 $self->{ size } or return undef;
48 2         9 my $value = $self->DELETE( $self->{ size } - 1 );
49 2         7 $self->{ size }--;
50 2         9 $self->{ kernel }->save_custom_grounding( $self );
51 2         6 return $value;
52             }
53              
54             sub PUSH {
55 3     3   9 my $self = shift; # @_ contains data to be pushed
56 3 50       18 @_ or return;
57 3         10 my $i = $self->{ size };
58 3         8 my $kernel = $self->{ kernel };
59 3         17 my $nc = $self->node_class;
60 3         29 $self->STORESIZE( $i + @_ );
61 3         15 for my $v ( @_ ) {
62 11         41 my $subscript = DWH_File::Subscript->from_input( $self, $i );
63 11         46 my $value = DWH_File::Value::Factory->from_input( $kernel, $v );
64 11         38 my $node = $nc->new;
65 11         47 $node->set_value( $value );
66             # make lazy
67 11         39 $kernel->store( $subscript, $node );
68 11         50 $i++;
69             }
70             }
71              
72             sub SHIFT {
73 3     3   8 my ( $self ) = @_;
74 3         15 return $self->SPLICE( 0, 1 );
75             }
76              
77             sub UNSHIFT {
78 3     3   6 my $self = shift; # @_ contains data to be unshifted
79 3         15 return $self->SPLICE( 0, 0, @_ );
80             }
81              
82             sub SPLICE {
83 11     11   18 my $self = shift;
84 11         13 my $offset = shift;
85 11         21 my $length = shift;
86             # @_ contains data to be inserted
87 11         16 my $insert_length = @_;
88              
89 11 50       39 if ( $offset > $self->{ size } ) { $offset = $self->{ size } }
  0 50       0  
90 0         0 elsif ( $self->{ size } == 0 ) { $offset = 0 }
91 11         31 else { while ( $offset < 0 ) { $offset += $self->{ size } } }
  0         0  
92              
93 11         19 my $last = $offset + $length - 1;
94 11 50       31 if ( $last >= $self->{ size } ) { $last = $self->{ size } - 1 }
  0         0  
95 11         18 $length = $last - $offset + 1;
96 11         34 my @return = map { $self->DELETE( $_ ) } ( $offset..$last );
  13         40  
97              
98 11 100       34 if ( $insert_length ) {
    50          
99 6 50 33     104 if ( $last < $self->{ size } - 1
      33        
100             and $offset < $self->{ size }
101             and $insert_length != $length ) {
102 6         22 $self->shove( $last + 1, $insert_length - $length );
103 6         14 $self->{ size } += $insert_length - $length;
104             # make lazy
105 6         24 $self->{ kernel }->save_custom_grounding( $self );
106             }
107 6         27 for my $v ( @_ ) {
108 14         66 $self->STORE( $offset++, $v );
109             }
110             }
111             elsif ( $length ) {
112 5 50       18 if ( $last < $self->{ size } - 1 ) {
113 5         23 $self->shove( $last + 1, -$length );
114             }
115 5         15 $self->{ size } -= $length;
116             # make lazy
117 5         20 $self->{ kernel }->save_custom_grounding( $self );
118             }
119              
120 11 100       41 wantarray and return @return;
121 10         39 return $return[ 0 ];
122             }
123              
124             sub DELETE {
125 15     15   25 my ( $self, $index ) = @_;
126             # check semantics. In this interpretation deleting never
127             # affects the size of the array - it only differs from
128             # the assignment of undef in terms of the way EXISTS()
129             # responds (and as a side effect, in terms of space
130             # complexity).
131 15         51 my $subscript = DWH_File::Subscript->from_input( $self, $index );
132 15 50       46 if ( my $node = $self->get_node( $subscript ) ) {
133 15         42 my $value = $node->{ value }->actual_value;
134 15         53 $node->release;
135 15         58 $self->{ kernel }->delete( $subscript );
136 15         87 return $value;
137             }
138 0         0 else { return undef }
139             }
140              
141             sub EXTEND {
142 0     0   0 my ( $self, $count ) = @_;
143             # no-op in this class
144             }
145              
146             sub shove {
147 11     11 0 24 my ( $self, $start, $amount ) = @_;
148 11 50       37 if ( $start + $amount < 0 ) { die "anomalous invocation of shove" }
  0         0  
149 11 100       33 if ( $amount < 0 ) {
    50          
150 6         20 for my $i ( $start .. ( $self->{ size } - 1 ) ) {
151 22         58 $self->move( $i, $amount );
152             }
153             }
154             elsif ( $amount > 0 ) {
155 5         21 for my $i ( 0 .. ( $self->{ size } - 1 - $start ) ) {
156 15         45 $self->move( $self->{ size } - 1 - $i, $amount );
157             }
158             }
159             }
160              
161             sub move {
162 37     37 0 52 my ( $self, $from, $amount ) = @_;
163 37         114 my $subscript = DWH_File::Subscript->from_input( $self, $from );
164 37         144 my $node_string = $self->{ kernel }->fetch( $subscript );
165 37         131 $self->{ kernel }->delete( $subscript );
166 37         140 $subscript = DWH_File::Subscript->from_input( $self, $from + $amount );
167 37         134 $self->{ kernel }->store( $subscript, $node_string );
168             }
169              
170             sub tie_reference {
171 28   100 28 0 169 $_[ 2 ] ||= [];
172 28         65 my ( $this, $kernel, $ref, $blessing, $id, $tail ) = @_;
173 28   33     152 my $class = ref $this || $this;
174 28   66     137 $blessing ||= ref $ref;
175 28         198 my $instance = tie @$ref, $class,
176             $kernel, $ref, $id, $tail;
177 28 50       110 if ( $blessing ne 'ARRAY' ) { bless $ref, $blessing }
  0         0  
178 28         81 return $instance;
179             }
180              
181             sub wake_up_call {
182 14     14 0 62 my ( $self, $tail ) = @_;
183 14 50       59 unless ( defined $tail ) { die "Tail anomaly" }
  0         0  
184 14         99 $self->{ size } = int $tail;
185             }
186              
187             sub sign_in_first_time {
188 14     14 0 21 my ( $self ) = @_;
189 14         25 my $i = 0;
190 14         20 for my $v ( @{ $self->{ content } } ) {
  14         47  
191 64         211 $self->STORE( $i, $v );
192 64         237 $i++;
193             }
194             }
195              
196 313     313 0 1244 sub node_class { 'DWH_File::Tie::Array::Node' }
197              
198             sub handle_new_node {
199 80     80 0 99 my ( $self, $node, $subscript ) = @_;
200 80         210 my $index = $subscript->actual;
201 80 100       180 if ( $index >= $self->FETCHSIZE ) { $self->STORESIZE( $index + 1 ) }
  65         138  
202             }
203              
204             sub custom_grounding {
205 31     31 0 76 return $_[ 0 ]->FETCHSIZE;
206             }
207              
208             1;
209              
210             __END__