Several improvements to pack(), which should be good enough for the
1.0 release. These changes pass all the tests, but the proof will be packing some real data (to come next -- this stuff has to be checked in first). Specifically, __init__(): We now allocate a pack-lock which is acquired in pack() to prevent multiple threads from packing at the same time. This should be deadlock-proof because you should never have the storage lock when you want to acquire the pack lock (but I could be missing something obvious). _rootreachable(): New method which calculates the set of object ids reachable from the current revision of the root object. _zapobject(): Rewritten to remove the recursion. It populates a dictionary (passed in the parameter) with the oids for any objects whose refcounts went to zero because of the object we're now zapping. _zaprevision(): Same deal as _zapobjects(). _dopack(): The guts of the pack() operation, done this way so pack() itself can just be a wrapper around _dopack() with pack lock acquisition/release. This also does not acquire the storage lock until it actually has to start zapping revisions, and it releases and reacquires the lock for each revision it zaps. This gives other threads an opportunity to do work during a pack, which should never impact the pack as any work they do will happen in the future (and we're safe against bogus future pack times). pack(): Acquire the pack lock, _dopack(), release the pack lock.
Showing
This diff is collapsed.
This diff is collapsed.
Please register or sign in to comment