From: rkinyon Date: Tue, 7 Mar 2006 19:45:42 +0000 (+0000) Subject: Moved a lot of open()'s code into setup_fh() X-Git-Tag: 0-99_01~73 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=118ba3432abff7926f632c8f269fdbf60a3c36ff;p=dbsrgits%2FDBM-Deep.git Moved a lot of open()'s code into setup_fh() --- diff --git a/lib/DBM/Deep.pm b/lib/DBM/Deep.pm index 5b14412..1726d4f 100644 --- a/lib/DBM/Deep.pm +++ b/lib/DBM/Deep.pm @@ -160,7 +160,7 @@ sub lock { flock($self->_fh, $type); # refresh end counter in case file has changed size - my @stats = stat($self->_root->{file}); + my @stats = stat($self->_fh); $self->_root->{end} = $stats[7]; # double-check file inode, in case another process diff --git a/lib/DBM/Deep/Engine.pm b/lib/DBM/Deep/Engine.pm index d49e4e4..542a4d3 100644 --- a/lib/DBM/Deep/Engine.pm +++ b/lib/DBM/Deep/Engine.pm @@ -107,8 +107,59 @@ sub setup_fh { $self->open( $obj ) if !defined $obj->_fh; - $obj->{base_offset} = length( SIG_FILE ) - unless defined $obj->{base_offset}; + unless ( $obj->{base_offset} ) { + my $fh = $obj->_fh; + + flock $fh, LOCK_EX; + + seek($fh, 0 + $obj->_root->{file_offset}, SEEK_SET); + my $signature; + my $bytes_read = read( $fh, $signature, length(SIG_FILE)); + + ## + # File is empty -- write signature and master index + ## + if (!$bytes_read) { + seek($fh, 0 + $obj->_root->{file_offset}, SEEK_SET); + print( $fh SIG_FILE); + + $obj->_root->{end} = length( SIG_FILE ); + + $obj->{base_offset} = $self->_request_space($obj, $self->{index_size}); + + $self->create_tag( + $obj, $obj->_base_offset, $obj->_type, chr(0) x $self->{index_size}, + ); + + # Flush the filehandle + my $old_fh = select $fh; + my $old_af = $|; $| = 1; $| = $old_af; + select $old_fh; + } + else { + $obj->{base_offset} = $bytes_read; + + ## + # Check signature was valid + ## + unless ($signature eq SIG_FILE) { + $self->close_fh( $obj ); + $obj->_throw_error("Signature not found -- file is not a Deep DB"); + } + + ## + # Get our type from master index signature + ## + my $tag = $self->load_tag($obj, $obj->_base_offset) + or $obj->_throw_error("Corrupted file, no master index record"); + + unless ($obj->{type} eq $tag->{signature}) { + $obj->_throw_error("File type mismatch"); + } + } + + flock $fh, LOCK_UN; + } #XXX We have to make sure we don't mess up when autoflush isn't turned on unless ( $obj->_root->{inode} ) { @@ -150,57 +201,6 @@ sub open { select $old; } - seek($fh, 0 + $obj->_root->{file_offset}, SEEK_SET); - my $signature; - my $bytes_read = read( $fh, $signature, length(SIG_FILE)); - - ## - # File is empty -- write signature and master index - ## - if (!$bytes_read) { - seek($fh, 0 + $obj->_root->{file_offset}, SEEK_SET); - print( $fh SIG_FILE); - - $obj->_root->{end} = length( SIG_FILE ); - - $obj->{base_offset} = $self->_request_space($obj, $self->{index_size}); - - $self->create_tag( - $obj, $obj->_base_offset, $obj->_type, chr(0) x $self->{index_size}, - ); - - # Flush the filehandle - my $old_fh = select $fh; - my $old_af = $|; $| = 1; $| = $old_af; - select $old_fh; - - return 1; - } - - $obj->{base_offset} = $bytes_read - unless defined $obj->{base_offset}; - - ## - # Check signature was valid - ## - unless ($signature eq SIG_FILE) { - $self->close_fh( $obj ); - $obj->_throw_error("Signature not found -- file is not a Deep DB"); - } - - ## - # Get our type from master index signature - ## - my $tag = $self->load_tag($obj, $obj->_base_offset) - or $obj->_throw_error("Corrupted file, no master index record"); - - unless ($obj->{type} eq $tag->{signature}) { - $obj->_throw_error("File type mismatch"); - } - -#XXX We probably also want to store the hash algorithm name and not assume anything -#XXX The cool thing would be to allow a different hashing algorithm at every level - return 1; }