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!
|