#13394: Write a WeakValueDictionary with safer key removal
-------------------------------------+-------------------------------------
Reporter: nbruin | Owner: rlm
Type: enhancement | Status: new
Priority: major | Milestone: sage-5.13
Component: memleak | Resolution:
Keywords: | Merged in:
Authors: | Reviewers:
Report Upstream: N/A | Work issues:
Branch: | Commit:
u/SimonKing/ticket/13394 | f0ed60fbdf5f2b1c7cd15f6bab98099f4ff8b822
Dependencies: | Stopgaps:
-------------------------------------+-------------------------------------
Comment (by SimonKing):
Here is an example concerning "garbage collection during iteration".
Features of the example:
- Many hash collisions
- Reference cycles, so that Python's cyclic garbage collector comes into
play
- The garbage collection is postponed until after the first iteration.
First, with `weakref.WeakValueDictionary`:
{{{
sage: class Cycle(object):
....: def __init__(self, n):
....: self.n = n
....: self.ref = self
....: def __cmp__(self, other):
....: c = cmp(type(self),type(other))
....: if c:
....: return c
....: return cmp(self.n, other.n)
....: def __repr__(self):
....: return "Cyc(%s)"%self.n
....:
sage: class Keys(object):
....: def __init__(self, n):
....: self.n = n
....: def __hash__(self):
....: return self.n%5
....: def __cmp__(self, other):
....: c = cmp(type(self),type(other))
....: if c:
....: return c
....: return cmp(self.n, other.n)
....: def __repr__(self):
....: return "Key(%s)"%self.n
....:
sage: C = [Cycle(n) for n in range(100)]
sage: K = [Keys(n) for n in range(100)]
sage: import gc
sage: import sage.misc.weak_dict
sage: import weakref
sage: D = weakref.WeakValueDictionary()
sage: for k,c in zip(K,C):
....: D[k] = c
....:
sage: del c
sage: gc.disable()
sage: del C
sage: for k,c in D.iteritems():
....: print k,c
....: gc.enable()
....: _ = gc.collect()
....:
Key(0) Cyc(0)
Traceback (most recent call last):
...
RuntimeError: dictionary changed size during iteration
}}}
And with `sage.misc.weak_dict.WeakValueDictionary`:
{{{
sage: D = sage.misc.weak_dict.WeakValueDictionary(zip(K,C))
sage: len(D)
100
sage: gc.disable()
sage: del C
sage: for k,c in D.iteritems():
....: print k,c
....: gc.enable()
....: _ = gc.collect()
....:
Key(0) Cyc(0)
Traceback (most recent call last):
...
IndexError: list index out of range
}}}
So, there is an error, too. Perhaps one could improve the error message.
--
Ticket URL: <http://trac.sagemath.org/ticket/13394#comment:15>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.