Moved _create_tag, _load_tag, and _index_lookup into the engine
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep.pm
1 package DBM::Deep;
2
3 ##
4 # DBM::Deep
5 #
6 # Description:
7 #       Multi-level database module for storing hash trees, arrays and simple
8 #       key/value pairs into FTP-able, cross-platform binary database files.
9 #
10 #       Type `perldoc DBM::Deep` for complete documentation.
11 #
12 # Usage Examples:
13 #       my %db;
14 #       tie %db, 'DBM::Deep', 'my_database.db'; # standard tie() method
15 #       
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";
25 #
26 # Copyright:
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.
30 ##
31
32 use strict;
33
34 use Fcntl qw( :DEFAULT :flock :seek );
35 use Digest::MD5 ();
36 use Scalar::Util ();
37
38 use DBM::Deep::Engine;
39
40 use vars qw( $VERSION );
41 $VERSION = q(0.99_01);
42
43 ##
44 # Set to 4 and 'N' for 32-bit offset tags (default).  Theoretical limit of 4 GB per file.
45 #       (Perl must be compiled with largefile support for files > 2 GB)
46 #
47 # Set to 8 and 'Q' for 64-bit offsets.  Theoretical limit of 16 XB per file.
48 #       (Perl must be compiled with largefile and 64-bit long support)
49 ##
50 #my $LONG_SIZE = 4;
51 #my $LONG_PACK = 'N';
52
53 ##
54 # Set to 4 and 'N' for 32-bit data length prefixes.  Limit of 4 GB for each key/value.
55 # Upgrading this is possible (see above) but probably not necessary.  If you need
56 # more than 4 GB for a single key or value, this module is really not for you :-)
57 ##
58 #my $DATA_LENGTH_SIZE = 4;
59 #my $DATA_LENGTH_PACK = 'N';
60 our ($LONG_SIZE, $LONG_PACK, $DATA_LENGTH_SIZE, $DATA_LENGTH_PACK);
61
62 ##
63 # Maximum number of buckets per list before another level of indexing is done.
64 # Increase this value for slightly greater speed, but larger database files.
65 # DO NOT decrease this value below 16, due to risk of recursive reindex overrun.
66 ##
67 my $MAX_BUCKETS = 16;
68
69 ##
70 # Better not adjust anything below here, unless you're me :-)
71 ##
72
73 ##
74 # Setup digest function for keys
75 ##
76 our ($DIGEST_FUNC, $HASH_SIZE);
77 #my $DIGEST_FUNC = \&Digest::MD5::md5;
78
79 ##
80 # Precalculate index and bucket sizes based on values above.
81 ##
82 #my $HASH_SIZE = 16;
83 our ($INDEX_SIZE, $BUCKET_SIZE, $BUCKET_LIST_SIZE);
84
85 set_digest();
86 #set_pack();
87 #_precalc_sizes();
88
89 ##
90 # Setup file and tag signatures.  These should never change.
91 ##
92 sub SIG_FILE   () { 'DPDB' }
93 sub SIG_HASH   () { 'H' }
94 sub SIG_ARRAY  () { 'A' }
95 sub SIG_SCALAR () { 'S' }
96 sub SIG_NULL   () { 'N' }
97 sub SIG_DATA   () { 'D' }
98 sub SIG_INDEX  () { 'I' }
99 sub SIG_BLIST  () { 'B' }
100 sub SIG_SIZE   () {  1  }
101
102 ##
103 # Setup constants for users to pass to new()
104 ##
105 sub TYPE_HASH   () { SIG_HASH   }
106 sub TYPE_ARRAY  () { SIG_ARRAY  }
107 sub TYPE_SCALAR () { SIG_SCALAR }
108
109 sub _get_args {
110     my $proto = shift;
111
112     my $args;
113     if (scalar(@_) > 1) {
114         if ( @_ % 2 ) {
115             $proto->_throw_error( "Odd number of parameters to " . (caller(1))[2] );
116         }
117         $args = {@_};
118     }
119         elsif ( ref $_[0] ) {
120         unless ( eval { local $SIG{'__DIE__'}; %{$_[0]} || 1 } ) {
121             $proto->_throw_error( "Not a hashref in args to " . (caller(1))[2] );
122         }
123         $args = $_[0];
124     }
125         else {
126         $args = { file => shift };
127     }
128
129     return $args;
130 }
131
132 sub new {
133         ##
134         # Class constructor method for Perl OO interface.
135         # Calls tie() and returns blessed reference to tied hash or array,
136         # providing a hybrid OO/tie interface.
137         ##
138         my $class = shift;
139         my $args = $class->_get_args( @_ );
140         
141         ##
142         # Check if we want a tied hash or array.
143         ##
144         my $self;
145         if (defined($args->{type}) && $args->{type} eq TYPE_ARRAY) {
146         $class = 'DBM::Deep::Array';
147         require DBM::Deep::Array;
148                 tie @$self, $class, %$args;
149         }
150         else {
151         $class = 'DBM::Deep::Hash';
152         require DBM::Deep::Hash;
153                 tie %$self, $class, %$args;
154         }
155
156         return bless $self, $class;
157 }
158
159 sub _init {
160     ##
161     # Setup $self and bless into this class.
162     ##
163     my $class = shift;
164     my $args = shift;
165
166     # These are the defaults to be optionally overridden below
167     my $self = bless {
168         type        => TYPE_HASH,
169         base_offset => length(SIG_FILE),
170         engine      => 'DBM::Deep::Engine',
171     }, $class;
172
173     foreach my $param ( keys %$self ) {
174         next unless exists $args->{$param};
175         $self->{$param} = delete $args->{$param}
176     }
177     
178     # locking implicitly enables autoflush
179     if ($args->{locking}) { $args->{autoflush} = 1; }
180     
181     $self->{root} = exists $args->{root}
182         ? $args->{root}
183         : DBM::Deep::_::Root->new( $args );
184
185     if (!defined($self->_fh)) { $self->{engine}->open( $self ); }
186
187     return $self;
188 }
189
190 sub TIEHASH {
191     shift;
192     require DBM::Deep::Hash;
193     return DBM::Deep::Hash->TIEHASH( @_ );
194 }
195
196 sub TIEARRAY {
197     shift;
198     require DBM::Deep::Array;
199     return DBM::Deep::Array->TIEARRAY( @_ );
200 }
201
202 #XXX Unneeded now ...
203 #sub DESTROY {
204 #}
205
206 sub _add_bucket {
207         ##
208         # Adds one key/value pair to bucket list, given offset, MD5 digest of key,
209         # plain (undigested) key and value.
210         ##
211         my $self = shift;
212         my ($tag, $md5, $plain_key, $value) = @_;
213         my $keys = $tag->{content};
214         my $location = 0;
215         my $result = 2;
216
217     my $root = $self->_root;
218
219     my $is_dbm_deep = eval { local $SIG{'__DIE__'}; $value->isa( 'DBM::Deep' ) };
220         my $internal_ref = $is_dbm_deep && ($value->_root eq $root);
221
222     my $fh = $self->_fh;
223
224         ##
225         # Iterate through buckets, seeing if this is a new entry or a replace.
226         ##
227         for (my $i=0; $i<$MAX_BUCKETS; $i++) {
228                 my $subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
229                 if (!$subloc) {
230                         ##
231                         # Found empty bucket (end of list).  Populate and exit loop.
232                         ##
233                         $result = 2;
234                         
235             $location = $internal_ref
236                 ? $value->_base_offset
237                 : $root->{end};
238                         
239                         seek($fh, $tag->{offset} + ($i * $BUCKET_SIZE) + $root->{file_offset}, SEEK_SET);
240                         print( $fh $md5 . pack($LONG_PACK, $location) );
241                         last;
242                 }
243
244                 my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
245                 if ($md5 eq $key) {
246                         ##
247                         # Found existing bucket with same key.  Replace with new value.
248                         ##
249                         $result = 1;
250                         
251                         if ($internal_ref) {
252                                 $location = $value->_base_offset;
253                                 seek($fh, $tag->{offset} + ($i * $BUCKET_SIZE) + $root->{file_offset}, SEEK_SET);
254                                 print( $fh $md5 . pack($LONG_PACK, $location) );
255                 return $result;
256                         }
257
258             seek($fh, $subloc + SIG_SIZE + $root->{file_offset}, SEEK_SET);
259             my $size;
260             read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
261             
262             ##
263             # If value is a hash, array, or raw value with equal or less size, we can
264             # reuse the same content area of the database.  Otherwise, we have to create
265             # a new content area at the EOF.
266             ##
267             my $actual_length;
268             my $r = Scalar::Util::reftype( $value ) || '';
269             if ( $r eq 'HASH' || $r eq 'ARRAY' ) {
270                 $actual_length = $INDEX_SIZE;
271                 
272                 # if autobless is enabled, must also take into consideration
273                 # the class name, as it is stored along with key/value.
274                 if ( $root->{autobless} ) {
275                     my $value_class = Scalar::Util::blessed($value);
276                     if ( defined $value_class && !$value->isa('DBM::Deep') ) {
277                         $actual_length += length($value_class);
278                     }
279                 }
280             }
281             else { $actual_length = length($value); }
282             
283             if ($actual_length <= $size) {
284                 $location = $subloc;
285             }
286             else {
287                 $location = $root->{end};
288                 seek($fh, $tag->{offset} + ($i * $BUCKET_SIZE) + $HASH_SIZE + $root->{file_offset}, SEEK_SET);
289                 print( $fh pack($LONG_PACK, $location) );
290             }
291
292                         last;
293                 }
294         }
295         
296         ##
297         # If this is an internal reference, return now.
298         # No need to write value or plain key
299         ##
300         if ($internal_ref) {
301         return $result;
302     }
303         
304         ##
305         # If bucket didn't fit into list, split into a new index level
306         ##
307         if (!$location) {
308                 seek($fh, $tag->{ref_loc} + $root->{file_offset}, SEEK_SET);
309                 print( $fh pack($LONG_PACK, $root->{end}) );
310                 
311                 my $index_tag = $self->{engine}->create_tag($self, $root->{end}, SIG_INDEX, chr(0) x $INDEX_SIZE);
312                 my @offsets = ();
313                 
314                 $keys .= $md5 . pack($LONG_PACK, 0);
315                 
316                 for (my $i=0; $i<=$MAX_BUCKETS; $i++) {
317                         my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
318                         if ($key) {
319                                 my $old_subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
320                                 my $num = ord(substr($key, $tag->{ch} + 1, 1));
321                                 
322                                 if ($offsets[$num]) {
323                                         my $offset = $offsets[$num] + SIG_SIZE + $DATA_LENGTH_SIZE;
324                                         seek($fh, $offset + $root->{file_offset}, SEEK_SET);
325                                         my $subkeys;
326                                         read( $fh, $subkeys, $BUCKET_LIST_SIZE);
327                                         
328                                         for (my $k=0; $k<$MAX_BUCKETS; $k++) {
329                                                 my $subloc = unpack($LONG_PACK, substr($subkeys, ($k * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
330                                                 if (!$subloc) {
331                                                         seek($fh, $offset + ($k * $BUCKET_SIZE) + $root->{file_offset}, SEEK_SET);
332                                                         print( $fh $key . pack($LONG_PACK, $old_subloc || $root->{end}) );
333                                                         last;
334                                                 }
335                                         } # k loop
336                                 }
337                                 else {
338                                         $offsets[$num] = $root->{end};
339                                         seek($fh, $index_tag->{offset} + ($num * $LONG_SIZE) + $root->{file_offset}, SEEK_SET);
340                                         print( $fh pack($LONG_PACK, $root->{end}) );
341                                         
342                                         my $blist_tag = $self->{engine}->create_tag($self, $root->{end}, SIG_BLIST, chr(0) x $BUCKET_LIST_SIZE);
343                                         
344                                         seek($fh, $blist_tag->{offset} + $root->{file_offset}, SEEK_SET);
345                                         print( $fh $key . pack($LONG_PACK, $old_subloc || $root->{end}) );
346                                 }
347                         } # key is real
348                 } # i loop
349                 
350                 $location ||= $root->{end};
351         } # re-index bucket list
352         
353         ##
354         # Seek to content area and store signature, value and plaintext key
355         ##
356         if ($location) {
357                 my $content_length;
358                 seek($fh, $location + $root->{file_offset}, SEEK_SET);
359                 
360                 ##
361                 # Write signature based on content type, set content length and write actual value.
362                 ##
363         my $r = Scalar::Util::reftype($value) || '';
364                 if ($r eq 'HASH') {
365                         print( $fh TYPE_HASH );
366                         print( $fh pack($DATA_LENGTH_PACK, $INDEX_SIZE) . chr(0) x $INDEX_SIZE );
367                         $content_length = $INDEX_SIZE;
368                 }
369                 elsif ($r eq 'ARRAY') {
370                         print( $fh TYPE_ARRAY );
371                         print( $fh pack($DATA_LENGTH_PACK, $INDEX_SIZE) . chr(0) x $INDEX_SIZE );
372                         $content_length = $INDEX_SIZE;
373                 }
374                 elsif (!defined($value)) {
375                         print( $fh SIG_NULL );
376                         print( $fh pack($DATA_LENGTH_PACK, 0) );
377                         $content_length = 0;
378                 }
379                 else {
380                         print( $fh SIG_DATA );
381                         print( $fh pack($DATA_LENGTH_PACK, length($value)) . $value );
382                         $content_length = length($value);
383                 }
384                 
385                 ##
386                 # Plain key is stored AFTER value, as keys are typically fetched less often.
387                 ##
388                 print( $fh pack($DATA_LENGTH_PACK, length($plain_key)) . $plain_key );
389                 
390                 ##
391                 # If value is blessed, preserve class name
392                 ##
393                 if ( $root->{autobless} ) {
394             my $value_class = Scalar::Util::blessed($value);
395             if ( defined $value_class && $value_class ne 'DBM::Deep' ) {
396                 ##
397                 # Blessed ref -- will restore later
398                 ##
399                 print( $fh chr(1) );
400                 print( $fh pack($DATA_LENGTH_PACK, length($value_class)) . $value_class );
401                 $content_length += 1;
402                 $content_length += $DATA_LENGTH_SIZE + length($value_class);
403             }
404             else {
405                 print( $fh chr(0) );
406                 $content_length += 1;
407             }
408         }
409             
410                 ##
411                 # If this is a new content area, advance EOF counter
412                 ##
413                 if ($location == $root->{end}) {
414                         $root->{end} += SIG_SIZE;
415                         $root->{end} += $DATA_LENGTH_SIZE + $content_length;
416                         $root->{end} += $DATA_LENGTH_SIZE + length($plain_key);
417                 }
418                 
419                 ##
420                 # If content is a hash or array, create new child DBM::Deep object and
421                 # pass each key or element to it.
422                 ##
423                 if ($r eq 'HASH') {
424                         my $branch = DBM::Deep->new(
425                                 type => TYPE_HASH,
426                                 base_offset => $location,
427                                 root => $root,
428                         );
429                         foreach my $key (keys %{$value}) {
430                 $branch->STORE( $key, $value->{$key} );
431                         }
432                 }
433                 elsif ($r eq 'ARRAY') {
434                         my $branch = DBM::Deep->new(
435                                 type => TYPE_ARRAY,
436                                 base_offset => $location,
437                                 root => $root,
438                         );
439                         my $index = 0;
440                         foreach my $element (@{$value}) {
441                 $branch->STORE( $index, $element );
442                                 $index++;
443                         }
444                 }
445                 
446                 return $result;
447         }
448         
449         return $self->_throw_error("Fatal error: indexing failed -- possibly due to corruption in file");
450 }
451
452 sub _get_bucket_value {
453         ##
454         # Fetch single value given tag and MD5 digested key.
455         ##
456         my $self = shift;
457         my ($tag, $md5) = @_;
458         my $keys = $tag->{content};
459
460     my $fh = $self->_fh;
461
462         ##
463         # Iterate through buckets, looking for a key match
464         ##
465     BUCKET:
466         for (my $i=0; $i<$MAX_BUCKETS; $i++) {
467                 my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
468                 my $subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
469
470                 if (!$subloc) {
471                         ##
472                         # Hit end of list, no match
473                         ##
474                         return;
475                 }
476
477         if ( $md5 ne $key ) {
478             next BUCKET;
479         }
480
481         ##
482         # Found match -- seek to offset and read signature
483         ##
484         my $signature;
485         seek($fh, $subloc + $self->_root->{file_offset}, SEEK_SET);
486         read( $fh, $signature, SIG_SIZE);
487         
488         ##
489         # If value is a hash or array, return new DBM::Deep object with correct offset
490         ##
491         if (($signature eq TYPE_HASH) || ($signature eq TYPE_ARRAY)) {
492             my $obj = DBM::Deep->new(
493                 type => $signature,
494                 base_offset => $subloc,
495                 root => $self->_root
496             );
497             
498             if ($self->_root->{autobless}) {
499                 ##
500                 # Skip over value and plain key to see if object needs
501                 # to be re-blessed
502                 ##
503                 seek($fh, $DATA_LENGTH_SIZE + $INDEX_SIZE, SEEK_CUR);
504                 
505                 my $size;
506                 read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
507                 if ($size) { seek($fh, $size, SEEK_CUR); }
508                 
509                 my $bless_bit;
510                 read( $fh, $bless_bit, 1);
511                 if (ord($bless_bit)) {
512                     ##
513                     # Yes, object needs to be re-blessed
514                     ##
515                     my $class_name;
516                     read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
517                     if ($size) { read( $fh, $class_name, $size); }
518                     if ($class_name) { $obj = bless( $obj, $class_name ); }
519                 }
520             }
521             
522             return $obj;
523         }
524         
525         ##
526         # Otherwise return actual value
527         ##
528         elsif ($signature eq SIG_DATA) {
529             my $size;
530             my $value = '';
531             read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
532             if ($size) { read( $fh, $value, $size); }
533             return $value;
534         }
535         
536         ##
537         # Key exists, but content is null
538         ##
539         else { return; }
540         } # i loop
541
542         return;
543 }
544
545 sub _delete_bucket {
546         ##
547         # Delete single key/value pair given tag and MD5 digested key.
548         ##
549         my $self = shift;
550         my ($tag, $md5) = @_;
551         my $keys = $tag->{content};
552
553     my $fh = $self->_fh;
554         
555         ##
556         # Iterate through buckets, looking for a key match
557         ##
558     BUCKET:
559         for (my $i=0; $i<$MAX_BUCKETS; $i++) {
560                 my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
561                 my $subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
562
563                 if (!$subloc) {
564                         ##
565                         # Hit end of list, no match
566                         ##
567                         return;
568                 }
569
570         if ( $md5 ne $key ) {
571             next BUCKET;
572         }
573
574         ##
575         # Matched key -- delete bucket and return
576         ##
577         seek($fh, $tag->{offset} + ($i * $BUCKET_SIZE) + $self->_root->{file_offset}, SEEK_SET);
578         print( $fh substr($keys, ($i+1) * $BUCKET_SIZE ) );
579         print( $fh chr(0) x $BUCKET_SIZE );
580         
581         return 1;
582         } # i loop
583
584         return;
585 }
586
587 sub _bucket_exists {
588         ##
589         # Check existence of single key given tag and MD5 digested key.
590         ##
591         my $self = shift;
592         my ($tag, $md5) = @_;
593         my $keys = $tag->{content};
594         
595         ##
596         # Iterate through buckets, looking for a key match
597         ##
598     BUCKET:
599         for (my $i=0; $i<$MAX_BUCKETS; $i++) {
600                 my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
601                 my $subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
602
603                 if (!$subloc) {
604                         ##
605                         # Hit end of list, no match
606                         ##
607                         return;
608                 }
609
610         if ( $md5 ne $key ) {
611             next BUCKET;
612         }
613
614         ##
615         # Matched key -- return true
616         ##
617         return 1;
618         } # i loop
619
620         return;
621 }
622
623 sub _find_bucket_list {
624         ##
625         # Locate offset for bucket list, given digested key
626         ##
627         my $self = shift;
628         my $md5 = shift;
629         
630         ##
631         # Locate offset for bucket list using digest index system
632         ##
633         my $ch = 0;
634         my $tag = $self->{engine}->load_tag($self, $self->_base_offset);
635         if (!$tag) { return; }
636         
637         while ($tag->{signature} ne SIG_BLIST) {
638                 $tag = $self->{engine}->index_lookup($self, $tag, ord(substr($md5, $ch, 1)));
639                 if (!$tag) { return; }
640                 $ch++;
641         }
642         
643         return $tag;
644 }
645
646 sub _traverse_index {
647         ##
648         # Scan index and recursively step into deeper levels, looking for next key.
649         ##
650     my ($self, $offset, $ch, $force_return_next) = @_;
651     $force_return_next = undef unless $force_return_next;
652         
653         my $tag = $self->{engine}->load_tag($self,  $offset );
654
655     my $fh = $self->_fh;
656         
657         if ($tag->{signature} ne SIG_BLIST) {
658                 my $content = $tag->{content};
659                 my $start;
660                 if ($self->{return_next}) { $start = 0; }
661                 else { $start = ord(substr($self->{prev_md5}, $ch, 1)); }
662                 
663                 for (my $index = $start; $index < 256; $index++) {
664                         my $subloc = unpack($LONG_PACK, substr($content, $index * $LONG_SIZE, $LONG_SIZE) );
665                         if ($subloc) {
666                                 my $result = $self->_traverse_index( $subloc, $ch + 1, $force_return_next );
667                                 if (defined($result)) { return $result; }
668                         }
669                 } # index loop
670                 
671                 $self->{return_next} = 1;
672         } # tag is an index
673         
674         elsif ($tag->{signature} eq SIG_BLIST) {
675                 my $keys = $tag->{content};
676                 if ($force_return_next) { $self->{return_next} = 1; }
677                 
678                 ##
679                 # Iterate through buckets, looking for a key match
680                 ##
681                 for (my $i=0; $i<$MAX_BUCKETS; $i++) {
682                         my $key = substr($keys, $i * $BUCKET_SIZE, $HASH_SIZE);
683                         my $subloc = unpack($LONG_PACK, substr($keys, ($i * $BUCKET_SIZE) + $HASH_SIZE, $LONG_SIZE));
684         
685                         if (!$subloc) {
686                                 ##
687                                 # End of bucket list -- return to outer loop
688                                 ##
689                                 $self->{return_next} = 1;
690                                 last;
691                         }
692                         elsif ($key eq $self->{prev_md5}) {
693                                 ##
694                                 # Located previous key -- return next one found
695                                 ##
696                                 $self->{return_next} = 1;
697                                 next;
698                         }
699                         elsif ($self->{return_next}) {
700                                 ##
701                                 # Seek to bucket location and skip over signature
702                                 ##
703                                 seek($fh, $subloc + SIG_SIZE + $self->_root->{file_offset}, SEEK_SET);
704                                 
705                                 ##
706                                 # Skip over value to get to plain key
707                                 ##
708                                 my $size;
709                                 read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
710                                 if ($size) { seek($fh, $size, SEEK_CUR); }
711                                 
712                                 ##
713                                 # Read in plain key and return as scalar
714                                 ##
715                                 my $plain_key;
716                                 read( $fh, $size, $DATA_LENGTH_SIZE); $size = unpack($DATA_LENGTH_PACK, $size);
717                                 if ($size) { read( $fh, $plain_key, $size); }
718                                 
719                                 return $plain_key;
720                         }
721                 } # bucket loop
722                 
723                 $self->{return_next} = 1;
724         } # tag is a bucket list
725         
726         return;
727 }
728
729 sub _get_next_key {
730         ##
731         # Locate next key, given digested previous one
732         ##
733     my $self = $_[0]->_get_self;
734         
735         $self->{prev_md5} = $_[1] ? $_[1] : undef;
736         $self->{return_next} = 0;
737         
738         ##
739         # If the previous key was not specifed, start at the top and
740         # return the first one found.
741         ##
742         if (!$self->{prev_md5}) {
743                 $self->{prev_md5} = chr(0) x $HASH_SIZE;
744                 $self->{return_next} = 1;
745         }
746         
747         return $self->_traverse_index( $self->_base_offset, 0 );
748 }
749
750 sub lock {
751         ##
752         # If db locking is set, flock() the db file.  If called multiple
753         # times before unlock(), then the same number of unlocks() must
754         # be called before the lock is released.
755         ##
756     my $self = $_[0]->_get_self;
757         my $type = $_[1];
758     $type = LOCK_EX unless defined $type;
759         
760         if (!defined($self->_fh)) { return; }
761
762         if ($self->_root->{locking}) {
763                 if (!$self->_root->{locked}) {
764                         flock($self->_fh, $type);
765                         
766                         # refresh end counter in case file has changed size
767                         my @stats = stat($self->_root->{file});
768                         $self->_root->{end} = $stats[7];
769                         
770                         # double-check file inode, in case another process
771                         # has optimize()d our file while we were waiting.
772                         if ($stats[1] != $self->_root->{inode}) {
773                                 $self->{engine}->open( $self ); # re-open
774                                 flock($self->_fh, $type); # re-lock
775                                 $self->_root->{end} = (stat($self->_fh))[7]; # re-end
776                         }
777                 }
778                 $self->_root->{locked}++;
779
780         return 1;
781         }
782
783     return;
784 }
785
786 sub unlock {
787         ##
788         # If db locking is set, unlock the db file.  See note in lock()
789         # regarding calling lock() multiple times.
790         ##
791     my $self = $_[0]->_get_self;
792
793         if (!defined($self->_fh)) { return; }
794         
795         if ($self->_root->{locking} && $self->_root->{locked} > 0) {
796                 $self->_root->{locked}--;
797                 if (!$self->_root->{locked}) { flock($self->_fh, LOCK_UN); }
798
799         return 1;
800         }
801
802     return;
803 }
804
805 sub _copy_value {
806     my $self = shift->_get_self;
807     my ($spot, $value) = @_;
808
809     if ( !ref $value ) {
810         ${$spot} = $value;
811     }
812     elsif ( eval { local $SIG{__DIE__}; $value->isa( 'DBM::Deep' ) } ) {
813         my $type = $value->_type;
814         ${$spot} = $type eq TYPE_HASH ? {} : [];
815         $value->_copy_node( ${$spot} );
816     }
817     else {
818         my $r = Scalar::Util::reftype( $value );
819         my $c = Scalar::Util::blessed( $value );
820         if ( $r eq 'ARRAY' ) {
821             ${$spot} = [ @{$value} ];
822         }
823         else {
824             ${$spot} = { %{$value} };
825         }
826         ${$spot} = bless ${$spot}, $c
827             if defined $c;
828     }
829
830     return 1;
831 }
832
833 sub _copy_node {
834         ##
835         # Copy single level of keys or elements to new DB handle.
836         # Recurse for nested structures
837         ##
838     my $self = shift->_get_self;
839         my ($db_temp) = @_;
840
841         if ($self->_type eq TYPE_HASH) {
842                 my $key = $self->first_key();
843                 while ($key) {
844                         my $value = $self->get($key);
845             $self->_copy_value( \$db_temp->{$key}, $value );
846                         $key = $self->next_key($key);
847                 }
848         }
849         else {
850                 my $length = $self->length();
851                 for (my $index = 0; $index < $length; $index++) {
852                         my $value = $self->get($index);
853             $self->_copy_value( \$db_temp->[$index], $value );
854                 }
855         }
856
857     return 1;
858 }
859
860 sub export {
861         ##
862         # Recursively export into standard Perl hashes and arrays.
863         ##
864     my $self = $_[0]->_get_self;
865         
866         my $temp;
867         if ($self->_type eq TYPE_HASH) { $temp = {}; }
868         elsif ($self->_type eq TYPE_ARRAY) { $temp = []; }
869         
870         $self->lock();
871         $self->_copy_node( $temp );
872         $self->unlock();
873         
874         return $temp;
875 }
876
877 sub import {
878         ##
879         # Recursively import Perl hash/array structure
880         ##
881     #XXX This use of ref() seems to be ok
882         if (!ref($_[0])) { return; } # Perl calls import() on use -- ignore
883         
884     my $self = $_[0]->_get_self;
885         my $struct = $_[1];
886         
887     #XXX This use of ref() seems to be ok
888         if (!ref($struct)) {
889                 ##
890                 # struct is not a reference, so just import based on our type
891                 ##
892                 shift @_;
893                 
894                 if ($self->_type eq TYPE_HASH) { $struct = {@_}; }
895                 elsif ($self->_type eq TYPE_ARRAY) { $struct = [@_]; }
896         }
897         
898     my $r = Scalar::Util::reftype($struct) || '';
899         if ($r eq "HASH" && $self->_type eq TYPE_HASH) {
900                 foreach my $key (keys %$struct) { $self->put($key, $struct->{$key}); }
901         }
902         elsif ($r eq "ARRAY" && $self->_type eq TYPE_ARRAY) {
903                 $self->push( @$struct );
904         }
905         else {
906                 return $self->_throw_error("Cannot import: type mismatch");
907         }
908         
909         return 1;
910 }
911
912 sub optimize {
913         ##
914         # Rebuild entire database into new file, then move
915         # it back on top of original.
916         ##
917     my $self = $_[0]->_get_self;
918
919 #XXX Need to create a new test for this
920 #       if ($self->_root->{links} > 1) {
921 #               return $self->_throw_error("Cannot optimize: reference count is greater than 1");
922 #       }
923         
924         my $db_temp = DBM::Deep->new(
925                 file => $self->_root->{file} . '.tmp',
926                 type => $self->_type
927         );
928         if (!$db_temp) {
929                 return $self->_throw_error("Cannot optimize: failed to open temp file: $!");
930         }
931         
932         $self->lock();
933         $self->_copy_node( $db_temp );
934         undef $db_temp;
935         
936         ##
937         # Attempt to copy user, group and permissions over to new file
938         ##
939         my @stats = stat($self->_fh);
940         my $perms = $stats[2] & 07777;
941         my $uid = $stats[4];
942         my $gid = $stats[5];
943         chown( $uid, $gid, $self->_root->{file} . '.tmp' );
944         chmod( $perms, $self->_root->{file} . '.tmp' );
945         
946     # q.v. perlport for more information on this variable
947     if ( $^O eq 'MSWin32' || $^O eq 'cygwin' ) {
948                 ##
949                 # Potential race condition when optmizing on Win32 with locking.
950                 # The Windows filesystem requires that the filehandle be closed 
951                 # before it is overwritten with rename().  This could be redone
952                 # with a soft copy.
953                 ##
954                 $self->unlock();
955                 $self->{engine}->close( $self );
956         }
957         
958         if (!rename $self->_root->{file} . '.tmp', $self->_root->{file}) {
959                 unlink $self->_root->{file} . '.tmp';
960                 $self->unlock();
961                 return $self->_throw_error("Optimize failed: Cannot copy temp file over original: $!");
962         }
963         
964         $self->unlock();
965         $self->{engine}->close( $self );
966         $self->{engine}->open( $self );
967         
968         return 1;
969 }
970
971 sub clone {
972         ##
973         # Make copy of object and return
974         ##
975     my $self = $_[0]->_get_self;
976         
977         return DBM::Deep->new(
978                 type => $self->_type,
979                 base_offset => $self->_base_offset,
980                 root => $self->_root
981         );
982 }
983
984 {
985     my %is_legal_filter = map {
986         $_ => ~~1,
987     } qw(
988         store_key store_value
989         fetch_key fetch_value
990     );
991
992     sub set_filter {
993         ##
994         # Setup filter function for storing or fetching the key or value
995         ##
996         my $self = $_[0]->_get_self;
997         my $type = lc $_[1];
998         my $func = $_[2] ? $_[2] : undef;
999         
1000         if ( $is_legal_filter{$type} ) {
1001             $self->_root->{"filter_$type"} = $func;
1002             return 1;
1003         }
1004
1005         return;
1006     }
1007 }
1008
1009 ##
1010 # Accessor methods
1011 ##
1012
1013 sub _root {
1014         ##
1015         # Get access to the root structure
1016         ##
1017     my $self = $_[0]->_get_self;
1018         return $self->{root};
1019 }
1020
1021 sub _fh {
1022         ##
1023         # Get access to the raw fh
1024         ##
1025     #XXX It will be useful, though, when we split out HASH and ARRAY
1026     my $self = $_[0]->_get_self;
1027         return $self->_root->{fh};
1028 }
1029
1030 sub _type {
1031         ##
1032         # Get type of current node (TYPE_HASH or TYPE_ARRAY)
1033         ##
1034     my $self = $_[0]->_get_self;
1035         return $self->{type};
1036 }
1037
1038 sub _base_offset {
1039         ##
1040         # Get base_offset of current node (TYPE_HASH or TYPE_ARRAY)
1041         ##
1042     my $self = $_[0]->_get_self;
1043         return $self->{base_offset};
1044 }
1045
1046 ##
1047 # Utility methods
1048 ##
1049
1050 sub _throw_error {
1051     die "DBM::Deep: $_[1]\n";
1052 }
1053
1054 sub _precalc_sizes {
1055         ##
1056         # Precalculate index, bucket and bucket list sizes
1057         ##
1058
1059     #XXX I don't like this ...
1060     set_pack() unless defined $LONG_SIZE;
1061
1062         $INDEX_SIZE = 256 * $LONG_SIZE;
1063         $BUCKET_SIZE = $HASH_SIZE + $LONG_SIZE;
1064         $BUCKET_LIST_SIZE = $MAX_BUCKETS * $BUCKET_SIZE;
1065 }
1066
1067 sub set_pack {
1068         ##
1069         # Set pack/unpack modes (see file header for more)
1070         ##
1071     my ($long_s, $long_p, $data_s, $data_p) = @_;
1072
1073     $LONG_SIZE = $long_s ? $long_s : 4;
1074     $LONG_PACK = $long_p ? $long_p : 'N';
1075
1076     $DATA_LENGTH_SIZE = $data_s ? $data_s : 4;
1077     $DATA_LENGTH_PACK = $data_p ? $data_p : 'N';
1078
1079         _precalc_sizes();
1080 }
1081
1082 sub set_digest {
1083         ##
1084         # Set key digest function (default is MD5)
1085         ##
1086     my ($digest_func, $hash_size) = @_;
1087
1088     $DIGEST_FUNC = $digest_func ? $digest_func : \&Digest::MD5::md5;
1089     $HASH_SIZE = $hash_size ? $hash_size : 16;
1090
1091         _precalc_sizes();
1092 }
1093
1094 sub _is_writable {
1095     my $fh = shift;
1096     (O_WRONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush = 0);
1097 }
1098
1099 #sub _is_readable {
1100 #    my $fh = shift;
1101 #    (O_RDONLY | O_RDWR) & fcntl( $fh, F_GETFL, my $slush = 0);
1102 #}
1103
1104 ##
1105 # tie() methods (hashes and arrays)
1106 ##
1107
1108 sub STORE {
1109         ##
1110         # Store single hash key/value or array element in database.
1111         ##
1112     my $self = $_[0]->_get_self;
1113         my $key = $_[1];
1114
1115     # User may be storing a hash, in which case we do not want it run 
1116     # through the filtering system
1117         my $value = ($self->_root->{filter_store_value} && !ref($_[2]))
1118         ? $self->_root->{filter_store_value}->($_[2])
1119         : $_[2];
1120         
1121         my $md5 = $DIGEST_FUNC->($key);
1122         
1123     unless ( _is_writable( $self->_fh ) ) {
1124         $self->_throw_error( 'Cannot write to a readonly filehandle' );
1125     }
1126         
1127         ##
1128         # Request exclusive lock for writing
1129         ##
1130         $self->lock( LOCK_EX );
1131         
1132         my $fh = $self->_fh;
1133         
1134         ##
1135         # Locate offset for bucket list using digest index system
1136         ##
1137         my $tag = $self->{engine}->load_tag($self, $self->_base_offset);
1138         if (!$tag) {
1139                 $tag = $self->{engine}->create_tag($self, $self->_base_offset, SIG_INDEX, chr(0) x $INDEX_SIZE);
1140         }
1141         
1142         my $ch = 0;
1143         while ($tag->{signature} ne SIG_BLIST) {
1144                 my $num = ord(substr($md5, $ch, 1));
1145
1146         my $ref_loc = $tag->{offset} + ($num * $LONG_SIZE);
1147                 my $new_tag = $self->{engine}->index_lookup($self, $tag, $num);
1148
1149                 if (!$new_tag) {
1150                         seek($fh, $ref_loc + $self->_root->{file_offset}, SEEK_SET);
1151                         print( $fh pack($LONG_PACK, $self->_root->{end}) );
1152                         
1153                         $tag = $self->{engine}->create_tag($self, $self->_root->{end}, SIG_BLIST, chr(0) x $BUCKET_LIST_SIZE);
1154
1155                         $tag->{ref_loc} = $ref_loc;
1156                         $tag->{ch} = $ch;
1157
1158                         last;
1159                 }
1160                 else {
1161                         $tag = $new_tag;
1162
1163                         $tag->{ref_loc} = $ref_loc;
1164                         $tag->{ch} = $ch;
1165                 }
1166                 $ch++;
1167         }
1168         
1169         ##
1170         # Add key/value to bucket list
1171         ##
1172         my $result = $self->_add_bucket( $tag, $md5, $key, $value );
1173         
1174         $self->unlock();
1175
1176         return $result;
1177 }
1178
1179 sub FETCH {
1180         ##
1181         # Fetch single value or element given plain key or array index
1182         ##
1183     my $self = shift->_get_self;
1184     my $key = shift;
1185
1186         my $md5 = $DIGEST_FUNC->($key);
1187
1188         ##
1189         # Request shared lock for reading
1190         ##
1191         $self->lock( LOCK_SH );
1192         
1193         my $tag = $self->_find_bucket_list( $md5 );
1194         if (!$tag) {
1195                 $self->unlock();
1196                 return;
1197         }
1198         
1199         ##
1200         # Get value from bucket list
1201         ##
1202         my $result = $self->_get_bucket_value( $tag, $md5 );
1203         
1204         $self->unlock();
1205         
1206     #XXX What is ref() checking here?
1207     #YYY Filters only apply on scalar values, so the ref check is making
1208     #YYY sure the fetched bucket is a scalar, not a child hash or array.
1209         return ($result && !ref($result) && $self->_root->{filter_fetch_value})
1210         ? $self->_root->{filter_fetch_value}->($result)
1211         : $result;
1212 }
1213
1214 sub DELETE {
1215         ##
1216         # Delete single key/value pair or element given plain key or array index
1217         ##
1218     my $self = $_[0]->_get_self;
1219         my $key = $_[1];
1220         
1221         my $md5 = $DIGEST_FUNC->($key);
1222
1223         ##
1224         # Request exclusive lock for writing
1225         ##
1226         $self->lock( LOCK_EX );
1227         
1228         my $tag = $self->_find_bucket_list( $md5 );
1229         if (!$tag) {
1230                 $self->unlock();
1231                 return;
1232         }
1233         
1234         ##
1235         # Delete bucket
1236         ##
1237     my $value = $self->_get_bucket_value( $tag, $md5 );
1238         if ($value && !ref($value) && $self->_root->{filter_fetch_value}) {
1239         $value = $self->_root->{filter_fetch_value}->($value);
1240     }
1241
1242         my $result = $self->_delete_bucket( $tag, $md5 );
1243         
1244         ##
1245         # If this object is an array and the key deleted was on the end of the stack,
1246         # decrement the length variable.
1247         ##
1248         
1249         $self->unlock();
1250         
1251         return $value;
1252 }
1253
1254 sub EXISTS {
1255         ##
1256         # Check if a single key or element exists given plain key or array index
1257         ##
1258     my $self = $_[0]->_get_self;
1259         my $key = $_[1];
1260         
1261         my $md5 = $DIGEST_FUNC->($key);
1262
1263         ##
1264         # Request shared lock for reading
1265         ##
1266         $self->lock( LOCK_SH );
1267         
1268         my $tag = $self->_find_bucket_list( $md5 );
1269         
1270         ##
1271         # For some reason, the built-in exists() function returns '' for false
1272         ##
1273         if (!$tag) {
1274                 $self->unlock();
1275                 return '';
1276         }
1277         
1278         ##
1279         # Check if bucket exists and return 1 or ''
1280         ##
1281         my $result = $self->_bucket_exists( $tag, $md5 ) || '';
1282         
1283         $self->unlock();
1284         
1285         return $result;
1286 }
1287
1288 sub CLEAR {
1289         ##
1290         # Clear all keys from hash, or all elements from array.
1291         ##
1292     my $self = $_[0]->_get_self;
1293
1294         ##
1295         # Request exclusive lock for writing
1296         ##
1297         $self->lock( LOCK_EX );
1298         
1299     my $fh = $self->_fh;
1300
1301         seek($fh, $self->_base_offset + $self->_root->{file_offset}, SEEK_SET);
1302         if (eof $fh) {
1303                 $self->unlock();
1304                 return;
1305         }
1306         
1307         $self->{engine}->create_tag($self, $self->_base_offset, $self->_type, chr(0) x $INDEX_SIZE);
1308         
1309         $self->unlock();
1310         
1311         return 1;
1312 }
1313
1314 ##
1315 # Public method aliases
1316 ##
1317 sub put { (shift)->STORE( @_ ) }
1318 sub store { (shift)->STORE( @_ ) }
1319 sub get { (shift)->FETCH( @_ ) }
1320 sub fetch { (shift)->FETCH( @_ ) }
1321 sub delete { (shift)->DELETE( @_ ) }
1322 sub exists { (shift)->EXISTS( @_ ) }
1323 sub clear { (shift)->CLEAR( @_ ) }
1324
1325 package DBM::Deep::_::Root;
1326
1327 sub new {
1328     my $class = shift;
1329     my ($args) = @_;
1330
1331     my $self = bless {
1332         file => undef,
1333         fh => undef,
1334         file_offset => 0,
1335         end => 0,
1336         autoflush => undef,
1337         locking => undef,
1338         debug => undef,
1339         filter_store_key => undef,
1340         filter_store_value => undef,
1341         filter_fetch_key => undef,
1342         filter_fetch_value => undef,
1343         autobless => undef,
1344         locked => 0,
1345         %$args,
1346     }, $class;
1347
1348     if ( $self->{fh} && !$self->{file_offset} ) {
1349         $self->{file_offset} = tell( $self->{fh} );
1350     }
1351
1352     return $self;
1353 }
1354
1355 sub DESTROY {
1356     my $self = shift;
1357     return unless $self;
1358
1359     close $self->{fh} if $self->{fh};
1360
1361     return;
1362 }
1363
1364 1;
1365
1366 __END__
1367
1368 =head1 NAME
1369
1370 DBM::Deep - A pure perl multi-level hash/array DBM
1371
1372 =head1 SYNOPSIS
1373
1374   use DBM::Deep;
1375   my $db = DBM::Deep->new( "foo.db" );
1376   
1377   $db->{key} = 'value'; # tie() style
1378   print $db->{key};
1379   
1380   $db->put('key' => 'value'); # OO style
1381   print $db->get('key');
1382   
1383   # true multi-level support
1384   $db->{my_complex} = [
1385         'hello', { perl => 'rules' }, 
1386         42, 99,
1387   ];
1388
1389 =head1 DESCRIPTION
1390
1391 A unique flat-file database module, written in pure perl.  True 
1392 multi-level hash/array support (unlike MLDBM, which is faked), hybrid 
1393 OO / tie() interface, cross-platform FTPable files, and quite fast.  Can 
1394 handle millions of keys and unlimited hash levels without significant 
1395 slow-down.  Written from the ground-up in pure perl -- this is NOT a 
1396 wrapper around a C-based DBM.  Out-of-the-box compatibility with Unix, 
1397 Mac OS X and Windows.
1398
1399 =head1 INSTALLATION
1400
1401 Hopefully you are using Perl's excellent CPAN module, which will download
1402 and install the module for you.  If not, get the tarball, and run these 
1403 commands:
1404
1405         tar zxf DBM-Deep-*
1406         cd DBM-Deep-*
1407         perl Makefile.PL
1408         make
1409         make test
1410         make install
1411
1412 =head1 SETUP
1413
1414 Construction can be done OO-style (which is the recommended way), or using 
1415 Perl's tie() function.  Both are examined here.
1416
1417 =head2 OO CONSTRUCTION
1418
1419 The recommended way to construct a DBM::Deep object is to use the new()
1420 method, which gets you a blessed, tied hash or array reference.
1421
1422         my $db = DBM::Deep->new( "foo.db" );
1423
1424 This opens a new database handle, mapped to the file "foo.db".  If this
1425 file does not exist, it will automatically be created.  DB files are 
1426 opened in "r+" (read/write) mode, and the type of object returned is a
1427 hash, unless otherwise specified (see L<OPTIONS> below).
1428
1429 You can pass a number of options to the constructor to specify things like
1430 locking, autoflush, etc.  This is done by passing an inline hash:
1431
1432         my $db = DBM::Deep->new(
1433                 file => "foo.db",
1434                 locking => 1,
1435                 autoflush => 1
1436         );
1437
1438 Notice that the filename is now specified I<inside> the hash with
1439 the "file" parameter, as opposed to being the sole argument to the 
1440 constructor.  This is required if any options are specified.
1441 See L<OPTIONS> below for the complete list.
1442
1443
1444
1445 You can also start with an array instead of a hash.  For this, you must
1446 specify the C<type> parameter:
1447
1448         my $db = DBM::Deep->new(
1449                 file => "foo.db",
1450                 type => DBM::Deep->TYPE_ARRAY
1451         );
1452
1453 B<Note:> Specifing the C<type> parameter only takes effect when beginning
1454 a new DB file.  If you create a DBM::Deep object with an existing file, the
1455 C<type> will be loaded from the file header, and an error will be thrown if
1456 the wrong type is passed in.
1457
1458 =head2 TIE CONSTRUCTION
1459
1460 Alternately, you can create a DBM::Deep handle by using Perl's built-in
1461 tie() function.  The object returned from tie() can be used to call methods,
1462 such as lock() and unlock(), but cannot be used to assign to the DBM::Deep
1463 file (as expected with most tie'd objects).
1464
1465         my %hash;
1466         my $db = tie %hash, "DBM::Deep", "foo.db";
1467         
1468         my @array;
1469         my $db = tie @array, "DBM::Deep", "bar.db";
1470
1471 As with the OO constructor, you can replace the DB filename parameter with
1472 a hash containing one or more options (see L<OPTIONS> just below for the
1473 complete list).
1474
1475         tie %hash, "DBM::Deep", {
1476                 file => "foo.db",
1477                 locking => 1,
1478                 autoflush => 1
1479         };
1480
1481 =head2 OPTIONS
1482
1483 There are a number of options that can be passed in when constructing your
1484 DBM::Deep objects.  These apply to both the OO- and tie- based approaches.
1485
1486 =over
1487
1488 =item * file
1489
1490 Filename of the DB file to link the handle to.  You can pass a full absolute
1491 filesystem path, partial path, or a plain filename if the file is in the 
1492 current working directory.  This is a required parameter (though q.v. fh).
1493
1494 =item * fh
1495
1496 If you want, you can pass in the fh instead of the file. This is most useful for doing
1497 something like:
1498
1499   my $db = DBM::Deep->new( { fh => \*DATA } );
1500
1501 You are responsible for making sure that the fh has been opened appropriately for your
1502 needs. If you open it read-only and attempt to write, an exception will be thrown. If you
1503 open it write-only or append-only, an exception will be thrown immediately as DBM::Deep
1504 needs to read from the fh.
1505
1506 =item * file_offset
1507
1508 This is the offset within the file that the DBM::Deep db starts. Most of the time, you will
1509 not need to set this. However, it's there if you want it.
1510
1511 If you pass in fh and do not set this, it will be set appropriately.
1512
1513 =item * type
1514
1515 This parameter specifies what type of object to create, a hash or array.  Use
1516 one of these two constants: C<DBM::Deep-E<gt>TYPE_HASH> or C<DBM::Deep-E<gt>TYPE_ARRAY>.
1517 This only takes effect when beginning a new file.  This is an optional 
1518 parameter, and defaults to C<DBM::Deep-E<gt>TYPE_HASH>.
1519
1520 =item * locking
1521
1522 Specifies whether locking is to be enabled.  DBM::Deep uses Perl's Fnctl flock()
1523 function to lock the database in exclusive mode for writes, and shared mode for
1524 reads.  Pass any true value to enable.  This affects the base DB handle I<and 
1525 any child hashes or arrays> that use the same DB file.  This is an optional 
1526 parameter, and defaults to 0 (disabled).  See L<LOCKING> below for more.
1527
1528 =item * autoflush
1529
1530 Specifies whether autoflush is to be enabled on the underlying filehandle.  
1531 This obviously slows down write operations, but is required if you may have 
1532 multiple processes accessing the same DB file (also consider enable I<locking>).  
1533 Pass any true value to enable.  This is an optional parameter, and defaults to 0 
1534 (disabled).
1535
1536 =item * autobless
1537
1538 If I<autobless> mode is enabled, DBM::Deep will preserve blessed hashes, and
1539 restore them when fetched.  This is an B<experimental> feature, and does have
1540 side-effects.  Basically, when hashes are re-blessed into their original
1541 classes, they are no longer blessed into the DBM::Deep class!  So you won't be
1542 able to call any DBM::Deep methods on them.  You have been warned.
1543 This is an optional parameter, and defaults to 0 (disabled).
1544
1545 =item * filter_*
1546
1547 See L<FILTERS> below.
1548
1549 =item * debug
1550
1551 Setting I<debug> mode will make all errors non-fatal, dump them out to
1552 STDERR, and continue on.  This is for debugging purposes only, and probably
1553 not what you want.  This is an optional parameter, and defaults to 0 (disabled).
1554
1555 B<NOTE>: This parameter is considered deprecated and should not be used anymore.
1556
1557 =back
1558
1559 =head1 TIE INTERFACE
1560
1561 With DBM::Deep you can access your databases using Perl's standard hash/array
1562 syntax.  Because all DBM::Deep objects are I<tied> to hashes or arrays, you can
1563 treat them as such.  DBM::Deep will intercept all reads/writes and direct them
1564 to the right place -- the DB file.  This has nothing to do with the
1565 L<TIE CONSTRUCTION> section above.  This simply tells you how to use DBM::Deep
1566 using regular hashes and arrays, rather than calling functions like C<get()>
1567 and C<put()> (although those work too).  It is entirely up to you how to want
1568 to access your databases.
1569
1570 =head2 HASHES
1571
1572 You can treat any DBM::Deep object like a normal Perl hash reference.  Add keys,
1573 or even nested hashes (or arrays) using standard Perl syntax:
1574
1575         my $db = DBM::Deep->new( "foo.db" );
1576         
1577         $db->{mykey} = "myvalue";
1578         $db->{myhash} = {};
1579         $db->{myhash}->{subkey} = "subvalue";
1580
1581         print $db->{myhash}->{subkey} . "\n";
1582
1583 You can even step through hash keys using the normal Perl C<keys()> function:
1584
1585         foreach my $key (keys %$db) {
1586                 print "$key: " . $db->{$key} . "\n";
1587         }
1588
1589 Remember that Perl's C<keys()> function extracts I<every> key from the hash and
1590 pushes them onto an array, all before the loop even begins.  If you have an 
1591 extra large hash, this may exhaust Perl's memory.  Instead, consider using 
1592 Perl's C<each()> function, which pulls keys/values one at a time, using very 
1593 little memory:
1594
1595         while (my ($key, $value) = each %$db) {
1596                 print "$key: $value\n";
1597         }
1598
1599 Please note that when using C<each()>, you should always pass a direct
1600 hash reference, not a lookup.  Meaning, you should B<never> do this:
1601
1602         # NEVER DO THIS
1603         while (my ($key, $value) = each %{$db->{foo}}) { # BAD
1604
1605 This causes an infinite loop, because for each iteration, Perl is calling
1606 FETCH() on the $db handle, resulting in a "new" hash for foo every time, so
1607 it effectively keeps returning the first key over and over again. Instead, 
1608 assign a temporary variable to C<$db->{foo}>, then pass that to each().
1609
1610 =head2 ARRAYS
1611
1612 As with hashes, you can treat any DBM::Deep object like a normal Perl array
1613 reference.  This includes inserting, removing and manipulating elements, 
1614 and the C<push()>, C<pop()>, C<shift()>, C<unshift()> and C<splice()> functions.
1615 The object must have first been created using type C<DBM::Deep-E<gt>TYPE_ARRAY>, 
1616 or simply be a nested array reference inside a hash.  Example:
1617
1618         my $db = DBM::Deep->new(
1619                 file => "foo-array.db",
1620                 type => DBM::Deep->TYPE_ARRAY
1621         );
1622         
1623         $db->[0] = "foo";
1624         push @$db, "bar", "baz";
1625         unshift @$db, "bah";
1626         
1627         my $last_elem = pop @$db; # baz
1628         my $first_elem = shift @$db; # bah
1629         my $second_elem = $db->[1]; # bar
1630         
1631         my $num_elements = scalar @$db;
1632
1633 =head1 OO INTERFACE
1634
1635 In addition to the I<tie()> interface, you can also use a standard OO interface
1636 to manipulate all aspects of DBM::Deep databases.  Each type of object (hash or
1637 array) has its own methods, but both types share the following common methods: 
1638 C<put()>, C<get()>, C<exists()>, C<delete()> and C<clear()>.
1639
1640 =over
1641
1642 =item * new() / clone()
1643
1644 These are the constructor and copy-functions.
1645
1646 =item * put() / store()
1647
1648 Stores a new hash key/value pair, or sets an array element value.  Takes two
1649 arguments, the hash key or array index, and the new value.  The value can be
1650 a scalar, hash ref or array ref.  Returns true on success, false on failure.
1651
1652         $db->put("foo", "bar"); # for hashes
1653         $db->put(1, "bar"); # for arrays
1654
1655 =item * get() / fetch()
1656
1657 Fetches the value of a hash key or array element.  Takes one argument: the hash
1658 key or array index.  Returns a scalar, hash ref or array ref, depending on the 
1659 data type stored.
1660
1661         my $value = $db->get("foo"); # for hashes
1662         my $value = $db->get(1); # for arrays
1663
1664 =item * exists()
1665
1666 Checks if a hash key or array index exists.  Takes one argument: the hash key 
1667 or array index.  Returns true if it exists, false if not.
1668
1669         if ($db->exists("foo")) { print "yay!\n"; } # for hashes
1670         if ($db->exists(1)) { print "yay!\n"; } # for arrays
1671
1672 =item * delete()
1673
1674 Deletes one hash key/value pair or array element.  Takes one argument: the hash
1675 key or array index.  Returns true on success, false if not found.  For arrays,
1676 the remaining elements located after the deleted element are NOT moved over.
1677 The deleted element is essentially just undefined, which is exactly how Perl's
1678 internal arrays work.  Please note that the space occupied by the deleted 
1679 key/value or element is B<not> reused again -- see L<UNUSED SPACE RECOVERY> 
1680 below for details and workarounds.
1681
1682         $db->delete("foo"); # for hashes
1683         $db->delete(1); # for arrays
1684
1685 =item * clear()
1686
1687 Deletes B<all> hash keys or array elements.  Takes no arguments.  No return 
1688 value.  Please note that the space occupied by the deleted keys/values or 
1689 elements is B<not> reused again -- see L<UNUSED SPACE RECOVERY> below for 
1690 details and workarounds.
1691
1692         $db->clear(); # hashes or arrays
1693
1694 =item * lock() / unlock()
1695
1696 q.v. Locking.
1697
1698 =item * optimize()
1699
1700 Recover lost disk space.
1701
1702 =item * import() / export()
1703
1704 Data going in and out.
1705
1706 =item * set_digest() / set_pack() / set_filter()
1707
1708 q.v. adjusting the interal parameters.
1709
1710 =back
1711
1712 =head2 HASHES
1713
1714 For hashes, DBM::Deep supports all the common methods described above, and the 
1715 following additional methods: C<first_key()> and C<next_key()>.
1716
1717 =over
1718
1719 =item * first_key()
1720
1721 Returns the "first" key in the hash.  As with built-in Perl hashes, keys are 
1722 fetched in an undefined order (which appears random).  Takes no arguments, 
1723 returns the key as a scalar value.
1724
1725         my $key = $db->first_key();
1726
1727 =item * next_key()
1728
1729 Returns the "next" key in the hash, given the previous one as the sole argument.
1730 Returns undef if there are no more keys to be fetched.
1731
1732         $key = $db->next_key($key);
1733
1734 =back
1735
1736 Here are some examples of using hashes:
1737
1738         my $db = DBM::Deep->new( "foo.db" );
1739         
1740         $db->put("foo", "bar");
1741         print "foo: " . $db->get("foo") . "\n";
1742         
1743         $db->put("baz", {}); # new child hash ref
1744         $db->get("baz")->put("buz", "biz");
1745         print "buz: " . $db->get("baz")->get("buz") . "\n";
1746         
1747         my $key = $db->first_key();
1748         while ($key) {
1749                 print "$key: " . $db->get($key) . "\n";
1750                 $key = $db->next_key($key);     
1751         }
1752         
1753         if ($db->exists("foo")) { $db->delete("foo"); }
1754
1755 =head2 ARRAYS
1756
1757 For arrays, DBM::Deep supports all the common methods described above, and the 
1758 following additional methods: C<length()>, C<push()>, C<pop()>, C<shift()>, 
1759 C<unshift()> and C<splice()>.
1760
1761 =over
1762
1763 =item * length()
1764
1765 Returns the number of elements in the array.  Takes no arguments.
1766
1767         my $len = $db->length();
1768
1769 =item * push()
1770
1771 Adds one or more elements onto the end of the array.  Accepts scalars, hash 
1772 refs or array refs.  No return value.
1773
1774         $db->push("foo", "bar", {});
1775
1776 =item * pop()
1777
1778 Fetches the last element in the array, and deletes it.  Takes no arguments.
1779 Returns undef if array is empty.  Returns the element value.
1780
1781         my $elem = $db->pop();
1782
1783 =item * shift()
1784
1785 Fetches the first element in the array, deletes it, then shifts all the 
1786 remaining elements over to take up the space.  Returns the element value.  This 
1787 method is not recommended with large arrays -- see L<LARGE ARRAYS> below for 
1788 details.
1789
1790         my $elem = $db->shift();
1791
1792 =item * unshift()
1793
1794 Inserts one or more elements onto the beginning of the array, shifting all 
1795 existing elements over to make room.  Accepts scalars, hash refs or array refs.  
1796 No return value.  This method is not recommended with large arrays -- see 
1797 <LARGE ARRAYS> below for details.
1798
1799         $db->unshift("foo", "bar", {});
1800
1801 =item * splice()
1802
1803 Performs exactly like Perl's built-in function of the same name.  See L<perldoc 
1804 -f splice> for usage -- it is too complicated to document here.  This method is
1805 not recommended with large arrays -- see L<LARGE ARRAYS> below for details.
1806
1807 =back
1808
1809 Here are some examples of using arrays:
1810
1811         my $db = DBM::Deep->new(
1812                 file => "foo.db",
1813                 type => DBM::Deep->TYPE_ARRAY
1814         );
1815         
1816         $db->push("bar", "baz");
1817         $db->unshift("foo");
1818         $db->put(3, "buz");
1819         
1820         my $len = $db->length();
1821         print "length: $len\n"; # 4
1822         
1823         for (my $k=0; $k<$len; $k++) {
1824                 print "$k: " . $db->get($k) . "\n";
1825         }
1826         
1827         $db->splice(1, 2, "biz", "baf");
1828         
1829         while (my $elem = shift @$db) {
1830                 print "shifted: $elem\n";
1831         }
1832
1833 =head1 LOCKING
1834
1835 Enable automatic file locking by passing a true value to the C<locking> 
1836 parameter when constructing your DBM::Deep object (see L<SETUP> above).
1837
1838         my $db = DBM::Deep->new(
1839                 file => "foo.db",
1840                 locking => 1
1841         );
1842
1843 This causes DBM::Deep to C<flock()> the underlying filehandle with exclusive 
1844 mode for writes, and shared mode for reads.  This is required if you have 
1845 multiple processes accessing the same database file, to avoid file corruption.  
1846 Please note that C<flock()> does NOT work for files over NFS.  See L<DB OVER 
1847 NFS> below for more.
1848
1849 =head2 EXPLICIT LOCKING
1850
1851 You can explicitly lock a database, so it remains locked for multiple 
1852 transactions.  This is done by calling the C<lock()> method, and passing an 
1853 optional lock mode argument (defaults to exclusive mode).  This is particularly
1854 useful for things like counters, where the current value needs to be fetched, 
1855 then incremented, then stored again.
1856
1857         $db->lock();
1858         my $counter = $db->get("counter");
1859         $counter++;
1860         $db->put("counter", $counter);
1861         $db->unlock();
1862
1863         # or...
1864         
1865         $db->lock();
1866         $db->{counter}++;
1867         $db->unlock();
1868
1869 You can pass C<lock()> an optional argument, which specifies which mode to use
1870 (exclusive or shared).  Use one of these two constants: C<DBM::Deep-E<gt>LOCK_EX> 
1871 or C<DBM::Deep-E<gt>LOCK_SH>.  These are passed directly to C<flock()>, and are the 
1872 same as the constants defined in Perl's C<Fcntl> module.
1873
1874         $db->lock( DBM::Deep->LOCK_SH );
1875         # something here
1876         $db->unlock();
1877
1878 =head1 IMPORTING/EXPORTING
1879
1880 You can import existing complex structures by calling the C<import()> method,
1881 and export an entire database into an in-memory structure using the C<export()>
1882 method.  Both are examined here.
1883
1884 =head2 IMPORTING
1885
1886 Say you have an existing hash with nested hashes/arrays inside it.  Instead of
1887 walking the structure and adding keys/elements to the database as you go, 
1888 simply pass a reference to the C<import()> method.  This recursively adds 
1889 everything to an existing DBM::Deep object for you.  Here is an example:
1890
1891         my $struct = {
1892                 key1 => "value1",
1893                 key2 => "value2",
1894                 array1 => [ "elem0", "elem1", "elem2" ],
1895                 hash1 => {
1896                         subkey1 => "subvalue1",
1897                         subkey2 => "subvalue2"
1898                 }
1899         };
1900         
1901         my $db = DBM::Deep->new( "foo.db" );
1902         $db->import( $struct );
1903         
1904         print $db->{key1} . "\n"; # prints "value1"
1905
1906 This recursively imports the entire C<$struct> object into C<$db>, including 
1907 all nested hashes and arrays.  If the DBM::Deep object contains exsiting data,
1908 keys are merged with the existing ones, replacing if they already exist.  
1909 The C<import()> method can be called on any database level (not just the base 
1910 level), and works with both hash and array DB types.
1911
1912 B<Note:> Make sure your existing structure has no circular references in it.
1913 These will cause an infinite loop when importing.
1914
1915 =head2 EXPORTING
1916
1917 Calling the C<export()> method on an existing DBM::Deep object will return 
1918 a reference to a new in-memory copy of the database.  The export is done 
1919 recursively, so all nested hashes/arrays are all exported to standard Perl
1920 objects.  Here is an example:
1921
1922         my $db = DBM::Deep->new( "foo.db" );
1923         
1924         $db->{key1} = "value1";
1925         $db->{key2} = "value2";
1926         $db->{hash1} = {};
1927         $db->{hash1}->{subkey1} = "subvalue1";
1928         $db->{hash1}->{subkey2} = "subvalue2";
1929         
1930         my $struct = $db->export();
1931         
1932         print $struct->{key1} . "\n"; # prints "value1"
1933
1934 This makes a complete copy of the database in memory, and returns a reference
1935 to it.  The C<export()> method can be called on any database level (not just 
1936 the base level), and works with both hash and array DB types.  Be careful of 
1937 large databases -- you can store a lot more data in a DBM::Deep object than an 
1938 in-memory Perl structure.
1939
1940 B<Note:> Make sure your database has no circular references in it.
1941 These will cause an infinite loop when exporting.
1942
1943 =head1 FILTERS
1944
1945 DBM::Deep has a number of hooks where you can specify your own Perl function
1946 to perform filtering on incoming or outgoing data.  This is a perfect
1947 way to extend the engine, and implement things like real-time compression or
1948 encryption.  Filtering applies to the base DB level, and all child hashes / 
1949 arrays.  Filter hooks can be specified when your DBM::Deep object is first 
1950 constructed, or by calling the C<set_filter()> method at any time.  There are 
1951 four available filter hooks, described below:
1952
1953 =over
1954
1955 =item * filter_store_key
1956
1957 This filter is called whenever a hash key is stored.  It 
1958 is passed the incoming key, and expected to return a transformed key.
1959
1960 =item * filter_store_value
1961
1962 This filter is called whenever a hash key or array element is stored.  It 
1963 is passed the incoming value, and expected to return a transformed value.
1964
1965 =item * filter_fetch_key
1966
1967 This filter is called whenever a hash key is fetched (i.e. via 
1968 C<first_key()> or C<next_key()>).  It is passed the transformed key,
1969 and expected to return the plain key.
1970
1971 =item * filter_fetch_value
1972
1973 This filter is called whenever a hash key or array element is fetched.  
1974 It is passed the transformed value, and expected to return the plain value.
1975
1976 =back
1977
1978 Here are the two ways to setup a filter hook:
1979
1980         my $db = DBM::Deep->new(
1981                 file => "foo.db",
1982                 filter_store_value => \&my_filter_store,
1983                 filter_fetch_value => \&my_filter_fetch
1984         );
1985         
1986         # or...
1987         
1988         $db->set_filter( "filter_store_value", \&my_filter_store );
1989         $db->set_filter( "filter_fetch_value", \&my_filter_fetch );
1990
1991 Your filter function will be called only when dealing with SCALAR keys or
1992 values.  When nested hashes and arrays are being stored/fetched, filtering
1993 is bypassed.  Filters are called as static functions, passed a single SCALAR 
1994 argument, and expected to return a single SCALAR value.  If you want to
1995 remove a filter, set the function reference to C<undef>:
1996
1997         $db->set_filter( "filter_store_value", undef );
1998
1999 =head2 REAL-TIME ENCRYPTION EXAMPLE
2000
2001 Here is a working example that uses the I<Crypt::Blowfish> module to 
2002 do real-time encryption / decryption of keys & values with DBM::Deep Filters.
2003 Please visit L<http://search.cpan.org/search?module=Crypt::Blowfish> for more 
2004 on I<Crypt::Blowfish>.  You'll also need the I<Crypt::CBC> module.
2005
2006         use DBM::Deep;
2007         use Crypt::Blowfish;
2008         use Crypt::CBC;
2009         
2010         my $cipher = Crypt::CBC->new({
2011                 'key'             => 'my secret key',
2012                 'cipher'          => 'Blowfish',
2013                 'iv'              => '$KJh#(}q',
2014                 'regenerate_key'  => 0,
2015                 'padding'         => 'space',
2016                 'prepend_iv'      => 0
2017         });
2018         
2019         my $db = DBM::Deep->new(
2020                 file => "foo-encrypt.db",
2021                 filter_store_key => \&my_encrypt,
2022                 filter_store_value => \&my_encrypt,
2023                 filter_fetch_key => \&my_decrypt,
2024                 filter_fetch_value => \&my_decrypt,
2025         );
2026         
2027         $db->{key1} = "value1";
2028         $db->{key2} = "value2";
2029         print "key1: " . $db->{key1} . "\n";
2030         print "key2: " . $db->{key2} . "\n";
2031         
2032         undef $db;
2033         exit;
2034         
2035         sub my_encrypt {
2036                 return $cipher->encrypt( $_[0] );
2037         }
2038         sub my_decrypt {
2039                 return $cipher->decrypt( $_[0] );
2040         }
2041
2042 =head2 REAL-TIME COMPRESSION EXAMPLE
2043
2044 Here is a working example that uses the I<Compress::Zlib> module to do real-time
2045 compression / decompression of keys & values with DBM::Deep Filters.
2046 Please visit L<http://search.cpan.org/search?module=Compress::Zlib> for 
2047 more on I<Compress::Zlib>.
2048
2049         use DBM::Deep;
2050         use Compress::Zlib;
2051         
2052         my $db = DBM::Deep->new(
2053                 file => "foo-compress.db",
2054                 filter_store_key => \&my_compress,
2055                 filter_store_value => \&my_compress,
2056                 filter_fetch_key => \&my_decompress,
2057                 filter_fetch_value => \&my_decompress,
2058         );
2059         
2060         $db->{key1} = "value1";
2061         $db->{key2} = "value2";
2062         print "key1: " . $db->{key1} . "\n";
2063         print "key2: " . $db->{key2} . "\n";
2064         
2065         undef $db;
2066         exit;
2067         
2068         sub my_compress {
2069                 return Compress::Zlib::memGzip( $_[0] ) ;
2070         }
2071         sub my_decompress {
2072                 return Compress::Zlib::memGunzip( $_[0] ) ;
2073         }
2074
2075 B<Note:> Filtering of keys only applies to hashes.  Array "keys" are
2076 actually numerical index numbers, and are not filtered.
2077
2078 =head1 ERROR HANDLING
2079
2080 Most DBM::Deep methods return a true value for success, and call die() on
2081 failure.  You can wrap calls in an eval block to catch the die.
2082
2083         my $db = DBM::Deep->new( "foo.db" ); # create hash
2084         eval { $db->push("foo"); }; # ILLEGAL -- push is array-only call
2085         
2086     print $@;           # prints error message
2087
2088 =head1 LARGEFILE SUPPORT
2089
2090 If you have a 64-bit system, and your Perl is compiled with both LARGEFILE
2091 and 64-bit support, you I<may> be able to create databases larger than 2 GB.
2092 DBM::Deep by default uses 32-bit file offset tags, but these can be changed
2093 by calling the static C<set_pack()> method before you do anything else.
2094
2095         DBM::Deep::set_pack(8, 'Q');
2096
2097 This tells DBM::Deep to pack all file offsets with 8-byte (64-bit) quad words 
2098 instead of 32-bit longs.  After setting these values your DB files have a 
2099 theoretical maximum size of 16 XB (exabytes).
2100
2101 B<Note:> Changing these values will B<NOT> work for existing database files.
2102 Only change this for new files, and make sure it stays set consistently 
2103 throughout the file's life.  If you do set these values, you can no longer 
2104 access 32-bit DB files.  You can, however, call C<set_pack(4, 'N')> to change 
2105 back to 32-bit mode.
2106
2107 B<Note:> I have not personally tested files > 2 GB -- all my systems have 
2108 only a 32-bit Perl.  However, I have received user reports that this does 
2109 indeed work!
2110
2111 =head1 LOW-LEVEL ACCESS
2112
2113 If you require low-level access to the underlying filehandle that DBM::Deep uses,
2114 you can call the C<_fh()> method, which returns the handle:
2115
2116         my $fh = $db->_fh();
2117
2118 This method can be called on the root level of the datbase, or any child
2119 hashes or arrays.  All levels share a I<root> structure, which contains things
2120 like the filehandle, a reference counter, and all the options specified
2121 when you created the object.  You can get access to this root structure by 
2122 calling the C<root()> method.
2123
2124         my $root = $db->_root();
2125
2126 This is useful for changing options after the object has already been created,
2127 such as enabling/disabling locking, or debug modes.  You can also
2128 store your own temporary user data in this structure (be wary of name 
2129 collision), which is then accessible from any child hash or array.
2130
2131 =head1 CUSTOM DIGEST ALGORITHM
2132
2133 DBM::Deep by default uses the I<Message Digest 5> (MD5) algorithm for hashing
2134 keys.  However you can override this, and use another algorithm (such as SHA-256)
2135 or even write your own.  But please note that DBM::Deep currently expects zero 
2136 collisions, so your algorithm has to be I<perfect>, so to speak.
2137 Collision detection may be introduced in a later version.
2138
2139
2140
2141 You can specify a custom digest algorithm by calling the static C<set_digest()> 
2142 function, passing a reference to a subroutine, and the length of the algorithm's 
2143 hashes (in bytes).  This is a global static function, which affects ALL DBM::Deep 
2144 objects.  Here is a working example that uses a 256-bit hash from the 
2145 I<Digest::SHA256> module.  Please see 
2146 L<http://search.cpan.org/search?module=Digest::SHA256> for more.
2147
2148         use DBM::Deep;
2149         use Digest::SHA256;
2150         
2151         my $context = Digest::SHA256::new(256);
2152         
2153         DBM::Deep::set_digest( \&my_digest, 32 );
2154         
2155         my $db = DBM::Deep->new( "foo-sha.db" );
2156         
2157         $db->{key1} = "value1";
2158         $db->{key2} = "value2";
2159         print "key1: " . $db->{key1} . "\n";
2160         print "key2: " . $db->{key2} . "\n";
2161         
2162         undef $db;
2163         exit;
2164         
2165         sub my_digest {
2166                 return substr( $context->hash($_[0]), 0, 32 );
2167         }
2168
2169 B<Note:> Your returned digest strings must be B<EXACTLY> the number
2170 of bytes you specify in the C<set_digest()> function (in this case 32).
2171
2172 =head1 CIRCULAR REFERENCES
2173
2174 DBM::Deep has B<experimental> support for circular references.  Meaning you
2175 can have a nested hash key or array element that points to a parent object.
2176 This relationship is stored in the DB file, and is preserved between sessions.
2177 Here is an example:
2178
2179         my $db = DBM::Deep->new( "foo.db" );
2180         
2181         $db->{foo} = "bar";
2182         $db->{circle} = $db; # ref to self
2183         
2184         print $db->{foo} . "\n"; # prints "foo"
2185         print $db->{circle}->{foo} . "\n"; # prints "foo" again
2186
2187 One catch is, passing the object to a function that recursively walks the
2188 object tree (such as I<Data::Dumper> or even the built-in C<optimize()> or
2189 C<export()> methods) will result in an infinite loop.  The other catch is, 
2190 if you fetch the I<key> of a circular reference (i.e. using the C<first_key()> 
2191 or C<next_key()> methods), you will get the I<target object's key>, not the 
2192 ref's key.  This gets even more interesting with the above example, where 
2193 the I<circle> key points to the base DB object, which technically doesn't 
2194 have a key.  So I made DBM::Deep return "[base]" as the key name in that 
2195 special case.
2196
2197 =head1 CAVEATS / ISSUES / BUGS
2198
2199 This section describes all the known issues with DBM::Deep.  It you have found
2200 something that is not listed here, please send e-mail to L<jhuckaby@cpan.org>.
2201
2202 =head2 UNUSED SPACE RECOVERY
2203
2204 One major caveat with DBM::Deep is that space occupied by existing keys and
2205 values is not recovered when they are deleted.  Meaning if you keep deleting
2206 and adding new keys, your file will continuously grow.  I am working on this,
2207 but in the meantime you can call the built-in C<optimize()> method from time to 
2208 time (perhaps in a crontab or something) to recover all your unused space.
2209
2210         $db->optimize(); # returns true on success
2211
2212 This rebuilds the ENTIRE database into a new file, then moves it on top of
2213 the original.  The new file will have no unused space, thus it will take up as
2214 little disk space as possible.  Please note that this operation can take 
2215 a long time for large files, and you need enough disk space to temporarily hold 
2216 2 copies of your DB file.  The temporary file is created in the same directory 
2217 as the original, named with a ".tmp" extension, and is deleted when the 
2218 operation completes.  Oh, and if locking is enabled, the DB is automatically 
2219 locked for the entire duration of the copy.
2220
2221 B<WARNING:> Only call optimize() on the top-level node of the database, and 
2222 make sure there are no child references lying around.  DBM::Deep keeps a reference 
2223 counter, and if it is greater than 1, optimize() will abort and return undef.
2224
2225 =head2 AUTOVIVIFICATION
2226
2227 Unfortunately, autovivification doesn't work with tied hashes.  This appears to 
2228 be a bug in Perl's tie() system, as I<Jakob Schmidt> encountered the very same 
2229 issue with his I<DWH_FIle> module (see L<http://search.cpan.org/search?module=DWH_File>),
2230 and it is also mentioned in the BUGS section for the I<MLDBM> module <see 
2231 L<http://search.cpan.org/search?module=MLDBM>).  Basically, on a new db file,
2232 this does not work:
2233
2234         $db->{foo}->{bar} = "hello";
2235
2236 Since "foo" doesn't exist, you cannot add "bar" to it.  You end up with "foo"
2237 being an empty hash.  Try this instead, which works fine:
2238
2239         $db->{foo} = { bar => "hello" };
2240
2241 As of Perl 5.8.7, this bug still exists.  I have walked very carefully through
2242 the execution path, and Perl indeed passes an empty hash to the STORE() method.
2243 Probably a bug in Perl.
2244
2245 =head2 FILE CORRUPTION
2246
2247 The current level of error handling in DBM::Deep is minimal.  Files I<are> checked
2248 for a 32-bit signature when opened, but other corruption in files can cause
2249 segmentation faults.  DBM::Deep may try to seek() past the end of a file, or get
2250 stuck in an infinite loop depending on the level of corruption.  File write
2251 operations are not checked for failure (for speed), so if you happen to run
2252 out of disk space, DBM::Deep will probably fail in a bad way.  These things will 
2253 be addressed in a later version of DBM::Deep.
2254
2255 =head2 DB OVER NFS
2256
2257 Beware of using DB files over NFS.  DBM::Deep uses flock(), which works well on local
2258 filesystems, but will NOT protect you from file corruption over NFS.  I've heard 
2259 about setting up your NFS server with a locking daemon, then using lockf() to 
2260 lock your files, but your mileage may vary there as well.  From what I 
2261 understand, there is no real way to do it.  However, if you need access to the 
2262 underlying filehandle in DBM::Deep for using some other kind of locking scheme like 
2263 lockf(), see the L<LOW-LEVEL ACCESS> section above.
2264
2265 =head2 COPYING OBJECTS
2266
2267 Beware of copying tied objects in Perl.  Very strange things can happen.  
2268 Instead, use DBM::Deep's C<clone()> method which safely copies the object and 
2269 returns a new, blessed, tied hash or array to the same level in the DB.
2270
2271         my $copy = $db->clone();
2272
2273 B<Note>: Since clone() here is cloning the object, not the database location, any
2274 modifications to either $db or $copy will be visible in both.
2275
2276 =head2 LARGE ARRAYS
2277
2278 Beware of using C<shift()>, C<unshift()> or C<splice()> with large arrays.
2279 These functions cause every element in the array to move, which can be murder
2280 on DBM::Deep, as every element has to be fetched from disk, then stored again in
2281 a different location.  This will be addressed in the forthcoming version 1.00.
2282
2283 =head2 WRITEONLY FILES
2284
2285 If you pass in a filehandle to new(), you may have opened it in either a readonly or
2286 writeonly mode. STORE will verify that the filehandle is writable. However, there
2287 doesn't seem to be a good way to determine if a filehandle is readable. And, if the
2288 filehandle isn't readable, it's not clear what will happen. So, don't do that.
2289
2290 =head1 PERFORMANCE
2291
2292 This section discusses DBM::Deep's speed and memory usage.
2293
2294 =head2 SPEED
2295
2296 Obviously, DBM::Deep isn't going to be as fast as some C-based DBMs, such as 
2297 the almighty I<BerkeleyDB>.  But it makes up for it in features like true
2298 multi-level hash/array support, and cross-platform FTPable files.  Even so,
2299 DBM::Deep is still pretty fast, and the speed stays fairly consistent, even
2300 with huge databases.  Here is some test data:
2301         
2302         Adding 1,000,000 keys to new DB file...
2303         
2304         At 100 keys, avg. speed is 2,703 keys/sec
2305         At 200 keys, avg. speed is 2,642 keys/sec
2306         At 300 keys, avg. speed is 2,598 keys/sec
2307         At 400 keys, avg. speed is 2,578 keys/sec
2308         At 500 keys, avg. speed is 2,722 keys/sec
2309         At 600 keys, avg. speed is 2,628 keys/sec
2310         At 700 keys, avg. speed is 2,700 keys/sec
2311         At 800 keys, avg. speed is 2,607 keys/sec
2312         At 900 keys, avg. speed is 2,190 keys/sec
2313         At 1,000 keys, avg. speed is 2,570 keys/sec
2314         At 2,000 keys, avg. speed is 2,417 keys/sec
2315         At 3,000 keys, avg. speed is 1,982 keys/sec
2316         At 4,000 keys, avg. speed is 1,568 keys/sec
2317         At 5,000 keys, avg. speed is 1,533 keys/sec
2318         At 6,000 keys, avg. speed is 1,787 keys/sec
2319         At 7,000 keys, avg. speed is 1,977 keys/sec
2320         At 8,000 keys, avg. speed is 2,028 keys/sec
2321         At 9,000 keys, avg. speed is 2,077 keys/sec
2322         At 10,000 keys, avg. speed is 2,031 keys/sec
2323         At 20,000 keys, avg. speed is 1,970 keys/sec
2324         At 30,000 keys, avg. speed is 2,050 keys/sec
2325         At 40,000 keys, avg. speed is 2,073 keys/sec
2326         At 50,000 keys, avg. speed is 1,973 keys/sec
2327         At 60,000 keys, avg. speed is 1,914 keys/sec
2328         At 70,000 keys, avg. speed is 2,091 keys/sec
2329         At 80,000 keys, avg. speed is 2,103 keys/sec
2330         At 90,000 keys, avg. speed is 1,886 keys/sec
2331         At 100,000 keys, avg. speed is 1,970 keys/sec
2332         At 200,000 keys, avg. speed is 2,053 keys/sec
2333         At 300,000 keys, avg. speed is 1,697 keys/sec
2334         At 400,000 keys, avg. speed is 1,838 keys/sec
2335         At 500,000 keys, avg. speed is 1,941 keys/sec
2336         At 600,000 keys, avg. speed is 1,930 keys/sec
2337         At 700,000 keys, avg. speed is 1,735 keys/sec
2338         At 800,000 keys, avg. speed is 1,795 keys/sec
2339         At 900,000 keys, avg. speed is 1,221 keys/sec
2340         At 1,000,000 keys, avg. speed is 1,077 keys/sec
2341
2342 This test was performed on a PowerMac G4 1gHz running Mac OS X 10.3.2 & Perl 
2343 5.8.1, with an 80GB Ultra ATA/100 HD spinning at 7200RPM.  The hash keys and 
2344 values were between 6 - 12 chars in length.  The DB file ended up at 210MB.  
2345 Run time was 12 min 3 sec.
2346
2347 =head2 MEMORY USAGE
2348
2349 One of the great things about DBM::Deep is that it uses very little memory.
2350 Even with huge databases (1,000,000+ keys) you will not see much increased
2351 memory on your process.  DBM::Deep relies solely on the filesystem for storing
2352 and fetching data.  Here is output from I</usr/bin/top> before even opening a
2353 database handle:
2354
2355           PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
2356         22831 root      11   0  2716 2716  1296 R     0.0  0.2   0:07 perl
2357
2358 Basically the process is taking 2,716K of memory.  And here is the same 
2359 process after storing and fetching 1,000,000 keys:
2360
2361           PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
2362         22831 root      14   0  2772 2772  1328 R     0.0  0.2  13:32 perl
2363
2364 Notice the memory usage increased by only 56K.  Test was performed on a 700mHz 
2365 x86 box running Linux RedHat 7.2 & Perl 5.6.1.
2366
2367 =head1 DB FILE FORMAT
2368
2369 In case you were interested in the underlying DB file format, it is documented
2370 here in this section.  You don't need to know this to use the module, it's just 
2371 included for reference.
2372
2373 =head2 SIGNATURE
2374
2375 DBM::Deep files always start with a 32-bit signature to identify the file type.
2376 This is at offset 0.  The signature is "DPDB" in network byte order.  This is
2377 checked for when the file is opened and an error will be thrown if it's not found.
2378
2379 =head2 TAG
2380
2381 The DBM::Deep file is in a I<tagged format>, meaning each section of the file
2382 has a standard header containing the type of data, the length of data, and then 
2383 the data itself.  The type is a single character (1 byte), the length is a 
2384 32-bit unsigned long in network byte order, and the data is, well, the data.
2385 Here is how it unfolds:
2386
2387 =head2 MASTER INDEX
2388
2389 Immediately after the 32-bit file signature is the I<Master Index> record.  
2390 This is a standard tag header followed by 1024 bytes (in 32-bit mode) or 2048 
2391 bytes (in 64-bit mode) of data.  The type is I<H> for hash or I<A> for array, 
2392 depending on how the DBM::Deep object was constructed.
2393
2394 The index works by looking at a I<MD5 Hash> of the hash key (or array index 
2395 number).  The first 8-bit char of the MD5 signature is the offset into the 
2396 index, multipled by 4 in 32-bit mode, or 8 in 64-bit mode.  The value of the 
2397 index element is a file offset of the next tag for the key/element in question,
2398 which is usually a I<Bucket List> tag (see below).
2399
2400 The next tag I<could> be another index, depending on how many keys/elements
2401 exist.  See L<RE-INDEXING> below for details.
2402
2403 =head2 BUCKET LIST
2404
2405 A I<Bucket List> is a collection of 16 MD5 hashes for keys/elements, plus 
2406 file offsets to where the actual data is stored.  It starts with a standard 
2407 tag header, with type I<B>, and a data size of 320 bytes in 32-bit mode, or 
2408 384 bytes in 64-bit mode.  Each MD5 hash is stored in full (16 bytes), plus
2409 the 32-bit or 64-bit file offset for the I<Bucket> containing the actual data.
2410 When the list fills up, a I<Re-Index> operation is performed (See 
2411 L<RE-INDEXING> below).
2412
2413 =head2 BUCKET
2414
2415 A I<Bucket> is a tag containing a key/value pair (in hash mode), or a
2416 index/value pair (in array mode).  It starts with a standard tag header with
2417 type I<D> for scalar data (string, binary, etc.), or it could be a nested
2418 hash (type I<H>) or array (type I<A>).  The value comes just after the tag
2419 header.  The size reported in the tag header is only for the value, but then,
2420 just after the value is another size (32-bit unsigned long) and then the plain 
2421 key itself.  Since the value is likely to be fetched more often than the plain 
2422 key, I figured it would be I<slightly> faster to store the value first.
2423
2424 If the type is I<H> (hash) or I<A> (array), the value is another I<Master Index>
2425 record for the nested structure, where the process begins all over again.
2426
2427 =head2 RE-INDEXING
2428
2429 After a I<Bucket List> grows to 16 records, its allocated space in the file is
2430 exhausted.  Then, when another key/element comes in, the list is converted to a 
2431 new index record.  However, this index will look at the next char in the MD5 
2432 hash, and arrange new Bucket List pointers accordingly.  This process is called 
2433 I<Re-Indexing>.  Basically, a new index tag is created at the file EOF, and all 
2434 17 (16 + new one) keys/elements are removed from the old Bucket List and 
2435 inserted into the new index.  Several new Bucket Lists are created in the 
2436 process, as a new MD5 char from the key is being examined (it is unlikely that 
2437 the keys will all share the same next char of their MD5s).
2438
2439 Because of the way the I<MD5> algorithm works, it is impossible to tell exactly
2440 when the Bucket Lists will turn into indexes, but the first round tends to 
2441 happen right around 4,000 keys.  You will see a I<slight> decrease in 
2442 performance here, but it picks back up pretty quick (see L<SPEED> above).  Then 
2443 it takes B<a lot> more keys to exhaust the next level of Bucket Lists.  It's 
2444 right around 900,000 keys.  This process can continue nearly indefinitely -- 
2445 right up until the point the I<MD5> signatures start colliding with each other, 
2446 and this is B<EXTREMELY> rare -- like winning the lottery 5 times in a row AND 
2447 getting struck by lightning while you are walking to cash in your tickets.  
2448 Theoretically, since I<MD5> hashes are 128-bit values, you I<could> have up to 
2449 340,282,366,921,000,000,000,000,000,000,000,000,000 keys/elements (I believe 
2450 this is 340 unodecillion, but don't quote me).
2451
2452 =head2 STORING
2453
2454 When a new key/element is stored, the key (or index number) is first run through 
2455 I<Digest::MD5> to get a 128-bit signature (example, in hex: 
2456 b05783b0773d894396d475ced9d2f4f6).  Then, the I<Master Index> record is checked
2457 for the first char of the signature (in this case I<b0>).  If it does not exist,
2458 a new I<Bucket List> is created for our key (and the next 15 future keys that 
2459 happen to also have I<b> as their first MD5 char).  The entire MD5 is written 
2460 to the I<Bucket List> along with the offset of the new I<Bucket> record (EOF at
2461 this point, unless we are replacing an existing I<Bucket>), where the actual 
2462 data will be stored.
2463
2464 =head2 FETCHING
2465
2466 Fetching an existing key/element involves getting a I<Digest::MD5> of the key 
2467 (or index number), then walking along the indexes.  If there are enough 
2468 keys/elements in this DB level, there might be nested indexes, each linked to 
2469 a particular char of the MD5.  Finally, a I<Bucket List> is pointed to, which 
2470 contains up to 16 full MD5 hashes.  Each is checked for equality to the key in 
2471 question.  If we found a match, the I<Bucket> tag is loaded, where the value and 
2472 plain key are stored.
2473
2474 Fetching the plain key occurs when calling the I<first_key()> and I<next_key()>
2475 methods.  In this process the indexes are walked systematically, and each key
2476 fetched in increasing MD5 order (which is why it appears random).   Once the
2477 I<Bucket> is found, the value is skipped and the plain key returned instead.  
2478 B<Note:> Do not count on keys being fetched as if the MD5 hashes were 
2479 alphabetically sorted.  This only happens on an index-level -- as soon as the 
2480 I<Bucket Lists> are hit, the keys will come out in the order they went in -- 
2481 so it's pretty much undefined how the keys will come out -- just like Perl's 
2482 built-in hashes.
2483
2484 =head1 CODE COVERAGE
2485
2486 We use B<Devel::Cover> to test the code coverage of our tests, below is the
2487 B<Devel::Cover> report on this module's test suite.
2488
2489   ---------------------------- ------ ------ ------ ------ ------ ------ ------
2490   File                           stmt   bran   cond    sub    pod   time  total
2491   ---------------------------- ------ ------ ------ ------ ------ ------ ------
2492   blib/lib/DBM/Deep.pm           95.2   83.8   70.0   98.2  100.0   58.0   91.0
2493   blib/lib/DBM/Deep/Array.pm    100.0   91.1  100.0  100.0    n/a   26.7   98.0
2494   blib/lib/DBM/Deep/Hash.pm      95.3   80.0  100.0  100.0    n/a   15.3   92.4
2495   Total                          96.2   84.8   74.4   98.8  100.0  100.0   92.4
2496   ---------------------------- ------ ------ ------ ------ ------ ------ ------
2497
2498 =head1 MORE INFORMATION
2499
2500 Check out the DBM::Deep Google Group at L<http://groups.google.com/group/DBM-Deep>
2501 or send email to L<DBM-Deep@googlegroups.com>.
2502
2503 =head1 AUTHORS
2504
2505 Joseph Huckaby, L<jhuckaby@cpan.org>
2506
2507 Rob Kinyon, L<rkinyon@cpan.org>
2508
2509 Special thanks to Adam Sah and Rich Gaushell!  You know why :-)
2510
2511 =head1 SEE ALSO
2512
2513 perltie(1), Tie::Hash(3), Digest::MD5(3), Fcntl(3), flock(2), lockf(3), nfs(5),
2514 Digest::SHA256(3), Crypt::Blowfish(3), Compress::Zlib(3)
2515
2516 =head1 LICENSE
2517
2518 Copyright (c) 2002-2006 Joseph Huckaby.  All Rights Reserved.
2519 This is free software, you may use it and distribute it under the
2520 same terms as Perl itself.
2521
2522 =cut