From: rkinyon Date: Tue, 11 Apr 2006 17:53:59 +0000 (+0000) Subject: Added ability for ::File to read and write transaction ID X-Git-Tag: 0-99_01~24 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=20b7f04742491a0dcc6b453625c06970092074e3;p=dbsrgits%2FDBM-Deep.git Added ability for ::File to read and write transaction ID --- diff --git a/lib/DBM/Deep/Engine.pm b/lib/DBM/Deep/Engine.pm index ddf16e4..df0b0e3 100644 --- a/lib/DBM/Deep/Engine.pm +++ b/lib/DBM/Deep/Engine.pm @@ -9,6 +9,10 @@ use Fcntl qw( :DEFAULT :flock :seek ); # File-wide notes: # * All the local($/,$\); are to protect read() and print() from -l. +# * To add to bucket_size, make sure you modify the following: +# - calculate_sizes() +# - _get_key_subloc() +# - add_bucket() - where the buckets are printed ## # Setup file and tag signatures. These should never change. @@ -117,6 +121,8 @@ sub write_file_header { pack('S', $self->{max_buckets}), ); + $self->_fileobj->set_transaction_offset( 13 ); + return; } @@ -571,7 +577,7 @@ sub split_index { my $keys = $tag->{content} . $md5 . pack($self->{long_pack}, $newtag_loc) . pack($self->{long_pack}, 0) # size - . pack($self->{long_pack}, 0); # transaction # + . pack($self->{long_pack}, 0); # transaction ID my @newloc = (); BUCKET: @@ -956,7 +962,7 @@ sub _get_key_subloc { my ($key, $subloc, $size, $transaction) = unpack( # This is 'a', not 'A'. Please read the pack() documentation for the # difference between the two and why it's important. - "a$self->{hash_size} $self->{long_pack} $self->{long_pack} $self->{long_pack}", + "a$self->{hash_size} $self->{long_pack}3", substr( $keys, ($idx * $self->{bucket_size}), @@ -984,14 +990,16 @@ sub _find_in_buckets { my @rv = ($subloc, $i * $self->{bucket_size}, $size); unless ( $subloc ) { - return @zero if !$exact && @zero and $trans_id; + if ( !$exact && @zero and $trans_id ) { + @rv = ($zero[2], $zero[0] * $self->{bucket_size}, $zero[3]); + } return @rv; } next BUCKET if $key ne $md5; # Save off the HEAD in case we need it. - @zero = @rv if $transaction_id == 0; + @zero = ($i,$key,$subloc,$size,$transaction_id) if $transaction_id == 0; next BUCKET if $transaction_id != $trans_id; diff --git a/lib/DBM/Deep/File.pm b/lib/DBM/Deep/File.pm index 2862ca5..f11a66a 100644 --- a/lib/DBM/Deep/File.pm +++ b/lib/DBM/Deep/File.pm @@ -27,8 +27,8 @@ sub new { filter_fetch_key => undef, filter_fetch_value => undef, - transaction_id => 0, - transaction_offset => 0, + transaction_id => 0, + transaction_offset => 0, }, $class; # Grab the parameters we want to use @@ -163,25 +163,76 @@ sub begin_transaction { my $fh = $self->{fh}; + $self->lock; + + seek( $fh, $self->{transaction_offset}, SEEK_SET ); + my $buffer; + read( $fh, $buffer, 4 ); + $buffer = unpack( 'N', $buffer ); + + for ( 1 .. 32 ) { + next if $buffer & (1 << ($_ - 1)); + $self->{transaction_id} = $_; + $buffer &= (1 << $_); + last; + } + seek( $fh, $self->{transaction_offset}, SEEK_SET ); + print( $fh pack( 'N', $buffer ) ); - $self->{transaction_id}++; + $self->unlock; + + return $self->{transaction_id}; } sub end_transaction { my $self = shift; -# seek( $fh, $self->{transaction_offset}, SEEK_SET ); + my $fh = $self->{fh}; + + $self->lock; + + seek( $fh, $self->{transaction_offset}, SEEK_SET ); + my $buffer; + read( $fh, $buffer, 4 ); + $buffer = unpack( 'N', $buffer ); + + # Unset $self->{transaction_id} bit + + seek( $fh, $self->{transaction_offset}, SEEK_SET ); + print( $fh pack( 'N', $buffer ) ); + + $self->unlock; $self->{transaction_id} = 0; } -sub transaction_id { +sub current_transactions { my $self = shift; - return $self->{transaction_id}; + my $fh = $self->{fh}; + + $self->lock; + + seek( $fh, $self->{transaction_offset}, SEEK_SET ); + my $buffer; + read( $fh, $buffer, 4 ); + $buffer = unpack( 'N', $buffer ); + + $self->unlock; + + my @transactions; + for ( 1 .. 32 ) { + if ( $buffer & (1 << ($_ - 1)) ) { + push @transactions, $_; + } + } + + return @transactions; } +sub transaction_id { return $_[0]->{transaction_id} } + #sub commit { #}