From: rkinyon Date: Thu, 15 Jun 2006 20:06:06 +0000 (+0000) Subject: r14235@Rob-Kinyons-PowerBook: rob | 2006-06-14 22:24:47 -0400 X-Git-Tag: 0-99_03~25 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=40956c06b63482f505f700229282f22804376ccd;p=dbsrgits%2FDBM-Deep.git r14235@Rob-Kinyons-PowerBook: rob | 2006-06-14 22:24:47 -0400 Moving further along --- diff --git a/lib/DBM/Deep.pm b/lib/DBM/Deep.pm index aa23179..97a592f 100644 --- a/lib/DBM/Deep.pm +++ b/lib/DBM/Deep.pm @@ -492,7 +492,7 @@ sub STORE { $value = $self->_storage->{filter_store_value}->( $value ); } - $self->_engine->write_value( $self->_base_offset, $key, $value, $orig_key ); + $self->_engine->write_value( $self->_storage->transaction_id, $self->_base_offset, $key, $value, $orig_key ); $self->unlock(); @@ -512,7 +512,7 @@ sub FETCH { ## $self->lock( LOCK_SH ); - my $result = $self->_engine->read_value( $self->_base_offset, $key, $orig_key ); + my $result = $self->_engine->read_value( $self->_storage->transaction_id, $self->_base_offset, $key, $orig_key ); $self->unlock(); @@ -553,7 +553,7 @@ sub DELETE { ## # Delete bucket ## - my $value = $self->_engine->delete_key( $self->_base_offset, $key, $orig_key ); + my $value = $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $orig_key ); if (defined $value && !ref($value) && $self->_storage->{filter_fetch_value}) { $value = $self->_storage->{filter_fetch_value}->($value); @@ -576,7 +576,7 @@ sub EXISTS { ## $self->lock( LOCK_SH ); - my $result = $self->_engine->key_exists( $self->_base_offset, $key ); + my $result = $self->_engine->key_exists( $self->_storage->transaction_id, $self->_base_offset, $key ); $self->unlock(); @@ -616,14 +616,14 @@ sub CLEAR { 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->_base_offset, $key, $key ); + $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $key ); $key = $next_key; } } else { my $size = $self->FETCHSIZE; for my $key ( 0 .. $size - 1 ) { - $self->_engine->delete_key( $self->_base_offset, $key, $key ); + $self->_engine->delete_key( $self->_storage->transaction_id, $self->_base_offset, $key, $key ); } $self->STORESIZE( 0 ); } diff --git a/lib/DBM/Deep/Engine.pm b/lib/DBM/Deep/Engine.pm index 73917a4..c430e6d 100644 --- a/lib/DBM/Deep/Engine.pm +++ b/lib/DBM/Deep/Engine.pm @@ -48,18 +48,18 @@ sub HEAD () { 0 } sub read_value { my $self = shift; - my ($offset, $key, $orig_key) = @_; + my ($trans_id, $offset, $key, $orig_key) = @_; - my $dig_key = $self->apply_digest( $key ); + my $dig_key = $self->_apply_digest( $key ); my $tag = $self->find_blist( $offset, $dig_key ) or return; return $self->get_bucket_value( $tag, $dig_key, $orig_key ); } sub key_exists { my $self = shift; - my ($offset, $key) = @_; + my ($trans_id, $offset, $key) = @_; - my $dig_key = $self->apply_digest( $key ); + my $dig_key = $self->_apply_digest( $key ); # exists() returns the empty string, not undef my $tag = $self->find_blist( $offset, $dig_key ) or return ''; return $self->bucket_exists( $tag, $dig_key, $key ); @@ -67,14 +67,14 @@ sub key_exists { sub get_next_key { my $self = shift; - my ($offset) = @_; + my ($trans_id, $offset) = @_; # If the previous key was not specifed, start at the top and # return the first one found. my $temp; - if ( @_ > 1 ) { + if ( @_ > 2 ) { $temp = { - prev_md5 => $self->apply_digest($_[1]), + prev_md5 => $self->_apply_digest($_[2]), return_next => 0, }; } @@ -90,9 +90,9 @@ sub get_next_key { sub delete_key { my $self = shift; - my ($offset, $key, $orig_key) = @_; + my ($trans_id, $offset, $key, $orig_key) = @_; - my $dig_key = $self->apply_digest( $key ); + my $dig_key = $self->_apply_digest( $key ); my $tag = $self->find_blist( $offset, $dig_key ) or return; my $value = $self->get_bucket_value( $tag, $dig_key, $orig_key ); $self->delete_bucket( $tag, $dig_key, $orig_key ); @@ -101,9 +101,9 @@ sub delete_key { sub write_value { my $self = shift; - my ($offset, $key, $value, $orig_key) = @_; + my ($trans_id, $offset, $key, $value, $orig_key) = @_; - my $dig_key = $self->apply_digest( $key ); + my $dig_key = $self->_apply_digest( $key ); my $tag = $self->find_blist( $offset, $dig_key, { create => 1 } ); return $self->add_bucket( $tag, $dig_key, $key, $value, undef, $orig_key ); } @@ -174,7 +174,7 @@ sub new { sub _storage { return $_[0]{storage} } -sub apply_digest { +sub _apply_digest { my $self = shift; return $self->{digest}->(@_); } diff --git a/lib/DBM/Deep/Engine2.pm b/lib/DBM/Deep/Engine2.pm index 9940165..bdeb0f1 100644 --- a/lib/DBM/Deep/Engine2.pm +++ b/lib/DBM/Deep/Engine2.pm @@ -227,12 +227,18 @@ sub write_value { } } - #XXX Write this - $self->_write_value({ - tag => $key_tag, - value => $value, + my $value_loc = $self->_storage->request_space( + $self->_length_needed( $value, $key ), + ); + + $self->_add_key_offset({ + tag => $key_tag, + trans_id => $trans_id, + loc => $value_loc, }); + $self->_write_value( $value_loc, $key, $value, $key ); + return 1; } @@ -240,6 +246,8 @@ sub _find_value_offset { my $self = shift; my ($args) = @_; + use Data::Dumper;warn Dumper $args; + my $key_tag = $self->load_tag( $args->{offset} ); my @head; @@ -269,8 +277,6 @@ sub _find_key_offset { my $bucket_tag = $self->load_tag( $args->{offset} ) or $self->_throw_error( "INTERNAL ERROR - Cannot find tag" ); - # $bucket_tag->{ref_loc} and $bucket_tag->{ch} are used in split_index() - #XXX What happens when $ch >= $self->{hash_size} ?? for (my $ch = 0; $bucket_tag->{signature} ne SIG_BLIST; $ch++) { my $num = ord substr($args->{key_md5}, $ch, 1); @@ -322,18 +328,47 @@ sub _find_key_offset { return( $keytag_loc, $bucket_tag ); } else { + my ($key, $subloc, $index); BUCKET: for ( my $i = 0; $i < $self->{max_buckets}; $i++ ) { - my ($key, $subloc) = $self->_get_key_subloc( + ($key, $subloc) = $self->_get_key_subloc( $bucket_tag->{content}, $i, ); next BUCKET if $subloc && $key ne $args->{key_md5}; - #XXX Right here, I need to create a new value, if I can - return( $subloc, $bucket_tag ); + + # Keep track of where we are, in case we need to create a new + # entry. + $index = $i; + last; } - # Right here, it looks like split_index needs to happen - # What happens here? + + # Either we have a subloc to return or we don't want to create a new + # entry. Either way, we need to return now. + return ($subloc, $bucket_tag) if $subloc || !$args->{create}; + + my $keytag_loc = $self->_storage->request_space( + $self->tag_size( $self->{keyloc_size} ), + ); + + # There's space left in this bucket + if ( defined $index ) { + substr( $bucket_tag->{content}, $index * $self->{key_size}, $self->{key_size} ) = + $args->{key_md5} . pack( "$self->{long_pack}", $keytag_loc ); + + $self->_storage->print_at( $bucket_tag->{offset}, $bucket_tag->{content} ); + } + # We need to split the index + else { + $self->split_index( $bucket_tag, $args->{key_md5}, $keytag_loc ); + } + + $self->write_tag( + $keytag_loc, SIG_KEYS, + chr(0)x$self->{keyloc_size}, + ); + + return( $keytag_loc, $bucket_tag ); } return; @@ -362,7 +397,7 @@ sub _mark_as_deleted { substr( $args->{tag}{content}, $i * $self->{key_size}, $self->{key_size} ) = pack( "$self->{long_pack} C C", $loc, $trans_id, 1, - ) + ); } } @@ -419,11 +454,37 @@ sub _remove_key_offset { return 1; } -sub _write_value { +sub _add_key_offset { my $self = shift; my ($args) = @_; + my $is_changed; + for ( my $i = 0; $i < $self->{max_buckets}; $i++ ) { + my ($loc, $trans_id, $is_deleted) = unpack( + "$self->{long_pack} C C", + substr( $args->{tag}{content}, $i * $self->{key_size}, $self->{key_size} ), + ); + if ( $trans_id == $args->{trans_id} || (!$loc && !$is_deleted) ) { + substr( $args->{tag}{content}, $i * $self->{key_size}, $self->{key_size} ) = pack( + "$self->{long_pack} C C", + $args->{loc}, $args->{trans_id}, 0, + ); + $is_changed = 1; + last; + } + } + + if ( $is_changed ) { + $self->_storage->print_at( + $args->{tag}{offset}, $args->{tag}{content}, + ); + } + else { + die "Why didn't _add_key_offset() change something?!\n"; + } + + return 1; } sub setup_fh { diff --git a/lib/DBM/Deep/Hash.pm b/lib/DBM/Deep/Hash.pm index 65775b8..9ce962a 100644 --- a/lib/DBM/Deep/Hash.pm +++ b/lib/DBM/Deep/Hash.pm @@ -92,7 +92,7 @@ sub FIRSTKEY { ## $self->lock( $self->LOCK_SH ); - my $result = $self->_engine->get_next_key($self->_base_offset); + my $result = $self->_engine->get_next_key($self->_storage->transaction_id, $self->_base_offset); $self->unlock(); @@ -116,7 +116,7 @@ sub NEXTKEY { ## $self->lock( $self->LOCK_SH ); - my $result = $self->_engine->get_next_key( $self->_base_offset, $prev_key ); + my $result = $self->_engine->get_next_key( $self->_storage->transaction_id, $self->_base_offset, $prev_key ); $self->unlock();