On Sep 21, 2006, at 5:40 PM, Jesus Cea wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > David Binger wrote: >> Would your application be crippled by dropping those >> references, as below, before releasing the lock? > > The code is several thousand of lines long. Moreover, the "issue" > would > be still present, ready to beat any other multithread usage of Durus. You said yourself that this can only work if done with great care. You must wrap all accesses in lock acquire/release blocks. I don't see why it is that much more difficult to make sure that you don't hold any references to persistent instances outside an acquire/release pair. > >> Better, write a lock-protected get_value() >> function that returns the value, and no references >> to persistent instances. > > That was my original workaround try, but see last paragraph :-(. Which last paragraph? > >> If I remember correctly, your database is cycle-free, >> so the gc garbage collector probably isn't doing anything >> for you, or causing trouble. If it were, you >> could call gc.disable(). > > "gc.disable()" disables the garbage collection of cycles, but this is > not an issue here. I'm talking about the reference counter when I say > "garbage collection". Yes. That's what I said. > > I am testing a WeakValueDictionary subclass implementing my first > suggestion: take note of the deleted objects, but keep them in the > dictionary until "cache.shrink()" calls "dictionary.shrink()". > > Would you be interested in the patch?. No noticeable performance hit. I like this approach much better. There are two changes that maybe should be considered. 1) Maybe __len__ should subtract the size of the set of dead keys so that the cache shrink does not overshoot the target. 2) Maybe the dictionary update() method should be overridden to do this, in addition to a normal update, instead of adding a shrink method. The cache.shrink() method could just call update() with no arguments. Then I think the cache could work with either type of weakvaluedictionary.