File Coverage

blib/lib/Tie/DxHash.pm
Criterion Covered Total %
statement 82 82 100.0
branch 12 12 100.0
condition 2 2 100.0
subroutine 15 15 100.0
pod n/a
total 111 111 100.0


line stmt bran cond sub pod time code
1             # $Id $
2             # $Revision 1.03 $
3              
4             package Tie::DxHash;
5              
6 11     11   185273 use warnings;
  11         26  
  11         402  
7 11     11   69 use strict;
  11         61  
  11         564  
8 11     11   61 use base qw(Tie::Hash);
  11         20  
  11         15225  
9              
10 11     11   16217 use Tie::Hash;
  11         43  
  11         21281  
11              
12             our $VERSION = '1.03';
13              
14             sub CLEAR {
15 24     24   96 my ($self) = @_;
16              
17 24         34 my $test;
18              
19 24         123 $self->{data} = [];
20 24         63 $self->{iterators} = {};
21 24         60 $self->{occurrences} = {};
22 24         102 $self->_ckey(0);
23              
24 24         103 return $self;
25             }
26              
27             sub DELETE {
28 6     6   2213 my ( $self, $key ) = @_;
29              
30 6         10 my $offset = 0;
31 6         9 my @deleted_elements = ();
32              
33 22         65 ELEMENT:
34 6         16 while ( $offset < @{ $self->{data} } ) {
35 16 100       47 if ( $key eq $self->{data}[$offset]{key} ) {
36 5         17 push @deleted_elements, $self->{data}[$offset]{value};
37 5         7 splice @{ $self->{data} }, $offset, 1;
  5         18  
38             }
39             else {
40 11         17 $offset++;
41             }
42             }
43              
44 6         12 delete $self->{iterators}{$key};
45 6         12 delete $self->{occurrences}{$key};
46              
47 6         30 return \@deleted_elements;
48             }
49              
50             sub EXISTS {
51 3     3   492 my ( $self, $key ) = @_;
52              
53 3         16 return exists $self->{occurrences}{$key};
54             }
55              
56             sub FETCH {
57 7     7   1649 my ( $self, $key ) = @_;
58              
59 7         12 my ($dup) = 1;
60              
61 7         23 HASH_KEY:
62 7         10 foreach my $offset ( 0 .. @{ $self->{data} } - 1 ) {
63 16 100       76 next HASH_KEY if $key ne $self->{data}[$offset]{key};
64 8 100       24 next HASH_KEY if $dup++ != $self->{iterators}{$key};
65 6         9 $self->{iterators}{$key}++;
66              
67 6 100       19 if ( $self->{iterators}{$key} > $self->{occurrences}{$key} ) {
68 3         7 $self->{iterators}{$key} = 1;
69             }
70              
71 6         29 return $self->{data}[$offset]{value};
72             }
73              
74 1         5 return;
75             }
76              
77             sub FIRSTKEY {
78 9     9   1616 my ($self) = @_;
79              
80 9         41 $self->_ckey(0);
81 9         48 return $self->NEXTKEY;
82             }
83              
84             sub NEXTKEY {
85 29     29   72 my ($self) = @_;
86              
87 29         96 my ($ckey) = $self->_ckey;
88              
89 29 100       39 if ( $ckey == @{ $self->{data} } ) {
  29         95  
90 8         45 return;
91             }
92             else {
93 21         54 $self->_ckey( $ckey + 1 );
94 21         92 return $self->{data}[$ckey]{key};
95             }
96             }
97              
98             sub SCALAR {
99 2     2   13 my ($self) = @_;
100              
101 2         3 my $hash_size = 0;
102              
103 2         7 HASH_KEY:
104 2         4 foreach my $key ( keys %{ $self->{occurrences} } ) {
105 2         6 $hash_size += $self->{occurrences}{$key};
106             }
107              
108 2         14 return $hash_size;
109             }
110              
111             sub STORE {
112 46     46   112 my ( $self, $key, $value ) = @_;
113              
114 46         69 push @{ $self->{data} }, { key => $key, value => $value };
  46         247  
115 46   100     256 $self->{iterators}{$key} ||= 1;
116 46         92 $self->{occurrences}{$key}++;
117              
118 46         194 return $self;
119             }
120              
121             sub TIEHASH {
122 13     13   378 my ( $class, @args ) = @_;
123              
124 13         26 my ($self);
125              
126 13         32 $self = {};
127 13         41 bless $self, $class;
128              
129 13         83 $self->_init(@args);
130 13         51 return $self;
131             }
132              
133             sub _ckey {
134 83     83   117 my ( $self, $ckey ) = @_;
135              
136 83 100       183 if ( defined $ckey ) {
137 54         91 $self->{ckey} = $ckey;
138             }
139 83         143 return $self->{ckey};
140             }
141              
142             sub _init {
143 13     13   30 my ( $self, @args ) = @_;
144              
145 13         94 $self->CLEAR;
146              
147 13         79 while ( my ( $key, $value ) = splice @args, 0, 2 ) {
148 4         17 $self->STORE( $key, $value );
149             }
150              
151 13         29 return $self;
152             }
153              
154             1; # Magic true value required at end of module
155             __END__