Added freespace management
rkinyon [Mon, 4 Dec 2006 03:26:27 +0000 (03:26 +0000)]
lib/DBM/Deep.pm
lib/DBM/Deep/Engine3.pm
lib/DBM/Deep/File.pm
t/27_filehandle.t
t/29_freespace_manager.t [deleted file]
t/40_freespace.t

index de806c3..da5cbc7 100644 (file)
@@ -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 = $@;
index 19f0849..5213030 100644 (file)
@@ -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;
index 8303834..649f0b9 100644 (file)
@@ -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;
 
index 7ae1a52..83e67d7 100644 (file)
@@ -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 (file)
index 336646e..0000000
+++ /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" );
-}
index 7f19011..0ab05b0 100644 (file)
@@ -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" );
-}