File Coverage

lib/Tie/DB_File/SplitHash.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Tie::DB_File::SplitHash;
2              
3 1     1   7478 use strict;
  1         2  
  1         35  
4              
5 1     1   2164 use DB_File;
  0            
  0            
6             use File::Path;
7             use File::Spec;
8             use Digest::SHA1 qw (sha1_hex);
9             use Fcntl qw (:flock);
10              
11             require Exporter;
12             use vars qw ($VERSION @ISA @EXPORT $DB_HASH);
13              
14             $VERSION = '1.05';
15             @ISA = qw (Tie::Hash Exporter);
16             @EXPORT = qw(
17             $DB_HASH
18             DB_LOCK DB_SHMEM DB_TXN HASHMAGIC
19             HASHVERSION MAX_PAGE_NUMBER MAX_PAGE_OFFSET MAX_REC_NUMBER
20             RET_ERROR RET_SPECIAL RET_SUCCESS R_CURSOR
21             R_DUP R_FIRST R_FIXEDLEN R_IAFTER
22             R_IBEFORE R_LAST R_NEXT R_NOKEY
23             R_NOOVERWRITE R_PREV R_RECNOSYNC R_SETCURSOR
24             R_SNAPSHOT __R_UNUSED);
25             eval {
26             # Make all Fcntl O_XXX constants available for importing
27             require Fcntl;
28             my @O = grep /^O_/, @Fcntl::EXPORT;
29             Fcntl->import(@O); # first we import what we want to export
30             push(@EXPORT, @O);
31             };
32              
33             ###############################################################################
34              
35             sub TIEHASH {
36             my $class = shift;
37             my $package = __PACKAGE__;
38             my $self = bless {},$class;
39             my $parms = [@_];
40             my $vars = {};
41             $self->{$package} = $vars;
42              
43             $vars->{'-init_parms'} = $parms;
44             my $n_parms = $#$parms + 1;
45             if ($n_parms != 5) {
46             require Carp;
47             Carp::croak($package . "::init_hash() - incorrect number of calling parameters\n");
48             }
49             my $multi_n = pop @$parms;
50             $vars->{'-multi_n'} = $multi_n;
51             $vars->{'-dirname'} = $parms->[0];
52             if (not ((-e $vars->{'-dirname'}) or (mkdir ($vars->{'-dirname'},0777)))) {
53             require Carp;
54             Carp::croak($package . '::TIEHASH - datafiles directory ' . $vars->{'-dirname'} . " does not exist and cannot be created.\n$!");
55             }
56             my $main_index_file = File::Spec->catfile($vars->{'-dirname'}, 'index');
57             shift @$parms;
58             $multi_n--;
59             my $errors=0;
60             my $error_message = '';
61             foreach my $f_part (0..$multi_n) {
62             my $tied_hash = {};
63             my $db_object = tie %$tied_hash,'DB_File',"${main_index_file}_${f_part}.db",@$parms;
64             if (not defined $db_object) {
65             $errors = $f_part + 1;
66             $error_message = $!;
67             last;
68             }
69             $vars->{'db'}->[$f_part]->{-object} = $db_object;
70             }
71             if ($errors) {
72             delete $vars->{'db'};
73             require Carp;
74             Carp::croak ("Failed to open database: $error_message\n");
75             }
76              
77             return $self;
78             }
79              
80             #######################################################################
81              
82             sub STORE {
83             my $self = shift;
84             my $package = __PACKAGE__;
85              
86             my ($key,$value) = @_;
87             my $section = $self->_section_hash($key);
88             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
89             return $db_object->STORE(@_);
90             }
91              
92             #######################################################################
93              
94             sub FETCH {
95             my $self = shift;
96             my $package = __PACKAGE__;
97              
98             my ($key) = @_;
99              
100             my $section = $self->_section_hash($key);
101             my $db_object = $self->{$package}->{'db'}->[$section]->{-object};
102             return $db_object->FETCH(@_);
103             }
104              
105             #######################################################################
106              
107             sub DELETE {
108             my $self = shift;
109             my $package = __PACKAGE__;
110            
111             my ($key) = @_;
112              
113             my $section = $self->_section_hash($key);
114             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
115             return $db_object->DELETE(@_);
116             }
117              
118             #######################################################################
119              
120             sub CLEAR {
121             my $self = shift;
122             my $package = __PACKAGE__;
123              
124             my $list_of_dbs = $self->{$package}->{'db'};
125             my $counter = 0;
126             foreach my $database (@$list_of_dbs) {
127             my $db_object = $database->{'-object'};
128             $counter++;
129             $db_object->CLEAR(@_);
130             }
131             }
132              
133             #######################################################################
134              
135             sub EXISTS {
136             my $self = shift;
137             my $package = __PACKAGE__;
138            
139             my ($key) = @_;
140              
141             my $section = $self->_section_hash($key);
142             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
143             return $db_object->EXISTS(@_);
144             }
145              
146             #######################################################################
147              
148             sub DESTROY {
149             my $self = shift;
150             my $package = __PACKAGE__;
151              
152             delete $self->{$package}->{'db'};
153             }
154              
155             #######################################################################
156              
157             sub FIRSTKEY {
158             my $self = shift;
159             my $package = __PACKAGE__;
160             my $vars = $self->{$package};
161             my $db_object = $vars->{'db'}->[0]->{'-object'};
162             $vars->{-iteration_section} = 0;
163             return $db_object->FIRSTKEY(@_);
164             }
165              
166             #######################################################################
167              
168             sub NEXTKEY {
169             my $self = shift;
170             my $package = __PACKAGE__;
171             my $vars = $self->{$package};
172            
173             my ($key) = @_;
174              
175             my $section = $vars->{'-iteration_section'};
176             my $multi_n = $vars->{'-multi_n'};
177             my $db_object = $vars->{'db'}->[$section]->{'-object'};
178             my $next_key;
179             while (not defined $next_key) {
180             $next_key = $db_object->NEXTKEY($key);
181             if (not defined $next_key) {
182             $section++;
183             $vars->{-iteration_section} = $section;
184             my $next_section = $vars->{'db'}->[$section];
185             last unless (defined $next_section);
186             $db_object = $next_section->{'-object'};
187             $next_key = $db_object->FIRSTKEY;
188             }
189             }
190             return $next_key;
191             }
192              
193             #######################################################################
194              
195             sub _section_hash {
196             my $self = shift;
197             my $package = __PACKAGE__;
198            
199             my ($key) = @_;
200              
201             $key = '' unless defined $key;
202             my $sections = $self->{$package}->{'-multi_n'};
203             my $digest = sha1_hex($key);
204             my $section_n = hex(substr($digest,0,2)) % $sections;
205             return $section_n;
206             }
207              
208             #######################################################################
209              
210             sub put {
211             my $self = shift;
212             my $package = __PACKAGE__;
213              
214             my $parms = [];
215             @$parms = @_;
216             my $key = shift @$parms;
217             my $section = $self->_section_hash($key);
218             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
219             return $db_object->put(@_);
220             }
221              
222             #######################################################################
223              
224             sub get {
225             my $self = shift;
226             my $package = __PACKAGE__;
227              
228             my $parms = [@_];
229             my $key = shift @$parms;
230             my $section = $self->_section_hash($key);
231             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
232             return $db_object->get(@_);
233             }
234              
235             #######################################################################
236              
237             sub seq {
238             my $self = shift;
239             my $package = __PACKAGE__;
240              
241             my $parms = [@_];
242             my $key = shift @$parms;
243             my $section = $self->_section_hash($key);
244             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
245             return $db_object->seq(@_);
246             }
247              
248             #######################################################################
249              
250             sub del {
251             my $self = shift;
252             my $package = __PACKAGE__;
253              
254             my $parms = [@_];
255             my $key = shift @$parms;
256             my $section = $self->_section_hash($key);
257             my $db_object = $self->{$package}->{'db'}->[$section]->{'-object'};
258             return $db_object->del(@_);
259             }
260              
261             #######################################################################
262              
263             sub sync {
264             my $self = shift;
265             my $package = __PACKAGE__;
266              
267             foreach my $db (@{$self->{$package}->{'db'}}) {
268             $db->{'-object'}->sync(@_);
269             }
270             }
271              
272             #######################################################################
273              
274             sub fd {
275             my $self = shift;
276             my $package = __PACKAGE__;
277             return $self->{$package}->{'db'}->[0]->{'-object'}->fd(@_);
278             }
279              
280             #######################################################################
281              
282             sub exists {
283             return shift->EXISTS(@_);
284             }
285              
286             #######################################################################
287              
288             sub clear {
289             return shift->CLEAR(@_);
290             }
291              
292             #######################################################################
293              
294             1;