Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

dree's scratchpad

by dree (Monsignor)
on Jun 01, 2004 at 19:58 UTC ( #358497=scratchpad: print w/ replies, xml ) Need Help??

This node, is very interesting. My consideration are:
use strict; use DB_File; my %btree; $DB_BTREE->{'flags'} = R_DUP; my $bhandle = tie %btree, 'DB_File', undef, O_RDWR|O_CREAT, 0666, $DB_ +BTREE; my @array = ( 'a'..'z' ); foreach ( '2' .. '6') {$btree{$_} = shift @array;} @array = ( 'A'..'Z' ); foreach ( '2' .. '6' ) {$btree{$_} = shift @array;} $btree{1}='HHI'; $btree{4.5}='HHI'; $btree{7}='HHI'; $btree{8}='HHI'; print "From each:\n"; while (my ($key,$val)=each %btree) { print "'$key' contains ".$bhandle->get_dup($key)." values\n"; } print "\n"; print "From for:\n"; my ($key,$val); for (my $status = $bhandle->seq($key, $val, R_FIRST()) ; $status == 0 ; $status = $bhandle->seq($key, $val, R_NEXT()) ) { print "'$key' contains ".$bhandle->get_dup($key)." values\n"; }

produces this output:

From each:
'1' contains 1 values
'2' contains 2 values
'3' contains 2 values
'4' contains 2 values
'5' contains 2 values
'6' contains 2 values
'8' contains 1 values

From for:
'1' contains 1 values
'2' contains 2 values
'3' contains 2 values
'4' contains 2 values
'5' contains 2 values
'6' contains 2 values
'8' contains 1 values

so elements with NO dups placed after an element with a dup ('4.5' and '7'), are forgot by each and for!

The problem arise when you perform a traversal reading of the keys (both with each and the for with the cursor). Look at the get_dup function of DB_File:
sub get_dup { croak "Usage: \$db->get_dup(key [,flag])\n" unless @_ == 2 or @_ == 3 ; my $db = shift ; my $key = shift ; my $flag = shift ; my $value = 0 ; my $origkey = $key ; my $wantarray = wantarray ; my %values = () ; my @values = () ; my $counter = 0 ; my $status = 0 ; # iterate through the database until either EOF ($status == 0) # or a different key is encountered ($key ne $origkey). for ($status = $db->seq($key, $value, R_CURSOR()) ; $status == 0 and $key eq $origkey ; $status = $db->seq($key, $value, R_NEXT()) ) { # save the value or count number of matches if ($wantarray) { if ($flag) { ++ $values{$value} } else { push (@values, $value) } } else { ++ $counter } } return ($wantarray ? ($flag ? %values : @values) : $counter) ; }


In particular look at:

$status == 0 and $key eq $origkey ;

in the for.

with the debugger I see that at the end of the reading of '4' key, $origkey==4 $key==4.5. So THIS traversal reading works! But the external each (or the external traversal reading) "loose" the '4.5' key!
Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (14)
As of 2015-07-29 11:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (263 votes), past polls