parent_key => undef,
storage => undef,
+ engine => undef,
}, $class;
- $self->{engine} = DBM::Deep::Engine3->new( { %{$args}, obj => $self } );
+
+ $args->{engine} = DBM::Deep::Engine3->new( { %{$args}, obj => $self } )
+ unless exists $args->{engine};
# Grab the parameters we want to use
foreach my $param ( keys %$self ) {
$self->_copy_node( $temp );
$self->unlock();
- my $classname = $self->_engine->get_classname( $self->_storage->transaction_id, $self->_base_offset );
+ my $classname = $self->_engine->get_classname( $self );
if ( defined $classname ) {
bless $temp, $classname;
}
type => $self->_type,
base_offset => $self->_base_offset,
storage => $self->_storage,
+ engine => $self->_engine,
parent => $self->{parent},
parent_key => $self->{parent_key},
);
sub begin_work {
my $self = shift->_get_self;
- return $self->_storage->begin_transaction;
+ return $self->_engine->begin_transaction( $self, @_ );
}
sub rollback {
my $self = shift->_get_self;
- return $self->_storage->end_transaction;
+ return $self->_engine->end_transaction( $self, @_ );
}
sub commit {
my $self = shift->_get_self;
- return $self->_storage->commit_transaction;
+ return $self->_engine->commit_transaction( $self, @_ );
}
##
$value = $self->_storage->{filter_store_value}->( $value );
}
- $self->_engine->write_value( $self->_storage->transaction_id, $self->_base_offset, $key, $value, $orig_key );
+ $self->_engine->write_value( $self, $key, $value, $orig_key );
$self->unlock();
##
$self->lock( LOCK_SH );
- my $result = $self->_engine->read_value( $self->_storage->transaction_id, $self->_base_offset, $key, $orig_key );
+ my $result = $self->_engine->read_value( $self, $key, $orig_key );
$self->unlock();
##
# Delete bucket
##
- my $value = $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $orig_key );
+ my $value = $self->_engine->delete_key( $self, $key, $orig_key );
if (defined $value && !ref($value) && $self->_storage->{filter_fetch_value}) {
$value = $self->_storage->{filter_fetch_value}->($value);
##
$self->lock( LOCK_SH );
- my $result = $self->_engine->key_exists( $self->_storage->transaction_id, $self->_base_offset, $key );
+ my $result = $self->_engine->key_exists( $self, $key );
$self->unlock();
while ( $key ) {
# Retrieve the key before deleting because we depend on next_key
my $next_key = $self->next_key( $key );
- $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $key );
+ $self->_engine->delete_key( $self, $key, $key );
$key = $next_key;
}
}
else {
my $size = $self->FETCHSIZE;
for my $key ( 0 .. $size - 1 ) {
- $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $key );
+ $self->_engine->delete_key( $self, $key, $key );
}
$self->STORESIZE( 0 );
}
use strict;
our $VERSION = q(0.99_03);
-our $DEBUG = 0;
use Scalar::Util ();
num_txns => 16, # HEAD plus 15 running txns
storage => undef,
- obj => undef,
}, $class;
if ( defined $args->{pack_size} ) {
next unless exists $args->{$param};
$self->{$param} = $args->{$param};
}
- Scalar::Util::weaken( $self->{obj} ) if $self->{obj};
$self->{byte_pack} = $StP{ $self->byte_size };
$self->{digest} = \&Digest::MD5::md5;
}
- #XXX HACK
- $self->{chains_loc} = 15;
-
return $self;
}
sub read_value {
my $self = shift;
- my ($trans_id, $base_offset, $key) = @_;
- print "read_value( $trans_id, $base_offset, $key )\n" if $DEBUG;
+ my ($obj, $key) = @_;
# This will be a Reference sector
- my $sector = $self->_load_sector( $base_offset )
- or die "How did read_value fail (no sector for '$base_offset')?!\n";
+ my $sector = $self->_load_sector( $obj->_base_offset )
+ or die "How did read_value fail (no sector for '$obj')?!\n";
my $key_md5 = $self->_apply_digest( $key );
sub get_classname {
my $self = shift;
- my ($trans_id, $base_offset) = @_;
- print "get_classname( $trans_id, $base_offset )\n" if $DEBUG;
+ my ($obj) = @_;
# This will be a Reference sector
- my $sector = $self->_load_sector( $base_offset )
- or die "How did read_value fail (no sector for '$base_offset')?!\n";
+ my $sector = $self->_load_sector( $obj->_base_offset )
+ or die "How did read_value fail (no sector for '$obj')?!\n";
return $sector->get_classname;
}
sub key_exists {
my $self = shift;
- my ($trans_id, $base_offset, $key) = @_;
- print "key_exists( $trans_id, $base_offset, $key )\n" if $DEBUG;
+ my ($obj, $key) = @_;
# This will be a Reference sector
- my $sector = $self->_load_sector( $base_offset )
- or die "How did key_exists fail (no sector for '$base_offset')?!\n";
+ my $sector = $self->_load_sector( $obj->_base_offset )
+ or die "How did key_exists fail (no sector for '$obj')?!\n";
my $key_md5 = $self->_apply_digest( $key );
sub delete_key {
my $self = shift;
- my ($trans_id, $base_offset, $key) = @_;
- print "delete_key( $trans_id, $base_offset, $key )\n" if $DEBUG;
+ my ($obj, $key) = @_;
- my $sector = $self->_load_sector( $base_offset )
- or die "How did delete_key fail (no sector for '$base_offset')?!\n";
+ my $sector = $self->_load_sector( $obj->_base_offset )
+ or die "How did delete_key fail (no sector for '$obj')?!\n";
my $key_md5 = $self->_apply_digest( $key );
sub write_value {
my $self = shift;
- my ($trans_id, $base_offset, $key, $value) = @_;
- print "write_value( $trans_id, $base_offset, $key, $value )\n" if $DEBUG;
+ my ($obj, $key, $value) = @_;
# This will be a Reference sector
- my $sector = $self->_load_sector( $base_offset )
- or die "How did write_value fail (no sector for '$base_offset')?!\n";
+ my $sector = $self->_load_sector( $obj->_base_offset )
+ or die "How did write_value fail (no sector for '$obj')?!\n";
my $key_md5 = $self->_apply_digest( $key );
tie @$value, 'DBM::Deep', {
base_offset => $value_sector->offset,
storage => $self->storage,
+ engine => $self,
};
@$value = @temp;
bless $value, 'DBM::Deep::Array' unless Scalar::Util::blessed( $value );
tie %$value, 'DBM::Deep', {
base_offset => $value_sector->offset,
storage => $self->storage,
+ engine => $self,
};
%$value = %temp;
sub get_next_key {
my $self = shift;
- my ($trans_id, $base_offset, $prev_key) = @_;
- print "get_next_key( $trans_id, $base_offset )\n" if $DEBUG;
+ my ($obj, $prev_key) = @_;
# XXX Need to add logic about resetting the iterator if any key in the reference has changed
unless ( $prev_key ) {
- $self->{iterator} = DBM::Deep::Engine::Iterator->new({
- base_offset => $base_offset,
- trans_id => $trans_id,
+ $obj->{iterator} = DBM::Deep::Engine::Iterator->new({
+ base_offset => $obj->_base_offset,
engine => $self,
});
}
- return $self->iterator->get_next_key;
+ return $obj->{iterator}->get_next_key;
}
################################################################################
return 1;
}
-################################################################################
+# begin_work
+sub begin_transaction {
+ my $self = shift;
+}
-sub _write_file_header {
+# rollback
+sub end_transaction {
my $self = shift;
+}
- my $header_fixed = length( SIG_FILE ) + 1 + 4 + 4;
- my $header_var = 1 + 1 + 2 * $self->byte_size;
-
- my $loc = $self->storage->request_space( $header_fixed + $header_var );
-
- $self->storage->print_at( $loc,
- SIG_FILE,
- SIG_HEADER,
- pack('N', 1), # header version - at this point, we're at 9 bytes
- pack('N', $header_var), # header size
- # --- Above is $header_fixed. Below is $header_var
- pack('C', $self->byte_size),
- pack('C', $self->max_buckets),
- pack($StP{$self->byte_size}, 0), # Start of free chain (blist size)
- pack($StP{$self->byte_size}, 0), # Start of free chain (data size)
- );
+# commit
+sub commit_transaction {
+ my $self = shift;
+}
- $self->set_chains_loc( $header_fixed + 2 );
+################################################################################
-# $self->storage->set_transaction_offset( $header_fixed );
+{
+ my $header_fixed = length( SIG_FILE ) + 1 + 4 + 4;
- return;
-}
+ sub _write_file_header {
+ my $self = shift;
-sub _read_file_header {
- my $self = shift;
+ my $header_var = 1 + 1 + 4 + 2 * $self->byte_size;
- my $header_fixed = length( SIG_FILE ) + 1 + 4 + 4;
+ my $loc = $self->storage->request_space( $header_fixed + $header_var );
- my $buffer = $self->storage->read_at( 0, $header_fixed );
- return unless length($buffer);
+ $self->storage->print_at( $loc,
+ SIG_FILE,
+ SIG_HEADER,
+ pack('N', 1), # header version - at this point, we're at 9 bytes
+ pack('N', $header_var), # header size
+ # --- Above is $header_fixed. Below is $header_var
+ pack('C', $self->byte_size),
+ pack('C', $self->max_buckets),
+ pack('N', 0 ), # Running transactions
+ pack($StP{$self->byte_size}, 0), # Start of free chain (blist size)
+ pack($StP{$self->byte_size}, 0), # Start of free chain (data size)
+ );
- my ($file_signature, $sig_header, $header_version, $size) = unpack(
- 'A4 A N N', $buffer
- );
+ $self->set_trans_loc( $header_fixed + 2 );
+ $self->set_chains_loc( $header_fixed + 6 );
- unless ( $file_signature eq SIG_FILE ) {
- $self->storage->close;
- DBM::Deep->_throw_error( "Signature not found -- file is not a Deep DB" );
+ return;
}
- unless ( $sig_header eq SIG_HEADER ) {
- $self->storage->close;
- DBM::Deep->_throw_error( "Old file version found." );
- }
+ sub _read_file_header {
+ my $self = shift;
- my $buffer2 = $self->storage->read_at( undef, $size );
- my @values = unpack( 'C C', $buffer2 );
+ my $buffer = $self->storage->read_at( 0, $header_fixed );
+ return unless length($buffer);
- $self->set_chains_loc( $header_fixed + 2 );
+ my ($file_signature, $sig_header, $header_version, $size) = unpack(
+ 'A4 A N N', $buffer
+ );
- # The transaction offset is the first thing after the fixed header section
- #$self->storage->set_transaction_offset( $header_fixed );
+ unless ( $file_signature eq SIG_FILE ) {
+ $self->storage->close;
+ DBM::Deep->_throw_error( "Signature not found -- file is not a Deep DB" );
+ }
- if ( @values < 2 || grep { !defined } @values ) {
- $self->storage->close;
- DBM::Deep->_throw_error("Corrupted file - bad header");
- }
+ unless ( $sig_header eq SIG_HEADER ) {
+ $self->storage->close;
+ DBM::Deep->_throw_error( "Old file version found." );
+ }
- #XXX Add warnings if values weren't set right
- @{$self}{qw(byte_size max_buckets)} = @values;
+ my $buffer2 = $self->storage->read_at( undef, $size );
+ my @values = unpack( 'C C', $buffer2 );
- my $header_var = 1 + 1 + 2 * $self->byte_size;
- unless ( $size eq $header_var ) {
- $self->storage->close;
- DBM::Deep->_throw_error( "Unexpected size found ($size <-> $header_var)." );
- }
+ $self->set_trans_loc( $header_fixed + 2 );
+ $self->set_chains_loc( $header_fixed + 6 );
+
+ if ( @values < 2 || grep { !defined } @values ) {
+ $self->storage->close;
+ DBM::Deep->_throw_error("Corrupted file - bad header");
+ }
+
+ #XXX Add warnings if values weren't set right
+ @{$self}{qw(byte_size max_buckets)} = @values;
- return length($buffer) + length($buffer2);
+ my $header_var = 1 + 1 + 4 + 2 * $self->byte_size;
+ unless ( $size eq $header_var ) {
+ $self->storage->close;
+ DBM::Deep->_throw_error( "Unexpected size found ($size <-> $header_var)." );
+ }
+
+ return length($buffer) + length($buffer2);
+ }
}
sub _load_sector {
sub hash_size { $_[0]{hash_size} }
sub num_txns { $_[0]{num_txns} }
sub max_buckets { $_[0]{max_buckets} }
-sub iterator { $_[0]{iterator} }
sub blank_md5 { chr(0) x $_[0]->hash_size }
+sub trans_loc { $_[0]{trans_loc} }
+sub set_trans_loc { $_[0]{trans_loc} = $_[1] }
+
sub chains_loc { $_[0]{chains_loc} }
sub set_chains_loc { $_[0]{chains_loc} = $_[1] }
type => $self->type,
base_offset => $self->offset,
storage => $self->engine->storage,
+ engine => $self->engine,
});
if ( $self->engine->storage->{autobless} ) {