staleness size now fully parameterized
rkinyon [Wed, 27 Dec 2006 04:41:19 +0000 (04:41 +0000)]
lib/DBM/Deep/Engine3.pm

index e052868..0da89a8 100644 (file)
@@ -27,6 +27,7 @@ sub SIG_BLIST    () { 'B'    }
 sub SIG_FREE     () { 'F'    }
 sub SIG_KEYS     () { 'K'    }
 sub SIG_SIZE     () {  1     }
+sub STALE_SIZE   () {  1     }
 
 ################################################################################
 
@@ -516,7 +517,7 @@ sub clear_entries {
     sub _write_file_header {
         my $self = shift;
 
-        my $header_var = 1 + 1 + 4 + 4 * $self->num_txns + 2 * $self->byte_size;
+        my $header_var = 1 + 1 + 4 + 4 * $self->num_txns + 3 * $self->byte_size;
 
         my $loc = $self->storage->request_space( $header_fixed + $header_var );
 
@@ -532,6 +533,7 @@ sub clear_entries {
             pack('N' . $self->num_txns, 0 x $self->num_txns ), # Transaction staleness counters
             pack($StP{$self->byte_size}, 0), # Start of free chain (blist size)
             pack($StP{$self->byte_size}, 0), # Start of free chain (data size)
+            pack($StP{$self->byte_size}, 0), # Start of free chain (index size)
         );
 
         $self->set_trans_loc( $header_fixed + 2 );
@@ -574,7 +576,7 @@ sub clear_entries {
         #XXX Add warnings if values weren't set right
         @{$self}{qw(byte_size max_buckets)} = @values;
 
-        my $header_var = 1 + 1 + 4 + 4 * $self->num_txns + 2 * $self->byte_size;
+        my $header_var = 1 + 1 + 4 + 4 * $self->num_txns + 3 * $self->byte_size;
         unless ( $size eq $header_var ) {
             $self->storage->close;
             DBM::Deep->_throw_error( "Unexpected size found ($size <-> $header_var)." );
@@ -606,6 +608,13 @@ sub _load_sector {
             offset => $offset,
         });
     }
+    elsif ( $type eq $self->SIG_INDEX ) {
+        return DBM::Deep::Engine::Sector::Index->new({
+            engine => $self,
+            type   => $type,
+            offset => $offset,
+        });
+    }
     elsif ( $type eq $self->SIG_NULL ) {
         return DBM::Deep::Engine::Sector::Null->new({
             engine => $self,
@@ -633,6 +642,7 @@ sub _apply_digest {
     return $self->{digest}->(@_);
 }
 
+#XXX Parameterize the staleness counter stuff here
 sub _add_free_sector {
     my $self = shift;
     my ($offset, $size) = @_;
@@ -650,9 +660,9 @@ sub _add_free_sector {
     my $storage = $self->storage;
 
     # Increment staleness.
-    my $staleness = unpack( $StP{1}, $storage->read_at( $offset + 1, 1 ) );
-    $staleness = ($staleness + 1 ) % ( 2 ** ( 8 * 1 ) );
-    $storage->print_at( $offset + 1, pack( $StP{1}, $staleness ) );
+    my $staleness = unpack( $StP{STALE_SIZE()}, $storage->read_at( $offset + SIG_SIZE, STALE_SIZE ) );
+    $staleness = ($staleness + 1 ) % ( 2 ** ( 8 * STALE_SIZE ) );
+    $storage->print_at( $offset + SIG_SIZE, pack( $StP{STALE_SIZE()}, $staleness ) );
 
     my $old_head = $storage->read_at( $self->chains_loc + $chains_offset, $self->byte_size );
 
@@ -661,7 +671,7 @@ sub _add_free_sector {
     );
 
     # Record the old head in the new sector after the signature and staleness counter
-    $storage->print_at( $offset + 1 + 1, $old_head );
+    $storage->print_at( $offset + SIG_SIZE + STALE_SIZE, $old_head );
 }
 
 sub _request_sector {
@@ -693,7 +703,7 @@ sub _request_sector {
     }
 
     # Read the new head after the signature and the staleness counter
-    my $new_head = $self->storage->read_at( $loc + 1 + 1, $self->byte_size );
+    my $new_head = $self->storage->read_at( $loc + SIG_SIZE + STALE_SIZE, $self->byte_size );
     $self->storage->print_at( $self->chains_loc + $chains_offset, $new_head );
 
     return $loc;
@@ -816,7 +826,10 @@ sub engine { $_[0]{engine} }
 sub offset { $_[0]{offset} }
 sub type   { $_[0]{type} }
 
-sub base_size { 1 + 1 } # Size of sig + staleness counter
+sub base_size {
+   my $self = shift;
+   return $self->engine->SIG_SIZE + $self->engine->STALE_SIZE;
+}
 
 sub free {
     my $self = shift;
@@ -909,7 +922,7 @@ sub _init {
 
             $engine->storage->print_at( $curr_offset, $self->type ); # Sector type
             # Skip staleness
-            $engine->storage->print_at( $curr_offset + 1 + 1,
+            $engine->storage->print_at( $curr_offset + $self->base_size,
                 pack( $StP{$engine->byte_size}, $next_offset ),  # Chain loc
                 pack( $StP{1}, $this_len ),                      # Data length
                 $chunk,                                          # Data to be stored in this sector
@@ -996,36 +1009,37 @@ our @ISA = qw( DBM::Deep::Engine::Sector::Data );
 sub _init {
     my $self = shift;
 
-    my $engine = $self->engine;
+    my $e = $self->engine;
 
     unless ( $self->offset ) {
         my $classname = Scalar::Util::blessed( delete $self->{data} );
-        my $leftover = $self->size - $self->base_size - 2 * $engine->byte_size;
+        my $leftover = $self->size - $self->base_size - 2 * $e->byte_size;
 
         my $class_offset = 0;
         if ( defined $classname ) {
             my $class_sector = DBM::Deep::Engine::Sector::Scalar->new({
-                engine => $self->engine,
+                engine => $e,
                 data   => $classname,
             });
             $class_offset = $class_sector->offset;
         }
 
-        $self->{offset} = $engine->_request_sector( $self->size );
-        $engine->storage->print_at( $self->offset, $self->type ); # Sector type
+        $self->{offset} = $e->_request_sector( $self->size );
+        $e->storage->print_at( $self->offset, $self->type ); # Sector type
         # Skip staleness counter
-        $engine->storage->print_at( $self->offset + $self->base_size,
-            pack( $StP{$engine->byte_size}, 0 ),             # Index/BList loc
-            pack( $StP{$engine->byte_size}, $class_offset ), # Classname loc
+        $e->storage->print_at( $self->offset + $self->base_size,
+            pack( $StP{$e->byte_size}, 0 ),             # Index/BList loc
+            pack( $StP{$e->byte_size}, $class_offset ), # Classname loc
             chr(0) x $leftover,                              # Zero-fill the rest
         );
     }
     else {
-        $self->{type} = $engine->storage->read_at( $self->offset, 1 );
+        $self->{type} = $e->storage->read_at( $self->offset, 1 );
     }
 
     $self->{staleness} = unpack(
-        $StP{1}, $engine->storage->read_at( $self->offset + 1, 1 ),
+        $StP{$e->STALE_SIZE},
+        $e->storage->read_at( $self->offset + $e->SIG_SIZE, $e->STALE_SIZE ),
     );
 
     return;
@@ -1488,9 +1502,6 @@ sub get_key_for {
     return $self->engine->_load_sector( $location );
 }
 
-1;
-__END__
-
 package DBM::Deep::Engine::Sector::Index;
 
 our @ISA = qw( DBM::Deep::Engine::Sector );
@@ -1507,14 +1518,10 @@ sub _init {
         $engine->storage->print_at( $self->offset, $engine->SIG_BLIST ); # Sector type
         # Skip staleness counter
         $engine->storage->print_at( $self->offset + $self->base_size,
-            chr(0) x $leftover, # Zero-fill the data
+            chr(0) x $leftover, # Zero-fill the rest
         );
     }
 
-    if ( $self->{key_md5} ) {
-        $self->find_md5;
-    }
-
     return $self;
 }
 
@@ -1522,7 +1529,7 @@ sub size {
     my $self = shift;
     unless ( $self->{size} ) {
         my $e = $self->engine;
-        $self->{size} = $self->base_size + $e->max_buckets * $self->bucket_size; # Base + numbuckets * bucketsize
+        $self->{size} = $self->base_size + $e->byte_size * $e->hash_chars;
     }
     return $self->{size};
 }