}
my @slots = $self->read_txn_slots;
- for my $i ( 0 .. @slots ) {
+ my $found;
+ for my $i ( 0 .. $#slots ) {
next if $slots[$i];
+
$slots[$i] = 1;
$self->set_trans_id( $i + 1 );
+ $found = 1;
last;
}
+ unless ( $found ) {
+ DBM::Deep->_throw_error( "Cannot allocate transaction ID" );
+ }
$self->write_txn_slots( @slots );
if ( !$self->trans_id ) {
sub read_txn_slots {
my $self = shift;
- return split '', unpack( 'b32',
+ my $bitfield_len = ($self->num_txns) / 8;
+ if ( $bitfield_len > int( $bitfield_len ) ) {
+ $bitfield_len = int( $bitfield_len ) + 1;
+ }
+ my $num_bits = $bitfield_len * 8;
+ return split '', unpack( 'b'.$num_bits,
$self->storage->read_at(
- $self->trans_loc, 4,
+ $self->trans_loc, $bitfield_len,
)
);
}
sub write_txn_slots {
my $self = shift;
+ my $bitfield_len = ($self->num_txns) / 8;
+ if ( $bitfield_len > int( $bitfield_len ) ) {
+ $bitfield_len = int( $bitfield_len ) + 1;
+ }
+ my $num_bits = $bitfield_len * 8;
$self->storage->print_at( $self->trans_loc,
- pack( 'b32', join('', @_) ),
+ pack( 'b'.$num_bits, join('', @_) ),
);
}
my $self = shift;
my $nt = $self->num_txns;
+ my $bitfield_len = ($nt) / 8;
+ if ( $bitfield_len > int( $bitfield_len ) ) {
+ $bitfield_len = int( $bitfield_len ) + 1;
+ }
- my $header_var = 1 + 1 + 1 + 1 + 4 + $STALE_SIZE * ($nt - 1) + 3 * $self->byte_size;
+ my $header_var = 1 + 1 + 1 + 1 + $bitfield_len + $STALE_SIZE * ($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('C' . $bitfield_len, 0 ), # Transaction activeness bitfield
pack($StP{$STALE_SIZE}.($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)
#XXX Set these less fragilely
$self->set_trans_loc( $header_fixed + 4 );
- $self->set_chains_loc( $header_fixed + 4 + 4 + $STALE_SIZE * ($nt-1) );
+ $self->set_chains_loc( $header_fixed + 4 + $bitfield_len + $STALE_SIZE * ($nt-1) );
return;
}
$self->{max_buckets} += 1;
$self->{data_sector_size} += 1;
- my $header_var = scalar(@values) + 4 + $STALE_SIZE * ($self->num_txns - 1) + 3 * $self->byte_size;
+ my $bitfield_len = ($self->num_txns) / 8;
+ if ( $bitfield_len > int( $bitfield_len ) ) {
+ $bitfield_len = int( $bitfield_len ) + 1;
+ }
+
+ my $header_var = scalar(@values) + $bitfield_len + $STALE_SIZE * ($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 + $STALE_SIZE * ($self->num_txns - 1) );
+ $self->set_chains_loc( $header_fixed + scalar(@values) + $bitfield_len + $STALE_SIZE * ($self->num_txns - 1) );
return length($buffer) + length($buffer2);
}
my $self = shift;
return ref($self)->new({
engine => $self->engine,
- data => $self->data,
type => $self->type,
+ data => $self->data,
});
}
return $self;
}
+#XXX Change here
sub size {
my $self = shift;
unless ( $self->{size} ) {