NAME
Tie::RefHash::Weak - A Tie::RefHash subclass with weakened references in the keys.
SYNOPSIS
use Tie::RefHash::Weak;
tie my %h, 'Tie::RefHash::Weak';
{ # new scope
my $val = "foo";
$h{\$val} = "bar"; # key is weak ref
print join(", ", keys %h); # contains \$val, returns regular reference
}
# $val goes out of scope, refcount goes to zero
# weak references to \$val are now undefined
keys %h; # no longer contains \$val
# see also Tie::RefHash
DESCRIPTION
The Tie::RefHash module can be used to access hashes by reference. This is useful when you index by object, for example.
The problem with Tie::RefHash, and cross indexing, is that sometimes the index should not contain strong references to the objecs. Tie::RefHash's internal structures contain strong references to the key, and provide no convenient means to make those references weak.
This subclass of Tie::RefHash has weak keys, instead of strong ones. The values are left unaltered, and you'll have to make sure there are no strong references there yourself.
STRUCTURE MAINTAINCE
In perl when weak refernces go bad, they become undef. Tie::RefHash::Weak needs to occasionally go through it's structures and clean out the stale keys.
It does this on two occasions:
- As necessary
-
When an aggregate operation, like keys and values (even in scalar context), or list context interpolation of the hash is made, the whole hash's state must be validated.
This is done lazily, within each call to NEXTKEY. If you need to ensure a low latency, then only iterate with each.
- Occasionally
-
A counter is raised on each update. It's stored in
$self-
[3]>. The counter is incremented via themaybe_purge
method. If the counter is bigger than ten plus$self-
[4]> (which defaults to 15) times the natural logarithm of the number of actual reference keys in the hash (before we know how many are stale), then the hash is iterated and purged. This value tries to ensure that purges aren't made too often, so that they don't take up too much time, but the cleanup is still made in order to prevent leaking data, and to decrement the reference counts of the values of the hash.If you know that your hash will not be accessed often, and
You can disable purging by making maybe_purge
a no-op in your subclass.
You can forcibly purge by calling
(tied %hash)->purge;
You can tweak the occasional purging by playing setting
(tied %hash)->[4] = $x;
TODO
- Hook Perl_magic_killbackrefs
-
Maybe some day the code which undefines weak references will be hooked with XS to purge the hash in a more real-time fashion.
BUGS
- Value refcount delay
-
When the key loses it's reference count and goes undef, the value associated with that key will not be deleted until the next call to purge, which may be significantly later.
Purge manually in critical sections, or implement "Hook Perl_magic_killbackrefs".
AUTHOR
Yuval Kogman <nothingmuch@woobling.org>
COPYRIGHT & LICENSE
Copyright (c) 2004 Yuval Kogman. All rights reserved
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
SEE ALSO
Tie::RefHash, Class::DBI (the live object cache), "Perl_magic_killbackrefs" in mg.c