From: rkinyon Date: Thu, 30 Nov 2006 03:58:40 +0000 (+0000) Subject: Added in storage of the key at the hash instead of as part of the value X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=4eee718c4368dafd6ed31c98df9b18853700e13f;p=dbsrgits%2FDBM-Deep.git Added in storage of the key at the hash instead of as part of the value --- diff --git a/lib/DBM/Deep/Engine3.pm b/lib/DBM/Deep/Engine3.pm index 6c4341b..062ab8d 100644 --- a/lib/DBM/Deep/Engine3.pm +++ b/lib/DBM/Deep/Engine3.pm @@ -28,9 +28,6 @@ sub SIG_FREE () { 'F' } sub SIG_KEYS () { 'K' } sub SIG_SIZE () { 1 } -# This is the transaction ID for the HEAD -sub HEAD () { 0 } - ################################################################################ # Please refer to the pack() documentation for further information @@ -107,16 +104,15 @@ sub read_value { my ($trans_id, $base_offset, $key) = @_; # This will be a Reference sector - my $sector = $self->_load_sector( $base_offset ); - die "How did this fail (no sector for '$base_offset')?!\n" unless $sector; + my $sector = $self->_load_sector( $base_offset ) + or die "How did this fail (no sector for '$base_offset')?!\n"; my $key_md5 = $self->_apply_digest( $key ); # XXX What should happen if this fails? my $blist = $sector->get_bucket_list({ key_md5 => $key_md5, - }); - die "How did this fail (no blist)?!\n" unless $blist; + }) or die "How did this fail (no blist)?!\n"; my $value_sector = $blist->get_data_for( $key_md5 ); return if ! $value_sector; @@ -129,16 +125,15 @@ sub key_exists { my ($trans_id, $base_offset, $key) = @_; # This will be a Reference sector - my $sector = $self->_load_sector( $base_offset ); - die "How did this fail (no sector for '$base_offset')?!\n" unless $sector; + my $sector = $self->_load_sector( $base_offset ) + or die "How did this fail (no sector for '$base_offset')?!\n"; my $key_md5 = $self->_apply_digest( $key ); # XXX What should happen if this fails? my $blist = $sector->get_bucket_list({ key_md5 => $key_md5, - }); - die "How did this fail (no blist)?!\n" unless $blist; + }) or die "How did this fail (no blist)?!\n"; # exists() returns 1 or '' for true/false. return $blist->has_md5( $key_md5 ) ? 1 : ''; @@ -148,16 +143,15 @@ sub delete_key { my $self = shift; my ($trans_id, $base_offset, $key) = @_; - my $sector = $self->_load_sector( $base_offset ); - die "How did this fail (no sector for '$base_offset')?!\n" unless $sector; + my $sector = $self->_load_sector( $base_offset ) + or die "How did this fail (no sector for '$base_offset')?!\n"; my $key_md5 = $self->_apply_digest( $key ); # XXX What should happen if this fails? my $blist = $sector->get_bucket_list({ key_md5 => $key_md5, - }); - die "How did this fail (no blist)?!\n" unless $blist; + }) or die "How did this fail (no blist)?!\n"; return $blist->delete_md5( $key_md5 ); } @@ -167,8 +161,8 @@ sub write_value { my ($trans_id, $base_offset, $key, $value) = @_; # This will be a Reference sector - my $sector = $self->_load_sector( $base_offset ); - die "How did this fail (no sector for '$base_offset')?!\n" unless $sector; + my $sector = $self->_load_sector( $base_offset ) + or die "How did this fail (no sector for '$base_offset')?!\n"; my $key_md5 = $self->_apply_digest( $key ); @@ -176,29 +170,61 @@ sub write_value { my $blist = $sector->get_bucket_list({ key_md5 => $key_md5, create => 1, - }); - die "How did this fail (no blist)?!\n" unless $blist; + }) or die "How did this fail (no blist)?!\n"; - my $value_sector; + my $class; if ( !defined $value ) { - $value_sector = DBM::Deep::Engine::Sector::Null->new({ - engine => $self, - data => $value, - }); + $class = 'DBM::Deep::Engine::Sector::Null'; } else { - $value_sector = DBM::Deep::Engine::Sector::Scalar->new({ - engine => $self, - data => $value, - }); + $class = 'DBM::Deep::Engine::Sector::Scalar'; } - $blist->write_md5( $key_md5, $value_sector->offset ); + my $value_sector = $class->new({ + engine => $self, + data => $value, + }); + + $blist->write_md5( $key_md5, $key, $value_sector->offset ); } sub get_next_key { my $self = shift; my ($trans_id, $base_offset) = @_; + + # This will be a Reference sector + my $sector = $self->_load_sector( $base_offset ) + or die "How did this fail (no sector for '$base_offset')?!\n"; + + return; + + # This is FIRSTKEY + if ( @_ == 2 ) { +# my $blist = $sector->get_bucket_list({ +# key_md5 => $key_md5, +# }) or die "How did this fail (no blist)?!\n"; +# +# return $blist->get_key_for_idx( 0 ); + } + + # This is NEXTKEY + + my $temp; + if ( @_ > 2 ) { + $temp = { + prev_md5 => $self->_apply_digest($_[2]), + return_next => 0, + }; + } + else { + $temp = { + prev_md5 => $self->blank_md5, + return_next => 1, + }; + } + + #return $self->traverse_index( $temp, $_val_offset, 0 ); + return; } ################################################################################ @@ -507,6 +533,7 @@ sub get_blist_loc { sub get_bucket_list { my $self = shift; my ($args) = @_; + $args ||= {}; # XXX Add in check here for recycling? @@ -533,10 +560,21 @@ sub get_bucket_list { }); } +sub get_first_key { + my $self = shift; + + my $blist = $self->get_bucket_list(); +} + +sub get_key_after { +} + package DBM::Deep::Engine::Sector::BucketList; our @ISA = qw( DBM::Deep::Engine::Sector ); +sub idx_for_txn { return $_[1] + 1 } + sub _init { my $self = shift; @@ -560,15 +598,16 @@ sub base_size { 2 } # Sig + recycled counter sub size { my $self = shift; - my $engine = $self->engine; - return $self->base_size + $engine->max_buckets * $self->bucket_size; # Base + numbuckets * bucketsize + my $e = $self->engine; + return $self->base_size + $e->max_buckets * $self->bucket_size; # Base + numbuckets * bucketsize } sub bucket_size { my $self = shift; my $e = $self->engine; - my $locs_size = $e->num_txns * $e->byte_size; # Pointer to data with magic values to indicate status - return $e->hash_size + $locs_size; # Hash + txn holders + # Key + transactions + my $locs_size = (1 + $e->num_txns ) * $e->byte_size; + return $e->hash_size + $locs_size; } sub has_md5 { @@ -581,7 +620,6 @@ sub find_md5 { my $self = shift; my ($md5) = @_; - # Make sure we don't hit the fencepost error foreach my $idx ( 0 .. $self->engine->max_buckets - 1 ) { my $potential = $self->engine->storage->read_at( $self->offset + $self->base_size + $idx * $self->bucket_size, $self->engine->hash_size, @@ -596,12 +634,25 @@ sub find_md5 { sub write_md5 { my $self = shift; - my ($md5, $value_loc) = @_; + my ($md5, $key, $value_loc) = @_; my $engine = $self->engine; my ($found, $idx) = $self->find_md5( $md5 ); - $engine->storage->print_at( $self->offset + $self->base_size + $idx * $self->bucket_size, - $md5, # The actual MD5 + my $spot = $self->offset + $self->base_size + $idx * $self->bucket_size; + + unless ($found) { + my $key_sector = DBM::Deep::Engine::Sector::Scalar->new({ + engine => $self->engine, + data => $key, + }); + + $engine->storage->print_at( $spot, + $md5, + $key_sector->offset, + ); + } + + $engine->storage->print_at( $spot + $self->engine->hash_size + $self->engine->byte_size, pack( $StP{$engine->byte_size}, $value_loc ), # The pointer to the data in the HEAD ); } @@ -613,10 +664,17 @@ sub delete_md5 { my $engine = $self->engine; my ($found, $idx) = $self->find_md5( $md5 ); return 1 unless $found; + + # Save the location so that we can free the data my $location = $self->get_location_for( $idx ); - $engine->storage->print_at( $self->offset + $self->base_size + $idx * $self->bucket_size, - $self->engine->blank_md5, # The blank MD5 - pack( $StP{$engine->byte_size}, 0 ), # The pointer to the data in the HEAD + + my $spot = $self->offset + $self->base_size + $idx * $self->bucket_size; + $engine->storage->print_at( $spot, + $engine->storage->read_at( + $spot + $self->bucket_size, + $self->bucket_size * ( $engine->num_txns - $idx - 1 ), + ), + chr(0) x $self->bucket_size, ); return 1; @@ -627,7 +685,8 @@ sub get_location_for { my ($idx) = @_; my $location = $self->engine->storage->read_at( - $self->offset + $self->base_size + $idx * $self->bucket_size + $self->engine->hash_size, $self->engine->byte_size, + $self->offset + $self->base_size + $idx * $self->bucket_size + $self->engine->hash_size + $self->engine->byte_size, + $self->engine->byte_size, ); return unpack( $StP{$self->engine->byte_size}, $location ); } diff --git a/t/02_hash.t b/t/02_hash.t index 19e26de..5a6673e 100644 --- a/t/02_hash.t +++ b/t/02_hash.t @@ -46,13 +46,13 @@ TODO: { delete $db->{key4}; ok( !exists $db->{key4}, "And key4 doesn't exists anymore" ); -__END__ + ## # count keys ## is( scalar keys %$db, 3, "keys() works against tied hash" ); - +__END__ ## # step through keys ##