From: rkinyon Date: Mon, 4 Dec 2006 03:26:27 +0000 (+0000) Subject: Added freespace management X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3ed2643347601ac29a7bd2c39b02a73943819722;p=dbsrgits%2FDBM-Deep.git Added freespace management --- diff --git a/lib/DBM/Deep.pm b/lib/DBM/Deep.pm index de806c3..da5cbc7 100644 --- a/lib/DBM/Deep.pm +++ b/lib/DBM/Deep.pm @@ -135,8 +135,10 @@ sub _init { eval { local $SIG{'__DIE__'}; + $self->lock; $self->_engine->setup_fh( $self ); + $self->_storage->set_inode; $self->unlock; }; if ( $@ ) { my $e = $@; diff --git a/lib/DBM/Deep/Engine3.pm b/lib/DBM/Deep/Engine3.pm index 19f0849..5213030 100644 --- a/lib/DBM/Deep/Engine3.pm +++ b/lib/DBM/Deep/Engine3.pm @@ -203,9 +203,9 @@ sub write_value { $class = 'DBM::Deep::Engine::Sector::Scalar'; } -# if ( $blist->has_md5( $key_md5 ) ) { -# $blist->load_data_for( $key_md5 )->free; -# } + if ( $blist->has_md5( $key_md5 ) ) { + $blist->get_data_for( $key_md5 )->free; + } my $value_sector = $class->new({ engine => $self, @@ -300,9 +300,6 @@ sub setup_fh { } } - # We have to make sure we don't mess up when autoflush isn't turned on - $self->storage->set_inode; - return 1; } @@ -446,7 +443,7 @@ sub _add_free_sector { my $old_head = $self->storage->read_at( $self->chains_loc + $chains_offset, $self->byte_size ); - $self->storage->print_at( $self->chains_loc + $offset, + $self->storage->print_at( $self->chains_loc + $chains_offset, pack( $StP{$self->byte_size}, $offset ), ); @@ -853,6 +850,7 @@ sub delete_md5 { # Save the location so that we can free the data my $location = $self->get_data_location_for( $idx ); + my $key_sector = $self->get_key_for( $idx ); my $spot = $self->offset + $self->base_size + $idx * $self->bucket_size; $engine->storage->print_at( $spot, @@ -863,10 +861,10 @@ sub delete_md5 { chr(0) x $self->bucket_size, ); + $key_sector->free; + my $data_sector = $self->engine->_load_sector( $location ); my $data = $data_sector->data; - - # Free the data (somehow) $data_sector->free; return $data; diff --git a/lib/DBM/Deep/File.pm b/lib/DBM/Deep/File.pm index 8303834..649f0b9 100644 --- a/lib/DBM/Deep/File.pm +++ b/lib/DBM/Deep/File.pm @@ -118,7 +118,7 @@ sub close { sub set_inode { my $self = shift; - unless ( $self->{inode} ) { + unless ( defined $self->{inode} ) { my @stats = stat($self->{fh}); $self->{inode} = $stats[1]; $self->{end} = $stats[7]; @@ -192,24 +192,6 @@ sub request_space { return $loc; } -#sub release_space { -# my $self = shift; -# my ($size, $loc) = @_; -# -# local($/,$\); -# -# my $next_loc = 0; -# -# my $fh = $self->{fh}; -# seek( $fh, $loc + $self->{file_offset}, SEEK_SET ); -# print( $fh SIG_FREE -# . pack($self->{long_pack}, $size ) -# . pack($self->{long_pack}, $next_loc ) -# ); -# -# return; -#} - ## # If db locking is set, flock() the db file. If called multiple # times before unlock(), then the same number of unlocks() must @@ -236,7 +218,7 @@ sub lock { # double-check file inode, in case another process # has optimize()d our file while we were waiting. - if ($stats[1] != $self->{inode}) { + if (defined($self->{inode}) && $stats[1] != $self->{inode}) { $self->close; $self->open; diff --git a/t/27_filehandle.t b/t/27_filehandle.t index 7ae1a52..83e67d7 100644 --- a/t/27_filehandle.t +++ b/t/27_filehandle.t @@ -79,7 +79,6 @@ __END_FH__ is( $db->{x}, 'b', 'and it was stored' ); } - { open my $fh, '<', $filename; my $db = DBM::Deep->new({ diff --git a/t/29_freespace_manager.t b/t/29_freespace_manager.t deleted file mode 100644 index 336646e..0000000 --- a/t/29_freespace_manager.t +++ /dev/null @@ -1,31 +0,0 @@ -use strict; - -use Test::More tests => 3; -use t::common qw( new_fh ); - -use_ok( 'DBM::Deep' ); - -my ($fh, $filename) = new_fh(); -my $db = DBM::Deep->new({ - file => $filename, - autoflush => 1, -}); - -$db->{foo} = 'abcd'; - -my $s1 = -s $filename; - -delete $db->{foo}; - -my $s2 = -s $filename; - -is( $s2, $s1, "delete doesn't recover freespace" ); - -$db->{bar} = 'a'; - -my $s3 = -s $filename; - -TODO: { - local $TODO = "Freespace manager doesn't work yet"; - is( $s3, $s1, "Freespace is reused" ); -} diff --git a/t/40_freespace.t b/t/40_freespace.t index 7f19011..0ab05b0 100644 --- a/t/40_freespace.t +++ b/t/40_freespace.t @@ -15,10 +15,7 @@ $db->{foo} = '1234'; my $size = -s $filename; $db->{foo} = '2345'; -TODO: { - local $TODO = "Still writing freespace code"; cmp_ok( $size, '==', -s $filename, "Overwrite doesn't change size" ); -} $size = -s $filename; delete $db->{foo}; @@ -26,7 +23,4 @@ cmp_ok( $size, '==', -s $filename, "Deleted space isn't released" ); $size = -s $filename; $db->{bar} = '2345'; -TODO: { - local $TODO = "Still writing freespace code"; cmp_ok( $size, '==', -s $filename, "Added a new key after a delete reuses space" ); -}