Added fix for RT#17947 and fixed a bug from last checkin
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep.pm
CommitLineData
ffed8b01 1package DBM::Deep;
2
3##
4# DBM::Deep
5#
6# Description:
d0b74c17 7# Multi-level database module for storing hash trees, arrays and simple
8# key/value pairs into FTP-able, cross-platform binary database files.
ffed8b01 9#
d0b74c17 10# Type `perldoc DBM::Deep` for complete documentation.
ffed8b01 11#
12# Usage Examples:
d0b74c17 13# my %db;
14# tie %db, 'DBM::Deep', 'my_database.db'; # standard tie() method
ffed8b01 15#
d0b74c17 16# my $db = new DBM::Deep( 'my_database.db' ); # preferred OO method
17#
18# $db->{my_scalar} = 'hello world';
19# $db->{my_hash} = { larry => 'genius', hashes => 'fast' };
20# $db->{my_array} = [ 1, 2, 3, time() ];
21# $db->{my_complex} = [ 'hello', { perl => 'rules' }, 42, 99 ];
22# push @{$db->{my_array}}, 'another value';
23# my @key_list = keys %{$db->{my_hash}};
24# print "This module " . $db->{my_complex}->[1]->{perl} . "!\n";
ffed8b01 25#
26# Copyright:
d0b74c17 27# (c) 2002-2006 Joseph Huckaby. All Rights Reserved.
28# This program is free software; you can redistribute it and/or
29# modify it under the same terms as Perl itself.
ffed8b01 30##
31
32use strict;
8b957036 33
596e9574 34use Fcntl qw( :DEFAULT :flock :seek );
ffed8b01 35use Digest::MD5 ();
36use Scalar::Util ();
ffed8b01 37
95967a5e 38use DBM::Deep::Engine;
39
596e9574 40use vars qw( $VERSION );
3a7a0dce 41$VERSION = q(0.99_01);
ffed8b01 42
ffed8b01 43##
44# Setup constants for users to pass to new()
45##
8db25060 46sub TYPE_HASH () { DBM::Deep::Engine::SIG_HASH }
47sub TYPE_ARRAY () { DBM::Deep::Engine::SIG_ARRAY }
48sub TYPE_SCALAR () { DBM::Deep::Engine::SIG_SCALAR }
ffed8b01 49
0ca7ea98 50sub _get_args {
51 my $proto = shift;
52
53 my $args;
54 if (scalar(@_) > 1) {
55 if ( @_ % 2 ) {
56 $proto->_throw_error( "Odd number of parameters to " . (caller(1))[2] );
57 }
58 $args = {@_};
59 }
d0b74c17 60 elsif ( ref $_[0] ) {
4d35d856 61 unless ( eval { local $SIG{'__DIE__'}; %{$_[0]} || 1 } ) {
0ca7ea98 62 $proto->_throw_error( "Not a hashref in args to " . (caller(1))[2] );
63 }
64 $args = $_[0];
65 }
d0b74c17 66 else {
0ca7ea98 67 $args = { file => shift };
68 }
69
70 return $args;
71}
72
ffed8b01 73sub new {
d0b74c17 74 ##
75 # Class constructor method for Perl OO interface.
76 # Calls tie() and returns blessed reference to tied hash or array,
77 # providing a hybrid OO/tie interface.
78 ##
79 my $class = shift;
80 my $args = $class->_get_args( @_ );
81
82 ##
83 # Check if we want a tied hash or array.
84 ##
85 my $self;
86 if (defined($args->{type}) && $args->{type} eq TYPE_ARRAY) {
6fe26b29 87 $class = 'DBM::Deep::Array';
88 require DBM::Deep::Array;
d0b74c17 89 tie @$self, $class, %$args;
90 }
91 else {
6fe26b29 92 $class = 'DBM::Deep::Hash';
93 require DBM::Deep::Hash;
d0b74c17 94 tie %$self, $class, %$args;
95 }
ffed8b01 96
d0b74c17 97 return bless $self, $class;
ffed8b01 98}
99
0795f290 100sub _init {
101 ##
102 # Setup $self and bless into this class.
103 ##
104 my $class = shift;
994ccd8e 105 my ($args) = @_;
0795f290 106
107 # These are the defaults to be optionally overridden below
108 my $self = bless {
95967a5e 109 type => TYPE_HASH,
612969fb 110 engine => DBM::Deep::Engine->new,
0795f290 111 }, $class;
8db25060 112 $self->{base_offset} = length( $self->{engine}->SIG_FILE );
113
0795f290 114 foreach my $param ( keys %$self ) {
115 next unless exists $args->{$param};
116 $self->{$param} = delete $args->{$param}
ffed8b01 117 }
d0b74c17 118
37c5bcf0 119 # locking implicitly enables autoflush
120 if ($args->{locking}) { $args->{autoflush} = 1; }
d0b74c17 121
0795f290 122 $self->{root} = exists $args->{root}
123 ? $args->{root}
124 : DBM::Deep::_::Root->new( $args );
125
70b55428 126 $self->{engine}->setup_fh( $self );
0795f290 127
128 return $self;
ffed8b01 129}
130
ffed8b01 131sub TIEHASH {
6fe26b29 132 shift;
133 require DBM::Deep::Hash;
134 return DBM::Deep::Hash->TIEHASH( @_ );
ffed8b01 135}
136
137sub TIEARRAY {
6fe26b29 138 shift;
139 require DBM::Deep::Array;
140 return DBM::Deep::Array->TIEARRAY( @_ );
ffed8b01 141}
142
cc4bef86 143#XXX Unneeded now ...
144#sub DESTROY {
145#}
ffed8b01 146
ffed8b01 147sub lock {
d0b74c17 148 ##
149 # If db locking is set, flock() the db file. If called multiple
150 # times before unlock(), then the same number of unlocks() must
151 # be called before the lock is released.
152 ##
994ccd8e 153 my $self = shift->_get_self;
154 my ($type) = @_;
ffed8b01 155 $type = LOCK_EX unless defined $type;
d0b74c17 156
157 if (!defined($self->_fh)) { return; }
158
159 if ($self->_root->{locking}) {
160 if (!$self->_root->{locked}) {
161 flock($self->_fh, $type);
162
163 # refresh end counter in case file has changed size
164 my @stats = stat($self->_root->{file});
165 $self->_root->{end} = $stats[7];
166
167 # double-check file inode, in case another process
168 # has optimize()d our file while we were waiting.
169 if ($stats[1] != $self->_root->{inode}) {
3d1b8be9 170 $self->{engine}->close_fh( $self );
70b55428 171 $self->{engine}->setup_fh( $self );
d0b74c17 172 flock($self->_fh, $type); # re-lock
70b55428 173
174 # This may not be necessary after re-opening
d0b74c17 175 $self->_root->{end} = (stat($self->_fh))[7]; # re-end
176 }
177 }
178 $self->_root->{locked}++;
b4522594 179
180 return 1;
d0b74c17 181 }
b4522594 182
183 return;
ffed8b01 184}
185
186sub unlock {
d0b74c17 187 ##
188 # If db locking is set, unlock the db file. See note in lock()
189 # regarding calling lock() multiple times.
190 ##
994ccd8e 191 my $self = shift->_get_self;
7f441181 192
d0b74c17 193 if (!defined($self->_fh)) { return; }
194
195 if ($self->_root->{locking} && $self->_root->{locked} > 0) {
196 $self->_root->{locked}--;
197 if (!$self->_root->{locked}) { flock($self->_fh, LOCK_UN); }
b4522594 198
199 return 1;
d0b74c17 200 }
b4522594 201
202 return;
ffed8b01 203}
204
906c8e01 205sub _copy_value {
206 my $self = shift->_get_self;
207 my ($spot, $value) = @_;
208
209 if ( !ref $value ) {
210 ${$spot} = $value;
211 }
212 elsif ( eval { local $SIG{__DIE__}; $value->isa( 'DBM::Deep' ) } ) {
213 my $type = $value->_type;
214 ${$spot} = $type eq TYPE_HASH ? {} : [];
215 $value->_copy_node( ${$spot} );
216 }
217 else {
218 my $r = Scalar::Util::reftype( $value );
219 my $c = Scalar::Util::blessed( $value );
220 if ( $r eq 'ARRAY' ) {
221 ${$spot} = [ @{$value} ];
222 }
223 else {
224 ${$spot} = { %{$value} };
225 }
95bbd935 226 ${$spot} = bless ${$spot}, $c
906c8e01 227 if defined $c;
228 }
229
230 return 1;
231}
232
261d1296 233sub _copy_node {
d0b74c17 234 ##
235 # Copy single level of keys or elements to new DB handle.
236 # Recurse for nested structures
237 ##
906c8e01 238 my $self = shift->_get_self;
d0b74c17 239 my ($db_temp) = @_;
b8b48a59 240
d0b74c17 241 if ($self->_type eq TYPE_HASH) {
242 my $key = $self->first_key();
243 while ($key) {
244 my $value = $self->get($key);
906c8e01 245 $self->_copy_value( \$db_temp->{$key}, $value );
d0b74c17 246 $key = $self->next_key($key);
247 }
248 }
249 else {
250 my $length = $self->length();
251 for (my $index = 0; $index < $length; $index++) {
252 my $value = $self->get($index);
906c8e01 253 $self->_copy_value( \$db_temp->[$index], $value );
d0b74c17 254 }
255 }
906c8e01 256
257 return 1;
ffed8b01 258}
259
260sub export {
d0b74c17 261 ##
262 # Recursively export into standard Perl hashes and arrays.
263 ##
994ccd8e 264 my $self = shift->_get_self;
d0b74c17 265
266 my $temp;
267 if ($self->_type eq TYPE_HASH) { $temp = {}; }
268 elsif ($self->_type eq TYPE_ARRAY) { $temp = []; }
269
270 $self->lock();
271 $self->_copy_node( $temp );
272 $self->unlock();
273
274 return $temp;
ffed8b01 275}
276
277sub import {
d0b74c17 278 ##
279 # Recursively import Perl hash/array structure
280 ##
d0b74c17 281 if (!ref($_[0])) { return; } # Perl calls import() on use -- ignore
282
994ccd8e 283 my $self = shift->_get_self;
284 my ($struct) = @_;
d0b74c17 285
c9cec40e 286 # struct is not a reference, so just import based on our type
d0b74c17 287 if (!ref($struct)) {
d0b74c17 288 if ($self->_type eq TYPE_HASH) { $struct = {@_}; }
289 elsif ($self->_type eq TYPE_ARRAY) { $struct = [@_]; }
290 }
291
ffed8b01 292 my $r = Scalar::Util::reftype($struct) || '';
d0b74c17 293 if ($r eq "HASH" && $self->_type eq TYPE_HASH) {
294 foreach my $key (keys %$struct) { $self->put($key, $struct->{$key}); }
295 }
296 elsif ($r eq "ARRAY" && $self->_type eq TYPE_ARRAY) {
297 $self->push( @$struct );
298 }
299 else {
1400a48e 300 $self->_throw_error("Cannot import: type mismatch");
d0b74c17 301 }
302
303 return 1;
ffed8b01 304}
305
306sub optimize {
d0b74c17 307 ##
308 # Rebuild entire database into new file, then move
309 # it back on top of original.
310 ##
994ccd8e 311 my $self = shift->_get_self;
cc4bef86 312
313#XXX Need to create a new test for this
d0b74c17 314# if ($self->_root->{links} > 1) {
1400a48e 315# $self->_throw_error("Cannot optimize: reference count is greater than 1");
d0b74c17 316# }
317
318 my $db_temp = DBM::Deep->new(
319 file => $self->_root->{file} . '.tmp',
320 type => $self->_type
321 );
322 if (!$db_temp) {
1400a48e 323 $self->_throw_error("Cannot optimize: failed to open temp file: $!");
d0b74c17 324 }
325
326 $self->lock();
327 $self->_copy_node( $db_temp );
328 undef $db_temp;
329
330 ##
331 # Attempt to copy user, group and permissions over to new file
332 ##
333 my @stats = stat($self->_fh);
334 my $perms = $stats[2] & 07777;
335 my $uid = $stats[4];
336 my $gid = $stats[5];
337 chown( $uid, $gid, $self->_root->{file} . '.tmp' );
338 chmod( $perms, $self->_root->{file} . '.tmp' );
339
ffed8b01 340 # q.v. perlport for more information on this variable
90f93b43 341 if ( $^O eq 'MSWin32' || $^O eq 'cygwin' ) {
d0b74c17 342 ##
343 # Potential race condition when optmizing on Win32 with locking.
344 # The Windows filesystem requires that the filehandle be closed
345 # before it is overwritten with rename(). This could be redone
346 # with a soft copy.
347 ##
348 $self->unlock();
349 $self->{engine}->close_fh( $self );
350 }
351
352 if (!rename $self->_root->{file} . '.tmp', $self->_root->{file}) {
353 unlink $self->_root->{file} . '.tmp';
354 $self->unlock();
1400a48e 355 $self->_throw_error("Optimize failed: Cannot copy temp file over original: $!");
d0b74c17 356 }
357
358 $self->unlock();
359 $self->{engine}->close_fh( $self );
70b55428 360 $self->{engine}->setup_fh( $self );
361
d0b74c17 362 return 1;
ffed8b01 363}
364
365sub clone {
d0b74c17 366 ##
367 # Make copy of object and return
368 ##
994ccd8e 369 my $self = shift->_get_self;
d0b74c17 370
371 return DBM::Deep->new(
372 type => $self->_type,
373 base_offset => $self->_base_offset,
374 root => $self->_root
375 );
ffed8b01 376}
377
378{
379 my %is_legal_filter = map {
380 $_ => ~~1,
381 } qw(
382 store_key store_value
383 fetch_key fetch_value
384 );
385
386 sub set_filter {
387 ##
388 # Setup filter function for storing or fetching the key or value
389 ##
994ccd8e 390 my $self = shift->_get_self;
391 my $type = lc shift;
392 my $func = shift;
d0b74c17 393
ffed8b01 394 if ( $is_legal_filter{$type} ) {
4d35d856 395 $self->_root->{"filter_$type"} = $func;
ffed8b01 396 return 1;
397 }
398
399 return;
400 }
401}
402
403##
404# Accessor methods
405##
406
4d35d856 407sub _root {
d0b74c17 408 ##
409 # Get access to the root structure
410 ##
2ac02042 411 my $self = $_[0]->_get_self;
d0b74c17 412 return $self->{root};
ffed8b01 413}
414
4d35d856 415sub _type {
d0b74c17 416 ##
417 # Get type of current node (TYPE_HASH or TYPE_ARRAY)
418 ##
2ac02042 419 my $self = $_[0]->_get_self;
d0b74c17 420 return $self->{type};
ffed8b01 421}
422
4d35d856 423sub _base_offset {
d0b74c17 424 ##
425 # Get base_offset of current node (TYPE_HASH or TYPE_ARRAY)
426 ##
2ac02042 427 my $self = $_[0]->_get_self;
d0b74c17 428 return $self->{base_offset};
ffed8b01 429}
430
994ccd8e 431sub _fh {
432 ##
433 # Get access to the raw fh
434 ##
435 my $self = $_[0]->_get_self;
436 return $self->_root->{fh};
437}
438
ffed8b01 439##
440# Utility methods
441##
442
261d1296 443sub _throw_error {
95967a5e 444 die "DBM::Deep: $_[1]\n";
ffed8b01 445}
446
acd4faf2 447sub _is_writable {
448 my $fh = shift;
449 (O_WRONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush = 0);
450}
451
9be51a89 452#sub _is_readable {
453# my $fh = shift;
454# (O_RDONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush = 0);
455#}
acd4faf2 456
ffed8b01 457sub STORE {
d0b74c17 458 ##
459 # Store single hash key/value or array element in database.
460 ##
461 my $self = shift->_get_self;
462 my ($key, $value) = @_;
81d3d316 463
acd4faf2 464 unless ( _is_writable( $self->_fh ) ) {
465 $self->_throw_error( 'Cannot write to a readonly filehandle' );
466 }
d0b74c17 467
468 ##
469 # Request exclusive lock for writing
470 ##
471 $self->lock( LOCK_EX );
472
473 my $md5 = $self->{engine}{digest}->($key);
474
475 my $tag = $self->{engine}->find_bucket_list( $self, $md5, { create => 1 } );
476
477 # User may be storing a hash, in which case we do not want it run
478 # through the filtering system
479 if ( !ref($value) && $self->_root->{filter_store_value} ) {
480 $value = $self->_root->{filter_store_value}->( $value );
481 }
482
483 ##
484 # Add key/value to bucket list
485 ##
486 my $result = $self->{engine}->add_bucket( $self, $tag, $md5, $key, $value );
487
488 $self->unlock();
489
490 return $result;
ffed8b01 491}
492
493sub FETCH {
d0b74c17 494 ##
495 # Fetch single value or element given plain key or array index
496 ##
cb79ec85 497 my $self = shift->_get_self;
498 my $key = shift;
ffed8b01 499
d0b74c17 500 my $md5 = $self->{engine}{digest}->($key);
501
502 ##
503 # Request shared lock for reading
504 ##
505 $self->lock( LOCK_SH );
506
507 my $tag = $self->{engine}->find_bucket_list( $self, $md5 );
508 if (!$tag) {
509 $self->unlock();
510 return;
511 }
512
513 ##
514 # Get value from bucket list
515 ##
516 my $result = $self->{engine}->get_bucket_value( $self, $tag, $md5 );
517
518 $self->unlock();
519
a86430bd 520 # Filters only apply to scalar values, so the ref check is making
521 # sure the fetched bucket is a scalar, not a child hash or array.
d0b74c17 522 return ($result && !ref($result) && $self->_root->{filter_fetch_value})
4d35d856 523 ? $self->_root->{filter_fetch_value}->($result)
cb79ec85 524 : $result;
ffed8b01 525}
526
527sub DELETE {
d0b74c17 528 ##
529 # Delete single key/value pair or element given plain key or array index
530 ##
2ac02042 531 my $self = $_[0]->_get_self;
d0b74c17 532 my $key = $_[1];
533
a86430bd 534 unless ( _is_writable( $self->_fh ) ) {
535 $self->_throw_error( 'Cannot write to a readonly filehandle' );
536 }
d0b74c17 537
538 ##
539 # Request exclusive lock for writing
540 ##
541 $self->lock( LOCK_EX );
542
a86430bd 543 my $md5 = $self->{engine}{digest}->($key);
544
d0b74c17 545 my $tag = $self->{engine}->find_bucket_list( $self, $md5 );
546 if (!$tag) {
547 $self->unlock();
548 return;
549 }
550
551 ##
552 # Delete bucket
553 ##
9020ee8c 554 my $value = $self->{engine}->get_bucket_value($self, $tag, $md5 );
a86430bd 555
556 if (defined $value && !ref($value) && $self->_root->{filter_fetch_value}) {
4d35d856 557 $value = $self->_root->{filter_fetch_value}->($value);
3b6a5056 558 }
559
d0b74c17 560 my $result = $self->{engine}->delete_bucket( $self, $tag, $md5 );
561
562 ##
563 # If this object is an array and the key deleted was on the end of the stack,
564 # decrement the length variable.
565 ##
566
567 $self->unlock();
568
569 return $value;
ffed8b01 570}
571
572sub EXISTS {
d0b74c17 573 ##
574 # Check if a single key or element exists given plain key or array index
575 ##
2ac02042 576 my $self = $_[0]->_get_self;
d0b74c17 577 my $key = $_[1];
578
579 my $md5 = $self->{engine}{digest}->($key);
580
581 ##
582 # Request shared lock for reading
583 ##
584 $self->lock( LOCK_SH );
585
586 my $tag = $self->{engine}->find_bucket_list( $self, $md5 );
587 if (!$tag) {
588 $self->unlock();
589
590 ##
591 # For some reason, the built-in exists() function returns '' for false
592 ##
593 return '';
594 }
595
596 ##
597 # Check if bucket exists and return 1 or ''
598 ##
599 my $result = $self->{engine}->bucket_exists( $self, $tag, $md5 ) || '';
600
601 $self->unlock();
602
603 return $result;
ffed8b01 604}
605
606sub CLEAR {
d0b74c17 607 ##
608 # Clear all keys from hash, or all elements from array.
609 ##
2ac02042 610 my $self = $_[0]->_get_self;
ffed8b01 611
a86430bd 612 unless ( _is_writable( $self->_fh ) ) {
613 $self->_throw_error( 'Cannot write to a readonly filehandle' );
614 }
615
d0b74c17 616 ##
617 # Request exclusive lock for writing
618 ##
619 $self->lock( LOCK_EX );
620
4d35d856 621 my $fh = $self->_fh;
629df3a3 622
d0b74c17 623 seek($fh, $self->_base_offset + $self->_root->{file_offset}, SEEK_SET);
624 if (eof $fh) {
625 $self->unlock();
626 return;
627 }
628
629 $self->{engine}->create_tag($self, $self->_base_offset, $self->_type, chr(0) x $self->{engine}{index_size});
630
631 $self->unlock();
632
633 return 1;
ffed8b01 634}
635
ffed8b01 636##
637# Public method aliases
638##
7f441181 639sub put { (shift)->STORE( @_ ) }
640sub store { (shift)->STORE( @_ ) }
641sub get { (shift)->FETCH( @_ ) }
642sub fetch { (shift)->FETCH( @_ ) }
baa27ab6 643sub delete { (shift)->DELETE( @_ ) }
644sub exists { (shift)->EXISTS( @_ ) }
645sub clear { (shift)->CLEAR( @_ ) }
ffed8b01 646
cc4bef86 647package DBM::Deep::_::Root;
648
649sub new {
650 my $class = shift;
651 my ($args) = @_;
652
653 my $self = bless {
a86430bd 654 autobless => undef,
655 autoflush => undef,
1400a48e 656 #XXX It should be this in order to work with the initial create_tag(),
657 #XXX but it's not ... it works out because of the stat() in setup_fh(),
658 #XXX but that's not good.
659 end => 0, #length(DBM::Deep->SIG_FILE),
f5be9b03 660 fh => undef,
a86430bd 661 file => undef,
f5be9b03 662 file_offset => 0,
f5be9b03 663 locking => undef,
664 locked => 0,
665 filter_store_key => undef,
cc4bef86 666 filter_store_value => undef,
f5be9b03 667 filter_fetch_key => undef,
cc4bef86 668 filter_fetch_value => undef,
cc4bef86 669 %$args,
670 }, $class;
671
714618f0 672 if ( $self->{fh} && !$self->{file_offset} ) {
673 $self->{file_offset} = tell( $self->{fh} );
674 }
675
cc4bef86 676 return $self;
677}
678
679sub DESTROY {
680 my $self = shift;
681 return unless $self;
682
683 close $self->{fh} if $self->{fh};
684
685 return;
686}
687
ffed8b01 6881;
ffed8b01 689__END__
690
691=head1 NAME
692
693DBM::Deep - A pure perl multi-level hash/array DBM
694
695=head1 SYNOPSIS
696
697 use DBM::Deep;
698 my $db = DBM::Deep->new( "foo.db" );
d0b74c17 699
ffed8b01 700 $db->{key} = 'value'; # tie() style
701 print $db->{key};
d0b74c17 702
cbaa107d 703 $db->put('key' => 'value'); # OO style
ffed8b01 704 print $db->get('key');
d0b74c17 705
ffed8b01 706 # true multi-level support
707 $db->{my_complex} = [
d0b74c17 708 'hello', { perl => 'rules' },
709 42, 99,
90f93b43 710 ];
ffed8b01 711
712=head1 DESCRIPTION
713
d0b74c17 714A unique flat-file database module, written in pure perl. True
715multi-level hash/array support (unlike MLDBM, which is faked), hybrid
716OO / tie() interface, cross-platform FTPable files, and quite fast. Can
717handle millions of keys and unlimited hash levels without significant
718slow-down. Written from the ground-up in pure perl -- this is NOT a
719wrapper around a C-based DBM. Out-of-the-box compatibility with Unix,
ffed8b01 720Mac OS X and Windows.
721
8db25060 722=head1 VERSION DIFFERENCES
723
724B<NOTE>: 0.99_01 and above have significant file format differences from 0.98 and
725before. While attempts have been made to be backwards compatible, no guarantees.
726
ffed8b01 727=head1 INSTALLATION
728
90f93b43 729Hopefully you are using Perl's excellent CPAN module, which will download
d0b74c17 730and install the module for you. If not, get the tarball, and run these
ffed8b01 731commands:
732
d0b74c17 733 tar zxf DBM-Deep-*
734 cd DBM-Deep-*
735 perl Makefile.PL
736 make
737 make test
738 make install
ffed8b01 739
740=head1 SETUP
741
d0b74c17 742Construction can be done OO-style (which is the recommended way), or using
ffed8b01 743Perl's tie() function. Both are examined here.
744
745=head2 OO CONSTRUCTION
746
747The recommended way to construct a DBM::Deep object is to use the new()
748method, which gets you a blessed, tied hash or array reference.
749
d0b74c17 750 my $db = DBM::Deep->new( "foo.db" );
ffed8b01 751
752This opens a new database handle, mapped to the file "foo.db". If this
d0b74c17 753file does not exist, it will automatically be created. DB files are
ffed8b01 754opened in "r+" (read/write) mode, and the type of object returned is a
755hash, unless otherwise specified (see L<OPTIONS> below).
756
ffed8b01 757You can pass a number of options to the constructor to specify things like
758locking, autoflush, etc. This is done by passing an inline hash:
759
d0b74c17 760 my $db = DBM::Deep->new(
761 file => "foo.db",
762 locking => 1,
763 autoflush => 1
764 );
ffed8b01 765
766Notice that the filename is now specified I<inside> the hash with
d0b74c17 767the "file" parameter, as opposed to being the sole argument to the
ffed8b01 768constructor. This is required if any options are specified.
769See L<OPTIONS> below for the complete list.
770
771
772
773You can also start with an array instead of a hash. For this, you must
774specify the C<type> parameter:
775
d0b74c17 776 my $db = DBM::Deep->new(
777 file => "foo.db",
778 type => DBM::Deep->TYPE_ARRAY
779 );
ffed8b01 780
781B<Note:> Specifing the C<type> parameter only takes effect when beginning
782a new DB file. If you create a DBM::Deep object with an existing file, the
90f93b43 783C<type> will be loaded from the file header, and an error will be thrown if
784the wrong type is passed in.
ffed8b01 785
786=head2 TIE CONSTRUCTION
787
90f93b43 788Alternately, you can create a DBM::Deep handle by using Perl's built-in
789tie() function. The object returned from tie() can be used to call methods,
790such as lock() and unlock(), but cannot be used to assign to the DBM::Deep
791file (as expected with most tie'd objects).
ffed8b01 792
d0b74c17 793 my %hash;
794 my $db = tie %hash, "DBM::Deep", "foo.db";
795
796 my @array;
797 my $db = tie @array, "DBM::Deep", "bar.db";
ffed8b01 798
799As with the OO constructor, you can replace the DB filename parameter with
800a hash containing one or more options (see L<OPTIONS> just below for the
801complete list).
802
d0b74c17 803 tie %hash, "DBM::Deep", {
804 file => "foo.db",
805 locking => 1,
806 autoflush => 1
807 };
ffed8b01 808
809=head2 OPTIONS
810
811There are a number of options that can be passed in when constructing your
812DBM::Deep objects. These apply to both the OO- and tie- based approaches.
813
814=over
815
816=item * file
817
818Filename of the DB file to link the handle to. You can pass a full absolute
d0b74c17 819filesystem path, partial path, or a plain filename if the file is in the
714618f0 820current working directory. This is a required parameter (though q.v. fh).
821
822=item * fh
823
824If you want, you can pass in the fh instead of the file. This is most useful for doing
825something like:
826
827 my $db = DBM::Deep->new( { fh => \*DATA } );
828
829You are responsible for making sure that the fh has been opened appropriately for your
830needs. If you open it read-only and attempt to write, an exception will be thrown. If you
831open it write-only or append-only, an exception will be thrown immediately as DBM::Deep
832needs to read from the fh.
833
834=item * file_offset
835
836This is the offset within the file that the DBM::Deep db starts. Most of the time, you will
837not need to set this. However, it's there if you want it.
838
839If you pass in fh and do not set this, it will be set appropriately.
ffed8b01 840
ffed8b01 841=item * type
842
843This parameter specifies what type of object to create, a hash or array. Use
844one of these two constants: C<DBM::Deep-E<gt>TYPE_HASH> or C<DBM::Deep-E<gt>TYPE_ARRAY>.
d0b74c17 845This only takes effect when beginning a new file. This is an optional
ffed8b01 846parameter, and defaults to C<DBM::Deep-E<gt>TYPE_HASH>.
847
848=item * locking
849
850Specifies whether locking is to be enabled. DBM::Deep uses Perl's Fnctl flock()
851function to lock the database in exclusive mode for writes, and shared mode for
d0b74c17 852reads. Pass any true value to enable. This affects the base DB handle I<and
853any child hashes or arrays> that use the same DB file. This is an optional
ffed8b01 854parameter, and defaults to 0 (disabled). See L<LOCKING> below for more.
855
856=item * autoflush
857
d0b74c17 858Specifies whether autoflush is to be enabled on the underlying filehandle.
859This obviously slows down write operations, but is required if you may have
860multiple processes accessing the same DB file (also consider enable I<locking>).
861Pass any true value to enable. This is an optional parameter, and defaults to 0
ffed8b01 862(disabled).
863
864=item * autobless
865
866If I<autobless> mode is enabled, DBM::Deep will preserve blessed hashes, and
867restore them when fetched. This is an B<experimental> feature, and does have
868side-effects. Basically, when hashes are re-blessed into their original
869classes, they are no longer blessed into the DBM::Deep class! So you won't be
870able to call any DBM::Deep methods on them. You have been warned.
871This is an optional parameter, and defaults to 0 (disabled).
872
873=item * filter_*
874
875See L<FILTERS> below.
876
ffed8b01 877=back
878
879=head1 TIE INTERFACE
880
881With DBM::Deep you can access your databases using Perl's standard hash/array
90f93b43 882syntax. Because all DBM::Deep objects are I<tied> to hashes or arrays, you can
883treat them as such. DBM::Deep will intercept all reads/writes and direct them
884to the right place -- the DB file. This has nothing to do with the
885L<TIE CONSTRUCTION> section above. This simply tells you how to use DBM::Deep
886using regular hashes and arrays, rather than calling functions like C<get()>
887and C<put()> (although those work too). It is entirely up to you how to want
888to access your databases.
ffed8b01 889
890=head2 HASHES
891
892You can treat any DBM::Deep object like a normal Perl hash reference. Add keys,
893or even nested hashes (or arrays) using standard Perl syntax:
894
d0b74c17 895 my $db = DBM::Deep->new( "foo.db" );
896
897 $db->{mykey} = "myvalue";
898 $db->{myhash} = {};
899 $db->{myhash}->{subkey} = "subvalue";
ffed8b01 900
d0b74c17 901 print $db->{myhash}->{subkey} . "\n";
ffed8b01 902
903You can even step through hash keys using the normal Perl C<keys()> function:
904
d0b74c17 905 foreach my $key (keys %$db) {
906 print "$key: " . $db->{$key} . "\n";
907 }
ffed8b01 908
909Remember that Perl's C<keys()> function extracts I<every> key from the hash and
d0b74c17 910pushes them onto an array, all before the loop even begins. If you have an
911extra large hash, this may exhaust Perl's memory. Instead, consider using
912Perl's C<each()> function, which pulls keys/values one at a time, using very
ffed8b01 913little memory:
914
d0b74c17 915 while (my ($key, $value) = each %$db) {
916 print "$key: $value\n";
917 }
ffed8b01 918
919Please note that when using C<each()>, you should always pass a direct
920hash reference, not a lookup. Meaning, you should B<never> do this:
921
d0b74c17 922 # NEVER DO THIS
923 while (my ($key, $value) = each %{$db->{foo}}) { # BAD
ffed8b01 924
925This causes an infinite loop, because for each iteration, Perl is calling
926FETCH() on the $db handle, resulting in a "new" hash for foo every time, so
d0b74c17 927it effectively keeps returning the first key over and over again. Instead,
ffed8b01 928assign a temporary variable to C<$db->{foo}>, then pass that to each().
929
930=head2 ARRAYS
931
932As with hashes, you can treat any DBM::Deep object like a normal Perl array
d0b74c17 933reference. This includes inserting, removing and manipulating elements,
ffed8b01 934and the C<push()>, C<pop()>, C<shift()>, C<unshift()> and C<splice()> functions.
d0b74c17 935The object must have first been created using type C<DBM::Deep-E<gt>TYPE_ARRAY>,
ffed8b01 936or simply be a nested array reference inside a hash. Example:
937
d0b74c17 938 my $db = DBM::Deep->new(
939 file => "foo-array.db",
940 type => DBM::Deep->TYPE_ARRAY
941 );
942
943 $db->[0] = "foo";
944 push @$db, "bar", "baz";
945 unshift @$db, "bah";
946
947 my $last_elem = pop @$db; # baz
948 my $first_elem = shift @$db; # bah
949 my $second_elem = $db->[1]; # bar
950
951 my $num_elements = scalar @$db;
ffed8b01 952
953=head1 OO INTERFACE
954
955In addition to the I<tie()> interface, you can also use a standard OO interface
956to manipulate all aspects of DBM::Deep databases. Each type of object (hash or
d0b74c17 957array) has its own methods, but both types share the following common methods:
ffed8b01 958C<put()>, C<get()>, C<exists()>, C<delete()> and C<clear()>.
959
960=over
961
4d35d856 962=item * new() / clone()
963
964These are the constructor and copy-functions.
965
90f93b43 966=item * put() / store()
ffed8b01 967
968Stores a new hash key/value pair, or sets an array element value. Takes two
969arguments, the hash key or array index, and the new value. The value can be
970a scalar, hash ref or array ref. Returns true on success, false on failure.
971
d0b74c17 972 $db->put("foo", "bar"); # for hashes
973 $db->put(1, "bar"); # for arrays
ffed8b01 974
90f93b43 975=item * get() / fetch()
ffed8b01 976
977Fetches the value of a hash key or array element. Takes one argument: the hash
d0b74c17 978key or array index. Returns a scalar, hash ref or array ref, depending on the
ffed8b01 979data type stored.
980
d0b74c17 981 my $value = $db->get("foo"); # for hashes
982 my $value = $db->get(1); # for arrays
ffed8b01 983
984=item * exists()
985
d0b74c17 986Checks if a hash key or array index exists. Takes one argument: the hash key
ffed8b01 987or array index. Returns true if it exists, false if not.
988
d0b74c17 989 if ($db->exists("foo")) { print "yay!\n"; } # for hashes
990 if ($db->exists(1)) { print "yay!\n"; } # for arrays
ffed8b01 991
992=item * delete()
993
994Deletes one hash key/value pair or array element. Takes one argument: the hash
995key or array index. Returns true on success, false if not found. For arrays,
996the remaining elements located after the deleted element are NOT moved over.
997The deleted element is essentially just undefined, which is exactly how Perl's
d0b74c17 998internal arrays work. Please note that the space occupied by the deleted
999key/value or element is B<not> reused again -- see L<UNUSED SPACE RECOVERY>
ffed8b01 1000below for details and workarounds.
1001
d0b74c17 1002 $db->delete("foo"); # for hashes
1003 $db->delete(1); # for arrays
ffed8b01 1004
1005=item * clear()
1006
d0b74c17 1007Deletes B<all> hash keys or array elements. Takes no arguments. No return
1008value. Please note that the space occupied by the deleted keys/values or
1009elements is B<not> reused again -- see L<UNUSED SPACE RECOVERY> below for
ffed8b01 1010details and workarounds.
1011
d0b74c17 1012 $db->clear(); # hashes or arrays
ffed8b01 1013
4d35d856 1014=item * lock() / unlock()
1015
1016q.v. Locking.
1017
1018=item * optimize()
1019
1020Recover lost disk space.
1021
1022=item * import() / export()
1023
1024Data going in and out.
1025
1026=item * set_digest() / set_pack() / set_filter()
1027
1028q.v. adjusting the interal parameters.
1029
ffed8b01 1030=back
1031
1032=head2 HASHES
1033
d0b74c17 1034For hashes, DBM::Deep supports all the common methods described above, and the
ffed8b01 1035following additional methods: C<first_key()> and C<next_key()>.
1036
1037=over
1038
1039=item * first_key()
1040
d0b74c17 1041Returns the "first" key in the hash. As with built-in Perl hashes, keys are
1042fetched in an undefined order (which appears random). Takes no arguments,
ffed8b01 1043returns the key as a scalar value.
1044
d0b74c17 1045 my $key = $db->first_key();
ffed8b01 1046
1047=item * next_key()
1048
1049Returns the "next" key in the hash, given the previous one as the sole argument.
1050Returns undef if there are no more keys to be fetched.
1051
d0b74c17 1052 $key = $db->next_key($key);
ffed8b01 1053
1054=back
1055
1056Here are some examples of using hashes:
1057
d0b74c17 1058 my $db = DBM::Deep->new( "foo.db" );
1059
1060 $db->put("foo", "bar");
1061 print "foo: " . $db->get("foo") . "\n";
1062
1063 $db->put("baz", {}); # new child hash ref
1064 $db->get("baz")->put("buz", "biz");
1065 print "buz: " . $db->get("baz")->get("buz") . "\n";
1066
1067 my $key = $db->first_key();
1068 while ($key) {
1069 print "$key: " . $db->get($key) . "\n";
1070 $key = $db->next_key($key);
1071 }
1072
1073 if ($db->exists("foo")) { $db->delete("foo"); }
ffed8b01 1074
1075=head2 ARRAYS
1076
d0b74c17 1077For arrays, DBM::Deep supports all the common methods described above, and the
1078following additional methods: C<length()>, C<push()>, C<pop()>, C<shift()>,
ffed8b01 1079C<unshift()> and C<splice()>.
1080
1081=over
1082
1083=item * length()
1084
1085Returns the number of elements in the array. Takes no arguments.
1086
d0b74c17 1087 my $len = $db->length();
ffed8b01 1088
1089=item * push()
1090
d0b74c17 1091Adds one or more elements onto the end of the array. Accepts scalars, hash
ffed8b01 1092refs or array refs. No return value.
1093
d0b74c17 1094 $db->push("foo", "bar", {});
ffed8b01 1095
1096=item * pop()
1097
1098Fetches the last element in the array, and deletes it. Takes no arguments.
1099Returns undef if array is empty. Returns the element value.
1100
d0b74c17 1101 my $elem = $db->pop();
ffed8b01 1102
1103=item * shift()
1104
d0b74c17 1105Fetches the first element in the array, deletes it, then shifts all the
1106remaining elements over to take up the space. Returns the element value. This
1107method is not recommended with large arrays -- see L<LARGE ARRAYS> below for
ffed8b01 1108details.
1109
d0b74c17 1110 my $elem = $db->shift();
ffed8b01 1111
1112=item * unshift()
1113
d0b74c17 1114Inserts one or more elements onto the beginning of the array, shifting all
1115existing elements over to make room. Accepts scalars, hash refs or array refs.
1116No return value. This method is not recommended with large arrays -- see
ffed8b01 1117<LARGE ARRAYS> below for details.
1118
d0b74c17 1119 $db->unshift("foo", "bar", {});
ffed8b01 1120
1121=item * splice()
1122
d0b74c17 1123Performs exactly like Perl's built-in function of the same name. See L<perldoc
ffed8b01 1124-f splice> for usage -- it is too complicated to document here. This method is
1125not recommended with large arrays -- see L<LARGE ARRAYS> below for details.
1126
1127=back
1128
1129Here are some examples of using arrays:
1130
d0b74c17 1131 my $db = DBM::Deep->new(
1132 file => "foo.db",
1133 type => DBM::Deep->TYPE_ARRAY
1134 );
1135
1136 $db->push("bar", "baz");
1137 $db->unshift("foo");
1138 $db->put(3, "buz");
1139
1140 my $len = $db->length();
1141 print "length: $len\n"; # 4
1142
1143 for (my $k=0; $k<$len; $k++) {
1144 print "$k: " . $db->get($k) . "\n";
1145 }
1146
1147 $db->splice(1, 2, "biz", "baf");
1148
1149 while (my $elem = shift @$db) {
1150 print "shifted: $elem\n";
1151 }
ffed8b01 1152
1153=head1 LOCKING
1154
d0b74c17 1155Enable automatic file locking by passing a true value to the C<locking>
ffed8b01 1156parameter when constructing your DBM::Deep object (see L<SETUP> above).
1157
d0b74c17 1158 my $db = DBM::Deep->new(
1159 file => "foo.db",
1160 locking => 1
1161 );
ffed8b01 1162
d0b74c17 1163This causes DBM::Deep to C<flock()> the underlying filehandle with exclusive
1164mode for writes, and shared mode for reads. This is required if you have
1165multiple processes accessing the same database file, to avoid file corruption.
1166Please note that C<flock()> does NOT work for files over NFS. See L<DB OVER
ffed8b01 1167NFS> below for more.
1168
1169=head2 EXPLICIT LOCKING
1170
d0b74c17 1171You can explicitly lock a database, so it remains locked for multiple
1172transactions. This is done by calling the C<lock()> method, and passing an
90f93b43 1173optional lock mode argument (defaults to exclusive mode). This is particularly
d0b74c17 1174useful for things like counters, where the current value needs to be fetched,
ffed8b01 1175then incremented, then stored again.
1176
d0b74c17 1177 $db->lock();
1178 my $counter = $db->get("counter");
1179 $counter++;
1180 $db->put("counter", $counter);
1181 $db->unlock();
1182
1183 # or...
ffed8b01 1184
d0b74c17 1185 $db->lock();
1186 $db->{counter}++;
1187 $db->unlock();
ffed8b01 1188
1189You can pass C<lock()> an optional argument, which specifies which mode to use
d0b74c17 1190(exclusive or shared). Use one of these two constants: C<DBM::Deep-E<gt>LOCK_EX>
1191or C<DBM::Deep-E<gt>LOCK_SH>. These are passed directly to C<flock()>, and are the
ffed8b01 1192same as the constants defined in Perl's C<Fcntl> module.
1193
d0b74c17 1194 $db->lock( DBM::Deep->LOCK_SH );
1195 # something here
1196 $db->unlock();
ffed8b01 1197
ffed8b01 1198=head1 IMPORTING/EXPORTING
1199
1200You can import existing complex structures by calling the C<import()> method,
1201and export an entire database into an in-memory structure using the C<export()>
1202method. Both are examined here.
1203
1204=head2 IMPORTING
1205
1206Say you have an existing hash with nested hashes/arrays inside it. Instead of
d0b74c17 1207walking the structure and adding keys/elements to the database as you go,
1208simply pass a reference to the C<import()> method. This recursively adds
ffed8b01 1209everything to an existing DBM::Deep object for you. Here is an example:
1210
d0b74c17 1211 my $struct = {
1212 key1 => "value1",
1213 key2 => "value2",
1214 array1 => [ "elem0", "elem1", "elem2" ],
1215 hash1 => {
1216 subkey1 => "subvalue1",
1217 subkey2 => "subvalue2"
1218 }
1219 };
1220
1221 my $db = DBM::Deep->new( "foo.db" );
1222 $db->import( $struct );
1223
1224 print $db->{key1} . "\n"; # prints "value1"
1225
1226This recursively imports the entire C<$struct> object into C<$db>, including
ffed8b01 1227all nested hashes and arrays. If the DBM::Deep object contains exsiting data,
d0b74c17 1228keys are merged with the existing ones, replacing if they already exist.
1229The C<import()> method can be called on any database level (not just the base
ffed8b01 1230level), and works with both hash and array DB types.
1231
ffed8b01 1232B<Note:> Make sure your existing structure has no circular references in it.
1233These will cause an infinite loop when importing.
1234
1235=head2 EXPORTING
1236
d0b74c17 1237Calling the C<export()> method on an existing DBM::Deep object will return
1238a reference to a new in-memory copy of the database. The export is done
ffed8b01 1239recursively, so all nested hashes/arrays are all exported to standard Perl
1240objects. Here is an example:
1241
d0b74c17 1242 my $db = DBM::Deep->new( "foo.db" );
1243
1244 $db->{key1} = "value1";
1245 $db->{key2} = "value2";
1246 $db->{hash1} = {};
1247 $db->{hash1}->{subkey1} = "subvalue1";
1248 $db->{hash1}->{subkey2} = "subvalue2";
1249
1250 my $struct = $db->export();
1251
1252 print $struct->{key1} . "\n"; # prints "value1"
ffed8b01 1253
1254This makes a complete copy of the database in memory, and returns a reference
d0b74c17 1255to it. The C<export()> method can be called on any database level (not just
1256the base level), and works with both hash and array DB types. Be careful of
1257large databases -- you can store a lot more data in a DBM::Deep object than an
ffed8b01 1258in-memory Perl structure.
1259
ffed8b01 1260B<Note:> Make sure your database has no circular references in it.
1261These will cause an infinite loop when exporting.
1262
1263=head1 FILTERS
1264
1265DBM::Deep has a number of hooks where you can specify your own Perl function
1266to perform filtering on incoming or outgoing data. This is a perfect
1267way to extend the engine, and implement things like real-time compression or
d0b74c17 1268encryption. Filtering applies to the base DB level, and all child hashes /
1269arrays. Filter hooks can be specified when your DBM::Deep object is first
1270constructed, or by calling the C<set_filter()> method at any time. There are
ffed8b01 1271four available filter hooks, described below:
1272
1273=over
1274
1275=item * filter_store_key
1276
d0b74c17 1277This filter is called whenever a hash key is stored. It
ffed8b01 1278is passed the incoming key, and expected to return a transformed key.
1279
1280=item * filter_store_value
1281
d0b74c17 1282This filter is called whenever a hash key or array element is stored. It
ffed8b01 1283is passed the incoming value, and expected to return a transformed value.
1284
1285=item * filter_fetch_key
1286
d0b74c17 1287This filter is called whenever a hash key is fetched (i.e. via
ffed8b01 1288C<first_key()> or C<next_key()>). It is passed the transformed key,
1289and expected to return the plain key.
1290
1291=item * filter_fetch_value
1292
d0b74c17 1293This filter is called whenever a hash key or array element is fetched.
ffed8b01 1294It is passed the transformed value, and expected to return the plain value.
1295
1296=back
1297
1298Here are the two ways to setup a filter hook:
1299
d0b74c17 1300 my $db = DBM::Deep->new(
1301 file => "foo.db",
1302 filter_store_value => \&my_filter_store,
1303 filter_fetch_value => \&my_filter_fetch
1304 );
1305
1306 # or...
1307
1308 $db->set_filter( "filter_store_value", \&my_filter_store );
1309 $db->set_filter( "filter_fetch_value", \&my_filter_fetch );
ffed8b01 1310
1311Your filter function will be called only when dealing with SCALAR keys or
1312values. When nested hashes and arrays are being stored/fetched, filtering
d0b74c17 1313is bypassed. Filters are called as static functions, passed a single SCALAR
ffed8b01 1314argument, and expected to return a single SCALAR value. If you want to
1315remove a filter, set the function reference to C<undef>:
1316
d0b74c17 1317 $db->set_filter( "filter_store_value", undef );
ffed8b01 1318
1319=head2 REAL-TIME ENCRYPTION EXAMPLE
1320
d0b74c17 1321Here is a working example that uses the I<Crypt::Blowfish> module to
ffed8b01 1322do real-time encryption / decryption of keys & values with DBM::Deep Filters.
d0b74c17 1323Please visit L<http://search.cpan.org/search?module=Crypt::Blowfish> for more
ffed8b01 1324on I<Crypt::Blowfish>. You'll also need the I<Crypt::CBC> module.
1325
d0b74c17 1326 use DBM::Deep;
1327 use Crypt::Blowfish;
1328 use Crypt::CBC;
1329
1330 my $cipher = Crypt::CBC->new({
1331 'key' => 'my secret key',
1332 'cipher' => 'Blowfish',
1333 'iv' => '$KJh#(}q',
1334 'regenerate_key' => 0,
1335 'padding' => 'space',
1336 'prepend_iv' => 0
1337 });
1338
1339 my $db = DBM::Deep->new(
1340 file => "foo-encrypt.db",
1341 filter_store_key => \&my_encrypt,
1342 filter_store_value => \&my_encrypt,
1343 filter_fetch_key => \&my_decrypt,
1344 filter_fetch_value => \&my_decrypt,
1345 );
1346
1347 $db->{key1} = "value1";
1348 $db->{key2} = "value2";
1349 print "key1: " . $db->{key1} . "\n";
1350 print "key2: " . $db->{key2} . "\n";
1351
1352 undef $db;
1353 exit;
1354
1355 sub my_encrypt {
1356 return $cipher->encrypt( $_[0] );
1357 }
1358 sub my_decrypt {
1359 return $cipher->decrypt( $_[0] );
1360 }
ffed8b01 1361
1362=head2 REAL-TIME COMPRESSION EXAMPLE
1363
1364Here is a working example that uses the I<Compress::Zlib> module to do real-time
1365compression / decompression of keys & values with DBM::Deep Filters.
d0b74c17 1366Please visit L<http://search.cpan.org/search?module=Compress::Zlib> for
ffed8b01 1367more on I<Compress::Zlib>.
1368
d0b74c17 1369 use DBM::Deep;
1370 use Compress::Zlib;
1371
1372 my $db = DBM::Deep->new(
1373 file => "foo-compress.db",
1374 filter_store_key => \&my_compress,
1375 filter_store_value => \&my_compress,
1376 filter_fetch_key => \&my_decompress,
1377 filter_fetch_value => \&my_decompress,
1378 );
1379
1380 $db->{key1} = "value1";
1381 $db->{key2} = "value2";
1382 print "key1: " . $db->{key1} . "\n";
1383 print "key2: " . $db->{key2} . "\n";
1384
1385 undef $db;
1386 exit;
1387
1388 sub my_compress {
1389 return Compress::Zlib::memGzip( $_[0] ) ;
1390 }
1391 sub my_decompress {
1392 return Compress::Zlib::memGunzip( $_[0] ) ;
1393 }
ffed8b01 1394
1395B<Note:> Filtering of keys only applies to hashes. Array "keys" are
1396actually numerical index numbers, and are not filtered.
1397
1398=head1 ERROR HANDLING
1399
1400Most DBM::Deep methods return a true value for success, and call die() on
95967a5e 1401failure. You can wrap calls in an eval block to catch the die.
ffed8b01 1402
d0b74c17 1403 my $db = DBM::Deep->new( "foo.db" ); # create hash
1404 eval { $db->push("foo"); }; # ILLEGAL -- push is array-only call
1405
90f93b43 1406 print $@; # prints error message
429e4192 1407
ffed8b01 1408=head1 LARGEFILE SUPPORT
1409
1410If you have a 64-bit system, and your Perl is compiled with both LARGEFILE
1411and 64-bit support, you I<may> be able to create databases larger than 2 GB.
1412DBM::Deep by default uses 32-bit file offset tags, but these can be changed
1413by calling the static C<set_pack()> method before you do anything else.
1414
d0b74c17 1415 DBM::Deep::set_pack(8, 'Q');
ffed8b01 1416
d0b74c17 1417This tells DBM::Deep to pack all file offsets with 8-byte (64-bit) quad words
1418instead of 32-bit longs. After setting these values your DB files have a
ffed8b01 1419theoretical maximum size of 16 XB (exabytes).
1420
ffed8b01 1421B<Note:> Changing these values will B<NOT> work for existing database files.
d0b74c17 1422Only change this for new files, and make sure it stays set consistently
1423throughout the file's life. If you do set these values, you can no longer
1424access 32-bit DB files. You can, however, call C<set_pack(4, 'N')> to change
ffed8b01 1425back to 32-bit mode.
1426
d0b74c17 1427B<Note:> I have not personally tested files > 2 GB -- all my systems have
1428only a 32-bit Perl. However, I have received user reports that this does
ffed8b01 1429indeed work!
1430
1431=head1 LOW-LEVEL ACCESS
1432
90f93b43 1433If you require low-level access to the underlying filehandle that DBM::Deep uses,
4d35d856 1434you can call the C<_fh()> method, which returns the handle:
ffed8b01 1435
d0b74c17 1436 my $fh = $db->_fh();
ffed8b01 1437
1438This method can be called on the root level of the datbase, or any child
1439hashes or arrays. All levels share a I<root> structure, which contains things
90f93b43 1440like the filehandle, a reference counter, and all the options specified
d0b74c17 1441when you created the object. You can get access to this root structure by
ffed8b01 1442calling the C<root()> method.
1443
d0b74c17 1444 my $root = $db->_root();
ffed8b01 1445
1446This is useful for changing options after the object has already been created,
f5be9b03 1447such as enabling/disabling locking. You can also store your own temporary user
1448data in this structure (be wary of name collision), which is then accessible from
1449any child hash or array.
ffed8b01 1450
1451=head1 CUSTOM DIGEST ALGORITHM
1452
1453DBM::Deep by default uses the I<Message Digest 5> (MD5) algorithm for hashing
1454keys. However you can override this, and use another algorithm (such as SHA-256)
d0b74c17 1455or even write your own. But please note that DBM::Deep currently expects zero
ffed8b01 1456collisions, so your algorithm has to be I<perfect>, so to speak.
1457Collision detection may be introduced in a later version.
1458
1459
1460
d0b74c17 1461You can specify a custom digest algorithm by calling the static C<set_digest()>
1462function, passing a reference to a subroutine, and the length of the algorithm's
1463hashes (in bytes). This is a global static function, which affects ALL DBM::Deep
1464objects. Here is a working example that uses a 256-bit hash from the
1465I<Digest::SHA256> module. Please see
ffed8b01 1466L<http://search.cpan.org/search?module=Digest::SHA256> for more.
1467
d0b74c17 1468 use DBM::Deep;
1469 use Digest::SHA256;
1470
1471 my $context = Digest::SHA256::new(256);
1472
1473 DBM::Deep::set_digest( \&my_digest, 32 );
1474
1475 my $db = DBM::Deep->new( "foo-sha.db" );
1476
1477 $db->{key1} = "value1";
1478 $db->{key2} = "value2";
1479 print "key1: " . $db->{key1} . "\n";
1480 print "key2: " . $db->{key2} . "\n";
1481
1482 undef $db;
1483 exit;
1484
1485 sub my_digest {
1486 return substr( $context->hash($_[0]), 0, 32 );
1487 }
ffed8b01 1488
1489B<Note:> Your returned digest strings must be B<EXACTLY> the number
1490of bytes you specify in the C<set_digest()> function (in this case 32).
1491
1492=head1 CIRCULAR REFERENCES
1493
1494DBM::Deep has B<experimental> support for circular references. Meaning you
1495can have a nested hash key or array element that points to a parent object.
1496This relationship is stored in the DB file, and is preserved between sessions.
1497Here is an example:
1498
d0b74c17 1499 my $db = DBM::Deep->new( "foo.db" );
1500
1501 $db->{foo} = "bar";
1502 $db->{circle} = $db; # ref to self
1503
1504 print $db->{foo} . "\n"; # prints "foo"
1505 print $db->{circle}->{foo} . "\n"; # prints "foo" again
ffed8b01 1506
69c94980 1507B<Note>: Passing the object to a function that recursively walks the
ffed8b01 1508object tree (such as I<Data::Dumper> or even the built-in C<optimize()> or
69c94980 1509C<export()> methods) will result in an infinite loop. This will be fixed in
1510a future release.
ffed8b01 1511
1512=head1 CAVEATS / ISSUES / BUGS
1513
1514This section describes all the known issues with DBM::Deep. It you have found
1515something that is not listed here, please send e-mail to L<jhuckaby@cpan.org>.
1516
1517=head2 UNUSED SPACE RECOVERY
1518
14a3acb6 1519One major caveat with DBM::Deep is that space occupied by existing keys and
ffed8b01 1520values is not recovered when they are deleted. Meaning if you keep deleting
1521and adding new keys, your file will continuously grow. I am working on this,
d0b74c17 1522but in the meantime you can call the built-in C<optimize()> method from time to
ffed8b01 1523time (perhaps in a crontab or something) to recover all your unused space.
1524
d0b74c17 1525 $db->optimize(); # returns true on success
ffed8b01 1526
1527This rebuilds the ENTIRE database into a new file, then moves it on top of
1528the original. The new file will have no unused space, thus it will take up as
d0b74c17 1529little disk space as possible. Please note that this operation can take
1530a long time for large files, and you need enough disk space to temporarily hold
15312 copies of your DB file. The temporary file is created in the same directory
1532as the original, named with a ".tmp" extension, and is deleted when the
1533operation completes. Oh, and if locking is enabled, the DB is automatically
ffed8b01 1534locked for the entire duration of the copy.
1535
d0b74c17 1536B<WARNING:> Only call optimize() on the top-level node of the database, and
1537make sure there are no child references lying around. DBM::Deep keeps a reference
ffed8b01 1538counter, and if it is greater than 1, optimize() will abort and return undef.
1539
1540=head2 AUTOVIVIFICATION
1541
d0b74c17 1542Unfortunately, autovivification doesn't work with tied hashes. This appears to
1543be a bug in Perl's tie() system, as I<Jakob Schmidt> encountered the very same
ffed8b01 1544issue with his I<DWH_FIle> module (see L<http://search.cpan.org/search?module=DWH_File>),
d0b74c17 1545and it is also mentioned in the BUGS section for the I<MLDBM> module <see
ffed8b01 1546L<http://search.cpan.org/search?module=MLDBM>). Basically, on a new db file,
1547this does not work:
1548
d0b74c17 1549 $db->{foo}->{bar} = "hello";
ffed8b01 1550
1551Since "foo" doesn't exist, you cannot add "bar" to it. You end up with "foo"
1552being an empty hash. Try this instead, which works fine:
1553
d0b74c17 1554 $db->{foo} = { bar => "hello" };
ffed8b01 1555
1556As of Perl 5.8.7, this bug still exists. I have walked very carefully through
1557the execution path, and Perl indeed passes an empty hash to the STORE() method.
1558Probably a bug in Perl.
1559
eea0d863 1560=head2 REFERENCES
1561
1562(The reasons given assume a high level of Perl understanding, specifically of
1563references. You can safely skip this section.)
1564
1565Currently, the only references supported are HASH and ARRAY. The other reference
1566types (SCALAR, CODE, GLOB, and REF) cannot be supported for various reasons.
1567
1568=over 4
1569
1570=item * GLOB
1571
1572These are things like filehandles and other sockets. They can't be supported
1573because it's completely unclear how DBM::Deep should serialize them.
1574
1575=item * SCALAR / REF
1576
1577The discussion here refers to the following type of example:
1578
1579 my $x = 25;
1580 $db->{key1} = \$x;
1581
1582 $x = 50;
1583
1584 # In some other process ...
1585
1586 my $val = ${ $db->{key1} };
1587
1588 is( $val, 50, "What actually gets stored in the DB file?" );
1589
1590The problem is one of synchronization. When the variable being referred to
1591changes value, the reference isn't notified. This means that the new value won't
1592be stored in the datafile for other processes to read. There is no TIEREF.
1593
1594It is theoretically possible to store references to values already within a
1595DBM::Deep object because everything already is synchronized, but the change to
1596the internals would be quite large. Specifically, DBM::Deep would have to tie
1597every single value that is stored. This would bloat the RAM footprint of
1598DBM::Deep at least twofold (if not more) and be a significant performance drain,
1599all to support a feature that has never been requested.
1600
1601=item * CODE
1602
1603L<http://search.cpan.org/search?module=Data::Dump::Streamer> provides a
1604mechanism for serializing coderefs, including saving off all closure state.
1605However, just as for SCALAR and REF, that closure state may change without
1606notifying the DBM::Deep object storing the reference.
1607
1608=back
1609
ffed8b01 1610=head2 FILE CORRUPTION
1611
14a3acb6 1612The current level of error handling in DBM::Deep is minimal. Files I<are> checked
1613for a 32-bit signature when opened, but other corruption in files can cause
1614segmentation faults. DBM::Deep may try to seek() past the end of a file, or get
ffed8b01 1615stuck in an infinite loop depending on the level of corruption. File write
1616operations are not checked for failure (for speed), so if you happen to run
d0b74c17 1617out of disk space, DBM::Deep will probably fail in a bad way. These things will
ffed8b01 1618be addressed in a later version of DBM::Deep.
1619
1620=head2 DB OVER NFS
1621
14a3acb6 1622Beware of using DB files over NFS. DBM::Deep uses flock(), which works well on local
d0b74c17 1623filesystems, but will NOT protect you from file corruption over NFS. I've heard
1624about setting up your NFS server with a locking daemon, then using lockf() to
1625lock your files, but your mileage may vary there as well. From what I
1626understand, there is no real way to do it. However, if you need access to the
1627underlying filehandle in DBM::Deep for using some other kind of locking scheme like
ffed8b01 1628lockf(), see the L<LOW-LEVEL ACCESS> section above.
1629
1630=head2 COPYING OBJECTS
1631
d0b74c17 1632Beware of copying tied objects in Perl. Very strange things can happen.
1633Instead, use DBM::Deep's C<clone()> method which safely copies the object and
ffed8b01 1634returns a new, blessed, tied hash or array to the same level in the DB.
1635
d0b74c17 1636 my $copy = $db->clone();
ffed8b01 1637
90f93b43 1638B<Note>: Since clone() here is cloning the object, not the database location, any
1639modifications to either $db or $copy will be visible in both.
1640
ffed8b01 1641=head2 LARGE ARRAYS
1642
1643Beware of using C<shift()>, C<unshift()> or C<splice()> with large arrays.
1644These functions cause every element in the array to move, which can be murder
1645on DBM::Deep, as every element has to be fetched from disk, then stored again in
90f93b43 1646a different location. This will be addressed in the forthcoming version 1.00.
ffed8b01 1647
9be51a89 1648=head2 WRITEONLY FILES
1649
1650If you pass in a filehandle to new(), you may have opened it in either a readonly or
1651writeonly mode. STORE will verify that the filehandle is writable. However, there
1652doesn't seem to be a good way to determine if a filehandle is readable. And, if the
1653filehandle isn't readable, it's not clear what will happen. So, don't do that.
1654
ffed8b01 1655=head1 PERFORMANCE
1656
1657This section discusses DBM::Deep's speed and memory usage.
1658
1659=head2 SPEED
1660
d0b74c17 1661Obviously, DBM::Deep isn't going to be as fast as some C-based DBMs, such as
ffed8b01 1662the almighty I<BerkeleyDB>. But it makes up for it in features like true
1663multi-level hash/array support, and cross-platform FTPable files. Even so,
1664DBM::Deep is still pretty fast, and the speed stays fairly consistent, even
1665with huge databases. Here is some test data:
d0b74c17 1666
1667 Adding 1,000,000 keys to new DB file...
1668
1669 At 100 keys, avg. speed is 2,703 keys/sec
1670 At 200 keys, avg. speed is 2,642 keys/sec
1671 At 300 keys, avg. speed is 2,598 keys/sec
1672 At 400 keys, avg. speed is 2,578 keys/sec
1673 At 500 keys, avg. speed is 2,722 keys/sec
1674 At 600 keys, avg. speed is 2,628 keys/sec
1675 At 700 keys, avg. speed is 2,700 keys/sec
1676 At 800 keys, avg. speed is 2,607 keys/sec
1677 At 900 keys, avg. speed is 2,190 keys/sec
1678 At 1,000 keys, avg. speed is 2,570 keys/sec
1679 At 2,000 keys, avg. speed is 2,417 keys/sec
1680 At 3,000 keys, avg. speed is 1,982 keys/sec
1681 At 4,000 keys, avg. speed is 1,568 keys/sec
1682 At 5,000 keys, avg. speed is 1,533 keys/sec
1683 At 6,000 keys, avg. speed is 1,787 keys/sec
1684 At 7,000 keys, avg. speed is 1,977 keys/sec
1685 At 8,000 keys, avg. speed is 2,028 keys/sec
1686 At 9,000 keys, avg. speed is 2,077 keys/sec
1687 At 10,000 keys, avg. speed is 2,031 keys/sec
1688 At 20,000 keys, avg. speed is 1,970 keys/sec
1689 At 30,000 keys, avg. speed is 2,050 keys/sec
1690 At 40,000 keys, avg. speed is 2,073 keys/sec
1691 At 50,000 keys, avg. speed is 1,973 keys/sec
1692 At 60,000 keys, avg. speed is 1,914 keys/sec
1693 At 70,000 keys, avg. speed is 2,091 keys/sec
1694 At 80,000 keys, avg. speed is 2,103 keys/sec
1695 At 90,000 keys, avg. speed is 1,886 keys/sec
1696 At 100,000 keys, avg. speed is 1,970 keys/sec
1697 At 200,000 keys, avg. speed is 2,053 keys/sec
1698 At 300,000 keys, avg. speed is 1,697 keys/sec
1699 At 400,000 keys, avg. speed is 1,838 keys/sec
1700 At 500,000 keys, avg. speed is 1,941 keys/sec
1701 At 600,000 keys, avg. speed is 1,930 keys/sec
1702 At 700,000 keys, avg. speed is 1,735 keys/sec
1703 At 800,000 keys, avg. speed is 1,795 keys/sec
1704 At 900,000 keys, avg. speed is 1,221 keys/sec
1705 At 1,000,000 keys, avg. speed is 1,077 keys/sec
1706
1707This test was performed on a PowerMac G4 1gHz running Mac OS X 10.3.2 & Perl
17085.8.1, with an 80GB Ultra ATA/100 HD spinning at 7200RPM. The hash keys and
1709values were between 6 - 12 chars in length. The DB file ended up at 210MB.
ffed8b01 1710Run time was 12 min 3 sec.
1711
1712=head2 MEMORY USAGE
1713
1714One of the great things about DBM::Deep is that it uses very little memory.
1715Even with huge databases (1,000,000+ keys) you will not see much increased
14a3acb6 1716memory on your process. DBM::Deep relies solely on the filesystem for storing
ffed8b01 1717and fetching data. Here is output from I</usr/bin/top> before even opening a
1718database handle:
1719
d0b74c17 1720 PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
1721 22831 root 11 0 2716 2716 1296 R 0.0 0.2 0:07 perl
ffed8b01 1722
d0b74c17 1723Basically the process is taking 2,716K of memory. And here is the same
ffed8b01 1724process after storing and fetching 1,000,000 keys:
1725
d0b74c17 1726 PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
1727 22831 root 14 0 2772 2772 1328 R 0.0 0.2 13:32 perl
ffed8b01 1728
d0b74c17 1729Notice the memory usage increased by only 56K. Test was performed on a 700mHz
ffed8b01 1730x86 box running Linux RedHat 7.2 & Perl 5.6.1.
1731
1732=head1 DB FILE FORMAT
1733
1734In case you were interested in the underlying DB file format, it is documented
d0b74c17 1735here in this section. You don't need to know this to use the module, it's just
ffed8b01 1736included for reference.
1737
1738=head2 SIGNATURE
1739
1740DBM::Deep files always start with a 32-bit signature to identify the file type.
1741This is at offset 0. The signature is "DPDB" in network byte order. This is
90f93b43 1742checked for when the file is opened and an error will be thrown if it's not found.
ffed8b01 1743
1744=head2 TAG
1745
1746The DBM::Deep file is in a I<tagged format>, meaning each section of the file
d0b74c17 1747has a standard header containing the type of data, the length of data, and then
1748the data itself. The type is a single character (1 byte), the length is a
ffed8b01 174932-bit unsigned long in network byte order, and the data is, well, the data.
1750Here is how it unfolds:
1751
1752=head2 MASTER INDEX
1753
d0b74c17 1754Immediately after the 32-bit file signature is the I<Master Index> record.
1755This is a standard tag header followed by 1024 bytes (in 32-bit mode) or 2048
1756bytes (in 64-bit mode) of data. The type is I<H> for hash or I<A> for array,
ffed8b01 1757depending on how the DBM::Deep object was constructed.
1758
d0b74c17 1759The index works by looking at a I<MD5 Hash> of the hash key (or array index
1760number). The first 8-bit char of the MD5 signature is the offset into the
1761index, multipled by 4 in 32-bit mode, or 8 in 64-bit mode. The value of the
ffed8b01 1762index element is a file offset of the next tag for the key/element in question,
1763which is usually a I<Bucket List> tag (see below).
1764
ffed8b01 1765The next tag I<could> be another index, depending on how many keys/elements
1766exist. See L<RE-INDEXING> below for details.
1767
1768=head2 BUCKET LIST
1769
d0b74c17 1770A I<Bucket List> is a collection of 16 MD5 hashes for keys/elements, plus
1771file offsets to where the actual data is stored. It starts with a standard
1772tag header, with type I<B>, and a data size of 320 bytes in 32-bit mode, or
ffed8b01 1773384 bytes in 64-bit mode. Each MD5 hash is stored in full (16 bytes), plus
1774the 32-bit or 64-bit file offset for the I<Bucket> containing the actual data.
d0b74c17 1775When the list fills up, a I<Re-Index> operation is performed (See
ffed8b01 1776L<RE-INDEXING> below).
1777
1778=head2 BUCKET
1779
1780A I<Bucket> is a tag containing a key/value pair (in hash mode), or a
1781index/value pair (in array mode). It starts with a standard tag header with
1782type I<D> for scalar data (string, binary, etc.), or it could be a nested
1783hash (type I<H>) or array (type I<A>). The value comes just after the tag
1784header. The size reported in the tag header is only for the value, but then,
d0b74c17 1785just after the value is another size (32-bit unsigned long) and then the plain
1786key itself. Since the value is likely to be fetched more often than the plain
ffed8b01 1787key, I figured it would be I<slightly> faster to store the value first.
1788
ffed8b01 1789If the type is I<H> (hash) or I<A> (array), the value is another I<Master Index>
1790record for the nested structure, where the process begins all over again.
1791
1792=head2 RE-INDEXING
1793
1794After a I<Bucket List> grows to 16 records, its allocated space in the file is
d0b74c17 1795exhausted. Then, when another key/element comes in, the list is converted to a
1796new index record. However, this index will look at the next char in the MD5
1797hash, and arrange new Bucket List pointers accordingly. This process is called
1798I<Re-Indexing>. Basically, a new index tag is created at the file EOF, and all
179917 (16 + new one) keys/elements are removed from the old Bucket List and
1800inserted into the new index. Several new Bucket Lists are created in the
1801process, as a new MD5 char from the key is being examined (it is unlikely that
ffed8b01 1802the keys will all share the same next char of their MD5s).
1803
ffed8b01 1804Because of the way the I<MD5> algorithm works, it is impossible to tell exactly
d0b74c17 1805when the Bucket Lists will turn into indexes, but the first round tends to
1806happen right around 4,000 keys. You will see a I<slight> decrease in
1807performance here, but it picks back up pretty quick (see L<SPEED> above). Then
1808it takes B<a lot> more keys to exhaust the next level of Bucket Lists. It's
1809right around 900,000 keys. This process can continue nearly indefinitely --
1810right up until the point the I<MD5> signatures start colliding with each other,
1811and this is B<EXTREMELY> rare -- like winning the lottery 5 times in a row AND
1812getting struck by lightning while you are walking to cash in your tickets.
1813Theoretically, since I<MD5> hashes are 128-bit values, you I<could> have up to
1814340,282,366,921,000,000,000,000,000,000,000,000,000 keys/elements (I believe
ffed8b01 1815this is 340 unodecillion, but don't quote me).
1816
1817=head2 STORING
1818
d0b74c17 1819When a new key/element is stored, the key (or index number) is first run through
1820I<Digest::MD5> to get a 128-bit signature (example, in hex:
ffed8b01 1821b05783b0773d894396d475ced9d2f4f6). Then, the I<Master Index> record is checked
37c5bcf0 1822for the first char of the signature (in this case I<b0>). If it does not exist,
d0b74c17 1823a new I<Bucket List> is created for our key (and the next 15 future keys that
1824happen to also have I<b> as their first MD5 char). The entire MD5 is written
ffed8b01 1825to the I<Bucket List> along with the offset of the new I<Bucket> record (EOF at
d0b74c17 1826this point, unless we are replacing an existing I<Bucket>), where the actual
ffed8b01 1827data will be stored.
1828
1829=head2 FETCHING
1830
d0b74c17 1831Fetching an existing key/element involves getting a I<Digest::MD5> of the key
1832(or index number), then walking along the indexes. If there are enough
1833keys/elements in this DB level, there might be nested indexes, each linked to
1834a particular char of the MD5. Finally, a I<Bucket List> is pointed to, which
1835contains up to 16 full MD5 hashes. Each is checked for equality to the key in
1836question. If we found a match, the I<Bucket> tag is loaded, where the value and
ffed8b01 1837plain key are stored.
1838
ffed8b01 1839Fetching the plain key occurs when calling the I<first_key()> and I<next_key()>
1840methods. In this process the indexes are walked systematically, and each key
1841fetched in increasing MD5 order (which is why it appears random). Once the
d0b74c17 1842I<Bucket> is found, the value is skipped and the plain key returned instead.
1843B<Note:> Do not count on keys being fetched as if the MD5 hashes were
1844alphabetically sorted. This only happens on an index-level -- as soon as the
1845I<Bucket Lists> are hit, the keys will come out in the order they went in --
1846so it's pretty much undefined how the keys will come out -- just like Perl's
ffed8b01 1847built-in hashes.
1848
261d1296 1849=head1 CODE COVERAGE
1850
37c5bcf0 1851We use B<Devel::Cover> to test the code coverage of our tests, below is the
90f93b43 1852B<Devel::Cover> report on this module's test suite.
7910cf68 1853
386bab6c 1854 ----------------------------------- ------ ------ ------ ------ ------ ------
1855 File stmt bran cond sub time total
1856 ----------------------------------- ------ ------ ------ ------ ------ ------
1857 blib/lib/DBM/Deep.pm 94.9 80.6 73.0 100.0 37.9 90.4
1858 blib/lib/DBM/Deep/Array.pm 100.0 91.1 100.0 100.0 18.2 98.1
1859 blib/lib/DBM/Deep/Engine.pm 98.9 87.3 80.0 100.0 34.2 95.2
1860 blib/lib/DBM/Deep/Hash.pm 100.0 87.5 100.0 100.0 9.7 97.3
1861 Total 97.9 85.9 79.7 100.0 100.0 94.3
1862 ----------------------------------- ------ ------ ------ ------ ------ ------
37c5bcf0 1863
1864=head1 MORE INFORMATION
1865
1866Check out the DBM::Deep Google Group at L<http://groups.google.com/group/DBM-Deep>
1867or send email to L<DBM-Deep@googlegroups.com>.
261d1296 1868
aeeb5497 1869=head1 AUTHORS
ffed8b01 1870
1871Joseph Huckaby, L<jhuckaby@cpan.org>
37c5bcf0 1872
aeeb5497 1873Rob Kinyon, L<rkinyon@cpan.org>
ffed8b01 1874
1875Special thanks to Adam Sah and Rich Gaushell! You know why :-)
1876
1877=head1 SEE ALSO
1878
1879perltie(1), Tie::Hash(3), Digest::MD5(3), Fcntl(3), flock(2), lockf(3), nfs(5),
1880Digest::SHA256(3), Crypt::Blowfish(3), Compress::Zlib(3)
1881
1882=head1 LICENSE
1883
aeeb5497 1884Copyright (c) 2002-2006 Joseph Huckaby. All Rights Reserved.
ffed8b01 1885This is free software, you may use it and distribute it under the
1886same terms as Perl itself.
1887
1888=cut