From: rkinyon Date: Mon, 27 Nov 2006 03:38:52 +0000 (+0000) Subject: Converted to using an object for each file sector type X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8fbac7294aa4343f8953b5db0f408fd8aa620fa9;p=dbsrgits%2FDBM-Deep.git Converted to using an object for each file sector type --- diff --git a/lib/DBM/Deep/Engine3.pm b/lib/DBM/Deep/Engine3.pm index 6ac7093..bef1d7c 100644 --- a/lib/DBM/Deep/Engine3.pm +++ b/lib/DBM/Deep/Engine3.pm @@ -9,7 +9,7 @@ our $VERSION = q(0.99_03); use Scalar::Util (); # File-wide notes: -# * Every method in here assumes that the _storage has been appropriately +# * Every method in here assumes that the storage has been appropriately # safeguarded. This can be anything from flock() to some sort of manual # mutex. But, it's the caller's responsability to make sure that this has # been done. @@ -33,10 +33,12 @@ sub HEAD () { 0 } ################################################################################ -my %size_to_pack = ( - 2 => 'n', - 4 => 'N', - 8 => 'Q', +# Please refer to the pack() documentation for further information +my %StP = ( + 1 => 'c', # Unsigned char value + 2 => 'n', # Unsigned short in "network" (big-endian) order + 4 => 'N', # Unsigned long in "network" (big-endian) order + 8 => 'Q', # Usigned quad (no order specified, presumably machine-dependent) ); sub new { @@ -76,7 +78,7 @@ sub new { } Scalar::Util::weaken( $self->{obj} ) if $self->{obj}; - $self->{byte_pack} = $size_to_pack{ $self->{byte_size} }; + $self->{byte_pack} = $StP{ $self->byte_size }; ## # Number of buckets per blist before another level of indexing is @@ -141,18 +143,13 @@ sub setup_fh { $self->_write_file_header; # 1) Create Array/Hash entry - # 2) Create Index entry + my $initial_reference = DBM::Deep::Engine::Sector::Reference->new({ + engine => $self, + type => $obj->_type, + }); + $obj->{base_offset} = $initial_reference->offset; - $obj->{base_offset} = $self->_storage->request_space( - $self->_tag_size( $self->{index_size} ), - ); - - $self->_write_tag( - $obj->_base_offset, $obj->_type, - chr(0) x $self->{index_size}, - ); - - $self->_storage->flush; + $self->storage->flush; } # Reading from an existing file else { @@ -171,8 +168,8 @@ sub setup_fh { $self->_calculate_sizes; } - #XXX We have to make sure we don't mess up when autoflush isn't turned on - $self->_storage->set_inode; + # We have to make sure we don't mess up when autoflush isn't turned on + $self->storage->set_inode; return 1; } @@ -186,11 +183,13 @@ sub _calculate_sizes { # current hashing algorithm #XXX Does this need to be updated with different hashing algorithms? $self->{hash_chars_used} = (2**8); - $self->{index_size} = $self->{hash_chars_used} * $self->{byte_size}; + $self->{index_size} = $self->{hash_chars_used} * $self->byte_size; - $self->{bucket_size} = $self->{hash_size} + $self->{byte_size} * 2; + $self->{bucket_size} = $self->{hash_size} + $self->byte_size * 2; $self->{bucket_list_size} = $self->{max_buckets} * $self->{bucket_size}; + $self->{data_size} = 256; # In bytes + return; } @@ -200,20 +199,20 @@ sub _write_file_header { my $header_fixed = length( SIG_FILE ) + 1 + 4 + 4; my $header_var = 16 + 1 + 1; - my $loc = $self->_storage->request_space( $header_fixed + $header_var ); + my $loc = $self->storage->request_space( $header_fixed + $header_var ); - $self->_storage->print_at( $loc, + $self->storage->print_at( $loc, SIG_FILE, SIG_HEADER, pack('N', 1), # header version - at this point, we're at 9 bytes pack('N', $header_var), # header size # --- Above is $header_fixed. Below is $header_var pack('N4', 0, 0, 0, 0), # currently running transaction IDs - pack('n', $self->{byte_size}), + pack('n', $self->byte_size), pack('n', $self->{max_buckets}), ); - $self->_storage->set_transaction_offset( 13 ); + $self->storage->set_transaction_offset( 13 ); return; } @@ -224,7 +223,7 @@ sub _read_file_header { my $header_fixed = length( SIG_FILE ) + 1 + 4 + 4; my $header_var = 16 + 1 + 1; - my $buffer = $self->_storage->read_at( 0, $header_fixed ); + my $buffer = $self->storage->read_at( 0, $header_fixed ); return unless length($buffer); my ($file_signature, $sig_header, $header_version, $size) = unpack( @@ -232,29 +231,29 @@ sub _read_file_header { ); unless ( $file_signature eq SIG_FILE ) { - $self->_storage->close; + $self->storage->close; DBM::Deep->_throw_error( "Signature not found -- file is not a Deep DB" ); } unless ( $sig_header eq SIG_HEADER ) { - $self->_storage->close; + $self->storage->close; DBM::Deep->_throw_error( "Old file version found." ); } unless ( $size eq $header_var ) { - $self->_storage->close; + $self->storage->close; DBM::Deep->_throw_error( "Unexpected size found." ); } - my $buffer2 = $self->_storage->read_at( undef, $size ); + my $buffer2 = $self->storage->read_at( undef, $size ); # $a1-4 are the transaction IDs my ($a1, $a2, $a3, $a4, @values) = unpack( 'N4 n n', $buffer2 ); # The transaction offset is the first thing after the fixed header section - $self->_storage->set_transaction_offset( $header_fixed ); + $self->storage->set_transaction_offset( $header_fixed ); if ( @values < 2 || grep { !defined } @values ) { - $self->_storage->close; + $self->storage->close; DBM::Deep->_throw_error("Corrupted file - bad header"); } @@ -269,7 +268,7 @@ sub _write_tag { my ($offset, $sig, $content) = @_; my $size = length( $content ); - $self->_storage->print_at( + $self->storage->print_at( $offset, $sig, pack($self->{byte_pack}, $size), $content, ); @@ -279,7 +278,7 @@ sub _write_tag { return { signature => $sig, start => $offset, - offset => $offset + SIG_SIZE + $self->{byte_size}, + offset => $offset + SIG_SIZE + $self->byte_size, content => $content, is_new => 1, }; @@ -288,17 +287,17 @@ sub _write_tag { sub _load_tag { my $self = shift; my ($offset) = @_; - my $storage = $self->_storage; + my $storage = $self->storage; my ($sig, $size) = unpack( "A $self->{byte_pack}", - $storage->read_at( $offset, SIG_SIZE + $self->{byte_size} ), + $storage->read_at( $offset, SIG_SIZE + $self->byte_size ), ); return { signature => $sig, start => $offset, - offset => $offset + SIG_SIZE + $self->{byte_size}, + offset => $offset + SIG_SIZE + $self->byte_size, content => $storage->read_at( undef, $size ), is_new => 0, }; @@ -307,12 +306,58 @@ sub _load_tag { sub _tag_size { my $self = shift; my ($size) = @_; - return SIG_SIZE + $self->{byte_size} + $size; + return SIG_SIZE + $self->byte_size + $size; } ################################################################################ -sub _storage { $_[0]{storage} } +sub storage { $_[0]{storage} } +sub byte_size { $_[0]{byte_size} } + +################################################################################ + +package DBM::Deep::Engine::Sector::Reference; + +our @ISA = qw( DBM::Deep::Engine::Sector ); + +sub _init { + my $self = shift; + + my $engine = $self->engine; + + my $leftover = $self->size - 3 - 2 * $engine->byte_size; + + my $offset = $engine->storage->request_space( $self->size ); + $engine->storage->print_at( $offset, + $self->type, + pack( $StP{1}, 0 ), # Recycled counter + pack( $StP{$engine->byte_size}, 0 ), # Chain loc + pack( $StP{$engine->byte_size}, 0 ), # Index/BList loc + pack( $StP{1}, 0 ), # Blessedness + pack( $StP{1}, 0 ), # Classname length + chr(0) x $leftover, # Zero-fill the data + ); + + return $offset; +} + +sub type { $_[0]{type} } + +package DBM::Deep::Engine::Sector; + +sub new { + my $self = bless $_[1], $_[0]; + Scalar::Util::weaken( $self->{engine} ); + $self->{offset} = $self->_init; + return $self; +} +sub _init {} + +sub engine { $_[0]{engine} } +sub offset { $_[0]{offset} } + +# This is in bytes +sub size { return 256 } 1; __END__