Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

dree's scratchpad

by dree (Monsignor)
on Jun 01, 2004 at 19:58 UTC ( [id://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
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-03-29 06:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found