-#TODO: Convert this to a string
package DBM::Deep::Engine::Sector::Reference;
use 5.006_000;
use strict;
use warnings FATAL => 'all';
-use Scalar::Util ();
+use base qw( DBM::Deep::Engine::Sector::Data );
-use DBM::Deep::Null;
+my $STALE_SIZE = 2;
-use DBM::Deep::Engine::Sector::Data;
-our @ISA = qw( DBM::Deep::Engine::Sector::Data );
+# Please refer to the pack() documentation for further information
+my %StP = (
+ 1 => 'C', # Unsigned char value (no order needed as it's just one byte)
+ 2 => 'n', # Unsigned short in "network" (big-endian) order
+ 4 => 'N', # Unsigned long in "network" (big-endian) order
+ 8 => 'Q', # Usigned quad (no order specified, presumably machine-dependent)
+);
sub _init {
my $self = shift;
my $e = $self->engine;
unless ( $self->offset ) {
- $self->{staleness} = 0;
- $self->{offset} = $e->_request_data_sector( $self->size );
+ my $classname = Scalar::Util::blessed( delete $self->{data} );
+ my $leftover = $self->size - $self->base_size - 3 * $e->byte_size;
my $class_offset = 0;
- my $classname = Scalar::Util::blessed( delete $self->{data} );
if ( defined $classname ) {
my $class_sector = DBM::Deep::Engine::Sector::Scalar->new({
engine => $e,
$class_offset = $class_sector->offset;
}
- my $string = chr(0) x $self->size;
- substr( $string, 0, 1, $self->type );
- substr( $string, $self->base_size, 3 * $e->byte_size,
- pack( $e->StP($e->byte_size), 0 ) # Index/BList loc
- . pack( $e->StP($e->byte_size), $class_offset ) # Classname loc
- . pack( $e->StP($e->byte_size), 1 ) # Initial refcount
+ $self->{offset} = $e->_request_data_sector( $self->size );
+ $e->storage->print_at( $self->offset, $self->type ); # Sector type
+ # Skip staleness counter
+ $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
+ pack( $StP{$e->byte_size}, 1 ), # Initial refcount
+ chr(0) x $leftover, # Zero-fill the rest
);
- $e->storage->print_at( $self->offset, $string );
}
else {
$self->{type} = $e->storage->read_at( $self->offset, 1 );
-
- $self->{staleness} = unpack(
- $e->StP($DBM::Deep::Engine::STALE_SIZE),
- $e->storage->read_at( $self->offset + $e->SIG_SIZE, $DBM::Deep::Engine::STALE_SIZE ),
- );
}
+ $self->{staleness} = unpack(
+ $StP{$STALE_SIZE},
+ $e->storage->read_at( $self->offset + $e->SIG_SIZE, $STALE_SIZE ),
+ );
+
return;
}
my $self = shift;
my ($args) = @_;
- # XXX What should happen if this fails?
+ # This can return nothing if we are deleting an entry in a hashref that was
+ # auto-vivified as part of the delete process. For example:
+ # my $x = {};
+ # delete $x->{foo}{bar};
my $blist = $self->get_bucket_list({
key_md5 => $args->{key_md5},
- }) or DBM::Deep->_throw_error( "How did delete_key fail (no blist)?!" );
+ }) or return;
# Save the location so that we can free the data
my $location = $blist->get_data_location_for({
my $e = $self->engine;
my $blist_loc = $e->storage->read_at( $self->offset + $self->base_size, $e->byte_size );
- return unpack( $e->StP($e->byte_size), $blist_loc );
+ return unpack( $StP{$e->byte_size}, $blist_loc );
}
sub get_bucket_list {
});
$engine->storage->print_at( $self->offset + $self->base_size,
- pack( $engine->StP($engine->byte_size), $blist->offset ),
+ pack( $StP{$engine->byte_size}, $blist->offset ),
);
return $blist;
$sector->find_md5( $args->{key_md5} );
# See whether or not we need to reindex the bucketlist
- # Yes, the double-braces are there for a reason. if() doesn't create a redo-able block,
- # so we have to create a bare block within the if() for redo-purposes. Patch and idea
- # submitted by sprout@cpan.org. -RobK, 2008-01-09
+ # Yes, the double-braces are there for a reason. if() doesn't create a
+ # redo-able block, so we have to create a bare block within the if() for
+ # redo-purposes.
+ # Patch and idea submitted by sprout@cpan.org. -RobK, 2008-01-09
if ( !$sector->has_md5 && $args->{create} && $sector->{idx} == -1 ) {{
my $redo;
);
} else {
$engine->storage->print_at( $self->offset + $self->base_size,
- pack( $engine->StP($engine->byte_size), $new_index->offset ),
+ pack( $StP{$engine->byte_size}, $new_index->offset ),
);
}
my $e = $self->engine;
return unpack(
- $e->StP($e->byte_size),
+ $StP{$e->byte_size},
$e->storage->read_at(
$self->offset + $self->base_size + 1 * $e->byte_size, $e->byte_size,
),
my $e = $self->engine;
return unpack(
- $e->StP($e->byte_size),
+ $StP{$e->byte_size},
$e->storage->read_at(
$self->offset + $self->base_size + 2 * $e->byte_size, $e->byte_size,
),
my $e = $self->engine;
$e->storage->print_at(
$self->offset + $self->base_size + 2 * $e->byte_size,
- pack( $e->StP($e->byte_size), $num ),
+ pack( $StP{$e->byte_size}, $num ),
);
}
-
1;
__END__
-