From: rkinyon Date: Thu, 27 Sep 2007 19:16:18 +0000 (+0000) Subject: Fixed the bug revealed by making bucketlists properly clean up after themselves X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=90fb1a24b98149740d5ade41b24effd784e611d8;p=dbsrgits%2FDBM-Deep.git Fixed the bug revealed by making bucketlists properly clean up after themselves --- diff --git a/lib/DBM/Deep/Engine.pm b/lib/DBM/Deep/Engine.pm index 00313d8..c5b3363 100644 --- a/lib/DBM/Deep/Engine.pm +++ b/lib/DBM/Deep/Engine.pm @@ -564,8 +564,8 @@ sub get_txn_staleness_counter { return unpack( $StP{$STALE_SIZE}, $self->storage->read_at( - $self->trans_loc + 4 + $STALE_SIZE * ($trans_id - 1), - 4, + $self->trans_loc + $self->txn_bitfield_len + $STALE_SIZE * ($trans_id - 1), + $STALE_SIZE, ) ); } @@ -578,7 +578,7 @@ sub inc_txn_staleness_counter { return unless $trans_id; $self->storage->print_at( - $self->trans_loc + 4 + $STALE_SIZE * ($trans_id - 1), + $self->trans_loc + $self->txn_bitfield_len + $STALE_SIZE * ($trans_id - 1), pack( $StP{$STALE_SIZE}, $self->get_txn_staleness_counter( $trans_id ) + 1 ), ); } @@ -893,12 +893,12 @@ sub _dump_file { 'I' => DBM::Deep::Engine::Sector::Index->new({engine=>$self,offset=>1})->size, ); + my $return = ""; # Read the free sector chains my %sectors; foreach my $multiple ( 0 .. 2 ) { - my $chains_offset = $multiple * $self->byte_size; - - my $old_loc = $self->chains_loc + $chains_offset; + $return .= "Chains($types{$multiple}):"; + my $old_loc = $self->chains_loc + $multiple * $self->byte_size; while ( 1 ) { my $loc = unpack( $StP{$self->byte_size}, @@ -912,10 +912,11 @@ sub _dump_file { $sectors{ $types{$multiple} }{ $loc } = undef; $old_loc = $loc + SIG_SIZE + $STALE_SIZE; + $return .= " $loc"; } + $return .= $/; } - my $return = ""; SECTOR: while ( $spot < $self->storage->{end} ) { # Read each sector in order. @@ -931,7 +932,7 @@ sub _dump_file { } } - die "Didn't find free sector for $spot in chains\n"; + die "********\n$return\nDidn't find free sector for $spot in chains\n********\n"; } else { $return .= sprintf "%08d: %s %04d", $spot, $sector->type, $sector->size; @@ -1497,6 +1498,8 @@ sub delete_key { my @trans_ids = $self->engine->get_running_txn_ids; + # If we're the HEAD and there are running txns, then we need to clone this value to the other + # transactions to preserve Isolation. if ( $self->engine->trans_id == 0 ) { if ( @trans_ids ) { foreach my $other_trans_id ( @trans_ids ) { @@ -1655,6 +1658,7 @@ sub get_bucket_list { ); } + $sector->clear; $sector->free; $sector = $blist_cache{ ord( substr( $args->{key_md5}, $i, 1 ) ) }; @@ -1789,6 +1793,13 @@ sub _init { return $self; } +sub clear { + my $self = shift; + $self->engine->storage->print_at( $self->offset + $self->base_size, + chr(0) x ($self->size - $self->base_size), # Zero-fill the data + ); +} + sub size { my $self = shift; unless ( $self->{size} ) {