}
my @slots = $self->read_txn_slots;
- for my $i ( 1 .. @slots ) {
+ for my $i ( 0 .. @slots ) {
next if $slots[$i];
$slots[$i] = 1;
- $self->set_trans_id( $i );
+ $self->set_trans_id( $i + 1 );
last;
}
$self->write_txn_slots( @slots );
my $read_loc = $entry
+ $self->hash_size
+ $self->byte_size
- + $self->trans_id * ( $self->byte_size + 4 );
+ + $self->byte_size
+ + ($self->trans_id - 1) * ( $self->byte_size + 4 );
my $data_loc = $self->storage->read_at( $read_loc, $self->byte_size );
$data_loc = unpack( $StP{$self->byte_size}, $data_loc );
$self->clear_entries;
my @slots = $self->read_txn_slots;
- $slots[$self->trans_id] = 0;
+ $slots[$self->trans_id-1] = 0;
$self->write_txn_slots( @slots );
$self->inc_txn_staleness_counter( $self->trans_id );
$self->set_trans_id( 0 );
my $head_loc = $self->storage->read_at( $base, $self->byte_size );
$head_loc = unpack( $StP{$self->byte_size}, $head_loc );
+
+ my $spot = $base + $self->byte_size + ($self->trans_id - 1) * ( $self->byte_size + 4 );
my $trans_loc = $self->storage->read_at(
- $base + $self->trans_id * ( $self->byte_size + 4 ), $self->byte_size,
+ $spot, $self->byte_size,
);
$self->storage->print_at( $base, $trans_loc );
$self->storage->print_at(
- $base + $self->trans_id * ( $self->byte_size + 4 ),
+ $spot,
pack( $StP{$self->byte_size} . ' N', (0) x 2 ),
);
$self->clear_entries;
my @slots = $self->read_txn_slots;
- $slots[$self->trans_id] = 0;
+ $slots[$self->trans_id-1] = 0;
$self->write_txn_slots( @slots );
$self->inc_txn_staleness_counter( $self->trans_id );
$self->set_trans_id( 0 );
sub get_running_txn_ids {
my $self = shift;
my @transactions = $self->read_txn_slots;
- my @trans_ids = grep { $transactions[$_] } 0 .. $#transactions;
+ my @trans_ids = map { $_+1} grep { $transactions[$_] } 0 .. $#transactions;
}
sub get_txn_staleness_counter {
# Hardcode staleness of 0 for the HEAD
return 0 unless $trans_id;
- my $x = unpack( 'N',
+ return unpack( 'N',
$self->storage->read_at(
- $self->trans_loc + 4 * $trans_id,
+ $self->trans_loc + 4 + 4 * ($trans_id - 1),
4,
)
);
- return $x;
}
sub inc_txn_staleness_counter {
return unless $trans_id;
$self->storage->print_at(
- $self->trans_loc + 4 * $trans_id,
+ $self->trans_loc + 4 + 4 * ($trans_id - 1),
pack( 'N', $self->get_txn_staleness_counter( $trans_id ) + 1 ),
);
}
my $nt = $self->num_txns;
- my $header_var = 1 + 1 + 1 + 1 + 4 + 4 * $nt + 3 * $self->byte_size;
+ my $header_var = 1 + 1 + 1 + 1 + 4 + 4 * ($nt - 1) + 3 * $self->byte_size;
my $loc = $self->storage->request_space( $header_fixed + $header_var );
pack('C', $self->data_sector_size - 1),
pack('C', $nt),
+#XXX This is a problem - it limits everything to 32 transactions
pack('N', 0 ), # Transaction activeness bitfield
- pack('N' . $nt, 0 x $nt ), # Transaction staleness counters
+ pack('N' . ($nt-1), 0 x ($nt-1) ), # 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)
#XXX Set these less fragilely
$self->set_trans_loc( $header_fixed + 4 );
- $self->set_chains_loc( $header_fixed + 4 + 4 + 4 * $nt );
+ $self->set_chains_loc( $header_fixed + 4 + 4 + 4 * ($nt-1) );
return;
}
DBM::Deep->_throw_error("Corrupted file - bad header");
}
- $self->set_trans_loc( $header_fixed + scalar(@values) );
- $self->set_chains_loc( $header_fixed + scalar(@values) + 4 + 4 * $self->num_txns );
-
#XXX Add warnings if values weren't set right
@{$self}{qw(byte_size max_buckets data_sector_size num_txns)} = @values;
$self->{max_buckets} += 1;
$self->{data_sector_size} += 1;
- my $header_var = scalar(@values) + 4 + 4 * $self->num_txns + 3 * $self->byte_size;
+ my $header_var = scalar(@values) + 4 + 4 * ($self->num_txns - 1) + 3 * $self->byte_size;
unless ( $size == $header_var ) {
$self->storage->close;
DBM::Deep->_throw_error( "Unexpected size found ($size <-> $header_var)." );
}
+ $self->set_trans_loc( $header_fixed + scalar(@values) );
+ $self->set_chains_loc( $header_fixed + scalar(@values) + 4 + 4 * ($self->num_txns - 1) );
+
return length($buffer) + length($buffer2);
}
}
my $self = shift;
unless ( $self->{bucket_size} ) {
my $e = $self->engine;
+ #XXX Convert the 4 to STALE_SIZE()
# Key + head (location) + transactions (location + staleness-counter)
- my $location_size = $e->byte_size + $e->num_txns * ( $e->byte_size + 4 );
+ my $location_size = $e->byte_size + $e->byte_size + ($e->num_txns - 1) * ($e->byte_size + 4);
$self->{bucket_size} = $e->hash_size + $location_size;
}
return $self->{bucket_size};
my $loc = $spot
+ $engine->hash_size
- + $engine->byte_size
- + $args->{trans_id} * ( $engine->byte_size + 4 );
+ + $engine->byte_size;
- $engine->storage->print_at( $loc,
- pack( $StP{$engine->byte_size}, $args->{value}->offset ),
- pack( 'N', $engine->get_txn_staleness_counter( $args->{trans_id} ) ),
- );
+ #XXX Convert the 4 to STALE_SIZE()
+ if ( $args->{trans_id} ) {
+ $loc += $engine->byte_size + ($args->{trans_id} - 1) * ( $engine->byte_size + 4 );
+
+ $engine->storage->print_at( $loc,
+ pack( $StP{$engine->byte_size}, $args->{value}->offset ),
+ pack( 'N', $engine->get_txn_staleness_counter( $args->{trans_id} ) ),
+ );
+ }
+ else {
+ $engine->storage->print_at( $loc,
+ pack( $StP{$engine->byte_size}, $args->{value}->offset ),
+ );
+ }
}
sub mark_deleted {
my $loc = $spot
+ $engine->hash_size
- + $engine->byte_size
- + $args->{trans_id} * ( $engine->byte_size + 4 );
+ + $engine->byte_size;
+
+ #XXX Convert the 4 to STALE_SIZE()
+ if ( $args->{trans_id} ) {
+ $loc += $engine->byte_size + ($args->{trans_id} - 1) * ( $engine->byte_size + 4 );
+
+ $engine->storage->print_at( $loc,
+ pack( $StP{$engine->byte_size}, 1 ), # 1 is the marker for deleted
+ pack( 'N', $engine->get_txn_staleness_counter( $args->{trans_id} ) ),
+ );
+ }
+ else {
+ $engine->storage->print_at( $loc,
+ pack( $StP{$engine->byte_size}, 1 ), # 1 is the marker for deleted
+ );
+ }
- $engine->storage->print_at( $loc,
- pack( $StP{$engine->byte_size}, 1 ), # 1 is the marker for deleted
- pack( 'N', $engine->get_txn_staleness_counter( $args->{trans_id} ) ),
- );
}
sub delete_md5 {
my $spot = $self->offset + $self->base_size
+ $args->{idx} * $self->bucket_size
+ $e->hash_size
- + $e->byte_size
- + $args->{trans_id} * ( $e->byte_size + 4 );
+ + $e->byte_size;
+
+ #XXX Convert the 4 to STALE_SIZE()
+ if ( $args->{trans_id} ) {
+ $spot += $e->byte_size + ($args->{trans_id} - 1) * ( $e->byte_size + 4 );
+ }
+ #XXX Convert the 4 to STALE_SIZE()
my $buffer = $e->storage->read_at(
$spot,
$e->byte_size + 4,
);
my ($loc, $staleness) = unpack( $StP{$e->byte_size} . ' N', $buffer );
- # We have found an entry that is old, so get rid of it
- if ( $staleness != (my $s = $e->get_txn_staleness_counter( $args->{trans_id} ) ) ) {
- $e->storage->print_at(
- $spot,
- pack( $StP{$e->byte_size} . ' N', (0) x 2 ),
- );
- $loc = 0;
+ if ( $args->{trans_id} ) {
+ # We have found an entry that is old, so get rid of it
+ if ( $staleness != (my $s = $e->get_txn_staleness_counter( $args->{trans_id} ) ) ) {
+ $e->storage->print_at(
+ $spot,
+ pack( $StP{$e->byte_size} . ' N', (0) x 2 ),
+ );
+ $loc = 0;
+ }
}
# If we're in a transaction and we never wrote to this location, try the