(original) (raw)
On Wed, 20 Jan 2016 at 12:27 Yury Selivanov <yselivanov.ml@gmail.com> wrote:
On 2016-01-20 2:45 PM, Glenn Linderman wrote:
\> For the reuse case, can't you simply keep the ma\_version "live" in
\> dict items on the free list, rather than starting over at (presumably)
\> 0 ? Then if the dict is reused, it bumps the ma\_version, and the
\> fallback code goes on with (presumably) relocating the original dict
\> (oops, it's gone), and dealing with the fallout.
Not all dicts are created from a freelist, and not all dicts go to the
freelist when they are GCed.
You still can have this situation:
\- dict "A" is used as f\_locals for a frame, its ma\_version is set to X
\- dict "A" is GCed, but the freelist is full, so it's just freed
\- after a while, you call the code object, a new dict "B" is allocated
with malloc (since now the freelist happens to be empty) for f\_locals
\- it happens that "B" is allocated where "A" was, and its ma\_version
happens to be X by an accident
\>
\> Then you can use the regular dict id as the globally unique dict id?
\> And only need the one uint64, rather than a separately allocated extra
\> pair of uint64?
In my design only namespace dicts will have a non-NULL ma\_extra, which
means that only a fraction of dicts will actually have a separated pair
of uint64s.
I think that we should either use one global ma\_version (as Maciej
suggested) or ma\_extra, as it gives more flexibility for us to extend
dicts in the future.
A global (shared between all dicts) unit64 ma\_version is actually quite
reliable -- if a program does 1,000,000 dict modifications per second,
it would take it 600,000 years till wrap-around.
Since you're going to need to hold the GIL for the modifications there won't be any locking or contention problems, so it sounds like the global value is the best since that's simple, uses the least amount of memory, and will be easiest to use as a modification check since that will be a simple uint64 comparison instead of comparing a GUID + version.