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