can"t delete from the 2th level hash
can"t delete from the 2th level hash
am 05.02.2006 15:59:54 von pangj
hello,list,
I can't know if it's fit or not to paste the question here.I use some a DB_File module to tie and store a hash.
the code is partly as following:
use strict;
use warnings;
use IO::Socket;
use MLDBM qw(DB_File Storable);
use Fcntl ':flock';
my %records;
my $msfwdb = tie(%records, 'MLDBM', $db, O_CREAT|O_RDWR, 0644)
or die "Can't open DB_File $db : $!\n";
my $fd = $msfwdb->fd;
open(DB_FH, "+<&=$fd") || die "dup $!";
# some codes to create the bind socket
while(1)
{
next unless my $connection = $listen_socket->accept;
my $child = fork();
die "can't fork:$!" unless defined $child;
if ($child == 0) #here in child
{
handle($connection);
exit 0;
}
}
....
and where in handle(),I do these:
flock (DB_FH, LOCK_EX) || die "flock: $!";
my $entry = $records{$mid};
$entry->{$timestamp} += $size;
$records{$mid} = $entry;
flock(DB_FH, LOCK_UN);
....
# here are the codes that seem having problem
{
flock (DB_FH, LOCK_EX) || die "flock: $!";
delete $records{$mid}->{$time}; # here I can't really delete the 2th level hash element.
flock(DB_FH, LOCK_UN);
}
------
the primary problem is this statement: delete $records{$mid}->{$time}; the action of 'delete' don't take effect.
and I try to write it as following:
my $tmp = $records{$mid}; delete $tmp->{$time};
but the bad result is the same as before.
why this happen and how to resolve it?thanks really.
--
Jeff Pang
NetEase AntiSpam Team
http://corp.netease.com
RE: can"t delete from the 2th level hash
am 06.02.2006 16:07:48 von rjk-dbi
Jeff Pang [mailto:pangj@earthlink.net] wrote:
> use MLDBM qw(DB_File Storable);
> the primary problem is this statement: delete $records{$mid}->{$time};
> the action of 'delete' don't take effect.
> and I try to write it as following:
>
> my $tmp = $records{$mid}; delete $tmp->{$time};
>
> but the bad result is the same as before.
>
> why this happen and how to resolve it?thanks really.
This is the way MLDBM works. Only the top-level hash is tied, so only
changes to the top-level hash are written to the DBM.
For example:
tie %h, 'MLDBM', 'mydbm', ...;
$h{'animals'} = { dog => 1 };
$h{'animals'}{'cat'} = 1;
mydbm will contain { animals => { dog => 1 } }. The 'cat' assignment was
not made at the top-level of the hash, so the tie mechanism doesn't even see
it.
Instead, to assign cat later, you would have to do something like this:
tie %h, 'MLDBM', 'mydbm', ...;
$h{'animals'} = { dog => 1 };
$tmp = $h{'animals'};
$tmp->{'cat'} = 1;
$h{'animals'} = $tmp;
Now mydbm will contain { animals => { dog => 1, cat => 1 } }.
Similarly, in order to delete from the nested hash:
$tmp = $h{'animals'};
delete $tmp->{'cat'};
$h{'animals'} = $tmp;
This all makes sense when you think of it in terms of how tie works.
HTH,
Ronald
RE: can"t delete from the 2th level hash
am 06.02.2006 16:29:09 von pangj
hi,Ronald,
as you said,
$tmp = $h{'animals'};
delete $tmp->{'cat'};
$h{'animals'} = $tmp;
You are very right.When do 'delete', I have not added the last statement '$h{'animals'} = $tmp;',so I get lost.
Thank you very much.
-----Original Message-----
>From: Ronald J Kimball
>Sent: Feb 6, 2006 10:07 AM
>To: dbi-users@perl.org
>Subject: RE: can't delete from the 2th level hash
>
>Jeff Pang [mailto:pangj@earthlink.net] wrote:
>
>> use MLDBM qw(DB_File Storable);
>
>> the primary problem is this statement: delete $records{$mid}->{$time};
>> the action of 'delete' don't take effect.
>> and I try to write it as following:
>>
>> my $tmp = $records{$mid}; delete $tmp->{$time};
>>
>> but the bad result is the same as before.
>>
>> why this happen and how to resolve it?thanks really.
>
>This is the way MLDBM works. Only the top-level hash is tied, so only
>changes to the top-level hash are written to the DBM.
>
>For example:
>
>tie %h, 'MLDBM', 'mydbm', ...;
>
>$h{'animals'} = { dog => 1 };
>$h{'animals'}{'cat'} = 1;
>
>mydbm will contain { animals => { dog => 1 } }. The 'cat' assignment was
>not made at the top-level of the hash, so the tie mechanism doesn't even see
>it.
>
>Instead, to assign cat later, you would have to do something like this:
>
>tie %h, 'MLDBM', 'mydbm', ...;
>
>$h{'animals'} = { dog => 1 };
>$tmp = $h{'animals'};
>$tmp->{'cat'} = 1;
>$h{'animals'} = $tmp;
>
>Now mydbm will contain { animals => { dog => 1, cat => 1 } }.
>
>
>Similarly, in order to delete from the nested hash:
>
>$tmp = $h{'animals'};
>delete $tmp->{'cat'};
>$h{'animals'} = $tmp;
>
>
>This all makes sense when you think of it in terms of how tie works.
>
>
>HTH,
>Ronald
>
>
--
Jeff Pang
NetEase AntiSpam Team
http://corp.netease.com
RE: can"t delete from the 2th level hash
am 06.02.2006 17:00:43 von pangj
Sorry for again,when my script run for some time,the hash elements become uncorrect and I get the error log:
Mon Feb 6 23:55:00 2006 Can't locate Log/Agent.pm in @INC (@INC contains: /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 .) at (eval 5) line 2.
Mon Feb 6 23:55:00 2006 Can't locate Log/Agent.pm in @INC (@INC contains: /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 .) at (eval 5) line 2.
BEGIN failed--compilation aborted at (eval 5) line 2.
I don't use this module of 'Log::Agent.pm' by myself.
Is there anyone know this situation under 'MLDBM'? thanks.
-----Original Message-----
>From: Ronald J Kimball
>Sent: Feb 6, 2006 10:07 AM
>To: dbi-users@perl.org
>Subject: RE: can't delete from the 2th level hash
>
>Jeff Pang [mailto:pangj@earthlink.net] wrote:
>
>> use MLDBM qw(DB_File Storable);
>
>> the primary problem is this statement: delete $records{$mid}->{$time};
>> the action of 'delete' don't take effect.
>> and I try to write it as following:
>>
>> my $tmp = $records{$mid}; delete $tmp->{$time};
>>
>> but the bad result is the same as before.
>>
>> why this happen and how to resolve it?thanks really.
>
>This is the way MLDBM works. Only the top-level hash is tied, so only
>changes to the top-level hash are written to the DBM.
>
>For example:
>
>tie %h, 'MLDBM', 'mydbm', ...;
>
>$h{'animals'} = { dog => 1 };
>$h{'animals'}{'cat'} = 1;
>
>mydbm will contain { animals => { dog => 1 } }. The 'cat' assignment was
>not made at the top-level of the hash, so the tie mechanism doesn't even see
>it.
>
>Instead, to assign cat later, you would have to do something like this:
>
>tie %h, 'MLDBM', 'mydbm', ...;
>
>$h{'animals'} = { dog => 1 };
>$tmp = $h{'animals'};
>$tmp->{'cat'} = 1;
>$h{'animals'} = $tmp;
>
>Now mydbm will contain { animals => { dog => 1, cat => 1 } }.
>
>
>Similarly, in order to delete from the nested hash:
>
>$tmp = $h{'animals'};
>delete $tmp->{'cat'};
>$h{'animals'} = $tmp;
>
>
>This all makes sense when you think of it in terms of how tie works.
>
>
>HTH,
>Ronald
>
>
--
Jeff Pang
NetEase AntiSpam Team
http://corp.netease.com