File Coverage

blib/lib/DWH_File/Tie/Hash.pm
Criterion Covered Total %
statement 95 106 89.6
branch 20 32 62.5
condition 13 19 68.4
subroutine 20 20 100.0
pod 0 9 0.0
total 148 186 79.5


line stmt bran cond sub pod time code
1             package DWH_File::Tie::Hash;
2              
3 9     9   58 use warnings;
  9         20  
  9         1177  
4 9     9   54 use strict;
  9         20  
  9         340  
5 9     9   50 use vars qw( @ISA $VERSION );
  9         19  
  9         588  
6              
7 9     9   6818 use DWH_File::Subscript::Wired;
  9         47  
  9         80  
8 9     9   234 use DWH_File::Tie::Subscripted;
  9         21  
  9         56  
9 9     9   6886 use DWH_File::Tie::Hash::Node;
  9         26  
  9         80  
10              
11             @ISA = qw( DWH_File::Tie::Subscripted );
12             $VERSION = 0.01;
13              
14             sub TIEHASH {
15 30     30   69 my $this = shift;
16 30         814 my $self = $this->perform_tie( @_ );
17             #$self->{ cache } = DWH_File::Cache->new;
18             }
19              
20             sub DELETE {
21 2     2   7 my ( $self, $key ) = @_;
22 2         7 my $subscript = $self->get_subscript( $key );
23 2 50       17 my $node = $self->get_node( $subscript ) or return undef;
24 2         6 my ( $p_node, $s_node, $p_sub, $s_sub );
25 2 50       34 if ( defined $node->{ pred } ) {
26 2         20 $p_sub = $self->subscript_from_value_object( $node->{ pred } );
27 2         9 $p_node = $self->get_node( $p_sub );
28             }
29 2 50       14 if ( defined $node->{ succ } ) {
30 2         6 $s_sub = $self->subscript_from_value_object( $node->{ succ } );
31 2         7 $s_node = $self->get_node( $s_sub );
32             }
33 2         8 my $value = $node->{ value };
34 2         16 $node->release;
35 2         24 $subscript->release;
36 2         47 $self->{ kernel }->delete( $subscript );
37 2 50       7 if ( not $p_node ) {
38 0 0       0 if ( not $s_node ) { $self->{ first } = undef } # first, last, only
  0         0  
39             else {
40             # first
41 0         0 $self->{ first } = $s_sub->{ value };
42 0         0 $s_node->{ pred } = undef;
43 0         0 $self->{ kernel }->store( $s_sub, $s_node );
44             }
45             # make lazy
46 0         0 $self->{ kernel }->save_custom_grounding( $self );
47             }
48             else {
49 2 50       7 if ( not $s_node ) {
50             # last
51 0         0 $p_node->{ succ } = undef;
52 0         0 $self->{ kernel }->store( $p_sub, $p_node );
53             }
54             else {
55             # general (mid)
56 2         14 $p_node->{ succ } = $s_sub->{ value };
57 2         11 $self->{ kernel }->store( $p_sub, $p_node );
58 2         8 $s_node->{ pred } = $p_sub->{ value };
59 2         12 $self->{ kernel }->store( $s_sub, $s_node );
60             }
61             }
62 2         18 return $value->actual_value;
63             }
64              
65             sub CLEAR {
66 2     2   5 my ( $self ) = @_;
67 2         6 my $k = $self->{ first };
68 2   66     41 while ( defined $k and defined $k->actual_value ) {
69 4         14 my $sub = $self->subscript_from_value_object( $k );
70 4         15 my $node = $self->get_node( $sub );
71 4         12 $k = $node->{ succ };
72 4         57 $node->release;
73 4         16 $sub->release;
74 4         19 $self->{ kernel }->delete( $sub );
75             }
76 2         8 $self->{ first } = undef;
77 2         59 $self->{ kernel }->save_custom_grounding( $self );
78             }
79              
80             sub FIRSTKEY {
81 62 100   62   292 defined $_[ 0 ]->{ first } ? $_[ 0 ]->{ first }->actual_value : undef;
82             }
83              
84             sub NEXTKEY {
85 108     108   513 my $subscript = $_[ 0 ]->get_subscript( $_[ 1 ] );
86 108 50       363 my $node = $_[ 0 ]->get_node( $subscript ) or return undef;
87 108 100       533 return defined $node->{ succ } ? $node->{ succ }->actual_value : undef;
88             }
89              
90             sub tie_reference {
91 30   100 30 0 267 $_[ 2 ] ||= {};
92 30         91 my ( $this, $kernel, $ref, $blessing, $id, $tail, $tie_class ) = @_;
93 30   33     192 my $class = ref $this || $this;
94 30   100     461 $tie_class ||= '';
95 30   66     173 $blessing ||= ref $ref;
96 30   66     449 my $instance = tie %$ref, $tie_class || $class, $kernel, $ref, $id, $tail;
97 30 100       132 if ( $blessing ne 'HASH' ) { bless $ref, $blessing }
  4         21  
98 30 100       170 $tie_class and bless $instance, $class;
99 30         154 return $instance;
100             }
101              
102             sub wake_up_call {
103 17     17 0 39 my ( $self, $tail ) = @_;
104 17 50       72 unless ( defined $tail ) { die "Tail anomaly" }
  0         0  
105 17         81 my ( $signal, $first ) = unpack "a a*", $tail;
106 17 50       56 if ( $signal eq '>' ) {
    0          
107             $self->{ first } = DWH_File::Value::Factory->
108 17         287 from_stored( $self->{ kernel }, $first );
109             }
110 0         0 elsif ( $signal eq '<' ) { $self->{ first } = undef }
111 0         0 else { die "Unknown signal byte: '$signal'" }
112             }
113              
114             sub sign_in_first_time {
115 13     13 0 26 my ( $self ) = @_;
116 13         25 while ( my ( $k, $v ) = each %{ $self->{ content } } ) {
  46         259  
117 33         208 $self->STORE( $k, $v );
118             }
119             }
120              
121 563     563 0 2382 sub node_class { 'DWH_File::Tie::Hash::Node' }
122              
123             sub handle_new_node {
124 50     50 0 85 my ( $self, $node, $subscript ) = @_;
125 50         181 $node->set_successor( $self->{ first } );
126 50         182 $self->set_first_key( $subscript->{ value } );
127 50         231 $subscript->retain;
128             }
129              
130             sub get_subscript {
131 558     558 0 2103 return DWH_File::Subscript::Wired->from_input( @_[ 0, 1 ] );
132             }
133              
134             sub subscript_from_value_object {
135 8     8 0 35 return DWH_File::Subscript::Wired->new( @_[ 0, 1 ] );
136             }
137              
138             sub set_first_key {
139 50     50 0 69 my ( $self, $new_first ) = @_;
140 50         129 my $first = $self->FIRSTKEY;
141 50 100       116 if ( defined $first ) {
142 37         76 my $subscript = $self->get_subscript( $first );
143 37         101 my $node = $self->get_node( $subscript );
144 37         127 $node->set_predecessor( $new_first );
145             # make lazy
146 37         166 $self->{ kernel }->store( $subscript, $node );
147             }
148 50         138 $self->{ first } = $new_first;
149             # make lazy
150 50         185 $self->{ kernel }->save_custom_grounding( $self );
151             }
152              
153             sub custom_grounding {
154 32     32 0 63 my $k = $_[ 0 ]->{ first };
155 32 100 66     173 if ( defined $k and defined $k->actual_value ) { return ">$k" }
  25         75  
156 7         45 else { return '<' }
157             }
158              
159             1;
160              
161             __END__