sub SIG_FREE () { 'F' }
sub SIG_KEYS () { 'K' }
sub SIG_SIZE () { 1 }
+sub STALE_SIZE () { 1 }
################################################################################
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 );
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 );
#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)." );
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,
return $self->{digest}->(@_);
}
+#XXX Parameterize the staleness counter stuff here
sub _add_free_sector {
my $self = shift;
my ($offset, $size) = @_;
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 );
);
# 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 {
}
# 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;
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;
$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
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;
return $self->engine->_load_sector( $location );
}
-1;
-__END__
-
package DBM::Deep::Engine::Sector::Index;
our @ISA = qw( DBM::Deep::Engine::Sector );
$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;
}
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};
}