? $args->{root}
: DBM::Deep::_::Root->new( $args );
- #XXX Right before this line, we have to set the physical parameters like
- #XXX 2S vs. 4N vs. 8Q or max_buckets, etc.
$self->{engine}->setup_fh( $self );
return $self;
B<Note:> Your returned digest strings must be B<EXACTLY> the number
of bytes you specify in the hash_size parameter (in this case 32).
+B<Note:> If you do choose to use a custom digest algorithm, you must set it
+every time you access this file. Otherwise, the default (MD5) will be used.
+
=head1 CIRCULAR REFERENCES
DBM::Deep has B<experimental> support for circular references. Meaning you
$self->{max_buckets} = 16;
}
+ return $self;
+}
+
+sub calculate_sizes {
+ my $self = shift;
+
$self->{index_size} = (2**8) * $self->{long_size};
$self->{bucket_size} = $self->{hash_size} + $self->{long_size} * 2;
$self->{bucket_list_size} = $self->{max_buckets} * $self->{bucket_size};
- return $self;
+ return;
}
sub write_file_header {
my $fh = $obj->_fh;
my $loc = $self->_request_space(
- $obj, length( SIG_FILE ) + $self->{data_size},
+ $obj, length( SIG_FILE ) + 12,
);
seek($fh, $loc + $obj->_root->{file_offset}, SEEK_SET);
- print( $fh SIG_FILE, pack('N', 0) );
+ print( $fh
+ SIG_FILE,
+ pack('N', 0),
+ pack('S', $self->{long_size}),
+ pack('A', $self->{long_pack}),
+ pack('S', $self->{data_size}),
+ pack('A', $self->{data_pack}),
+ pack('S', $self->{max_buckets}),
+ );
return;
}
seek($fh, 0 + $obj->_root->{file_offset}, SEEK_SET);
my $buffer;
my $bytes_read = read(
- $fh, $buffer, length(SIG_FILE) + $self->{data_size},
+ $fh, $buffer, length(SIG_FILE) + 12,
);
if ( $bytes_read ) {
- my ($signature, $version) = unpack( 'A4 N', $buffer );
+ my ($signature, $version, @values) = unpack( 'A4 N S A S A S', $buffer );
unless ($signature eq SIG_FILE) {
$self->close_fh( $obj );
$obj->_throw_error("Signature not found -- file is not a Deep DB");
}
+
+ $#values = 4;
+ if ( grep { !defined } @values ) {
+ die "DBM::Deep: Corrupted file - bad header\n";
+ }
+ @{$self}{qw( long_size long_pack data_size data_pack max_buckets )} = @values;
}
return $bytes_read;
my $fh = $obj->_fh;
flock $fh, LOCK_EX;
+ #XXX The duplication of calculate_sizes needs to go away
unless ( $obj->{base_offset} ) {
my $bytes_read = $self->read_file_header( $obj );
+ $self->calculate_sizes;
+
##
# File is empty -- write header and master index
##
}
}
}
+ else {
+ $self->calculate_sizes;
+ }
#XXX We have to make sure we don't mess up when autoflush isn't turned on
unless ( $obj->_root->{inode} ) {