Commit 7b08a4bc authored by Jim Fulton's avatar Jim Fulton

Use the cPickle inst_persistent_id rather than the persistent_id hook

to avoid unnecessary calls to the persistent_id hook for objects that
we know can't be persistent.
parent ce161198
...@@ -22,6 +22,14 @@ New Features ...@@ -22,6 +22,14 @@ New Features
XXX There are known issues with this implementation that need to be XXX There are known issues with this implementation that need to be
sorted out before it is "released". sorted out before it is "released".
3.9.0a5 (2008-11-??)
====================
New Features
------------
- Object saves are a little faster
3.9.0a4 (2008-11-06) 3.9.0a4 (2008-11-06)
==================== ====================
......
...@@ -208,7 +208,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle, ...@@ -208,7 +208,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
file = StringIO() file = StringIO()
pickler = Pickler(file,1) pickler = Pickler(file,1)
pickler.persistent_id = persistent_id pickler.inst_persistent_id = persistent_id
pickler.dump(meta) pickler.dump(meta)
pickler.dump(resolved) pickler.dump(resolved)
return file.getvalue(1) return file.getvalue(1)
......
...@@ -170,7 +170,7 @@ class ExportImport: ...@@ -170,7 +170,7 @@ class ExportImport:
newp = StringIO() newp = StringIO()
pickler = Pickler(newp, 1) pickler = Pickler(newp, 1)
pickler.persistent_id = persistent_id pickler.inst_persistent_id = persistent_id
pickler.dump(unpickler.load()) pickler.dump(unpickler.load())
pickler.dump(unpickler.load()) pickler.dump(unpickler.load())
......
...@@ -173,7 +173,7 @@ class ObjectWriter: ...@@ -173,7 +173,7 @@ class ObjectWriter:
def __init__(self, obj=None): def __init__(self, obj=None):
self._file = cStringIO.StringIO() self._file = cStringIO.StringIO()
self._p = cPickle.Pickler(self._file, 1) self._p = cPickle.Pickler(self._file, 1)
self._p.persistent_id = self.persistent_id self._p.inst_persistent_id = self.persistent_id
self._stack = [] self._stack = []
if obj is not None: if obj is not None:
self._stack.append(obj) self._stack.append(obj)
......
...@@ -13,17 +13,8 @@ ...@@ -13,17 +13,8 @@
############################################################################## ##############################################################################
"""Run some tests relevant for storages that support pack().""" """Run some tests relevant for storages that support pack()."""
try: import cPickle
import cPickle from cStringIO import StringIO
pickle = cPickle
#import cPickle as pickle
except ImportError:
import pickle
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
import time import time
...@@ -59,7 +50,7 @@ class Root: ...@@ -59,7 +50,7 @@ class Root:
# persistent pickling machinery -- in the dumps() function below -- will # persistent pickling machinery -- in the dumps() function below -- will
# pickle the oid string instead of the object's actual state. Yee haw, this # pickle the oid string instead of the object's actual state. Yee haw, this
# stuff is deep. ;) # stuff is deep. ;)
class Object: class Object(object):
def __init__(self, oid): def __init__(self, oid):
self._oid = oid self._oid = oid
...@@ -86,15 +77,15 @@ def dumps(obj): ...@@ -86,15 +77,15 @@ def dumps(obj):
return obj.getoid() return obj.getoid()
return None return None
s = StringIO() s = StringIO()
p = pickle.Pickler(s, 1) p = cPickle.Pickler(s, 1)
p.persistent_id = getpersid p.inst_persistent_id = getpersid
p.dump(obj) p.dump(obj)
p.dump(None) p.dump(None)
return s.getvalue() return s.getvalue()
def pdumps(obj): def pdumps(obj):
s = StringIO() s = StringIO()
p = pickle.Pickler(s) p = cPickle.Pickler(s)
p.dump(obj) p.dump(obj)
p.dump(None) p.dump(None)
return s.getvalue() return s.getvalue()
...@@ -124,12 +115,12 @@ class PackableStorageBase: ...@@ -124,12 +115,12 @@ class PackableStorageBase:
# with an argument bound to an instance attribute method, we do it # with an argument bound to an instance attribute method, we do it
# this way because it makes the code in the tests more succinct. # this way because it makes the code in the tests more succinct.
# #
# BUT! Be careful in your use of loads() vs. pickle.loads(). loads() # BUT! Be careful in your use of loads() vs. cPickle.loads(). loads()
# should only be used on the Root object's pickle since it's the only # should only be used on the Root object's pickle since it's the only
# special one. All the Object instances should use pickle.loads(). # special one. All the Object instances should use cPickle.loads().
def loads(str, persfunc=self._cache.get): def loads(str, persfunc=self._cache.get):
fp = StringIO(str) fp = StringIO(str)
u = pickle.Unpickler(fp) u = cPickle.Unpickler(fp)
u.persistent_load = persfunc u.persistent_load = persfunc
return u.load() return u.load()
return loads return loads
...@@ -339,15 +330,15 @@ class PackableStorage(PackableStorageBase): ...@@ -339,15 +330,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj)) revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted # Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1) data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 1) eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2) data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 2) eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3) data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 3) eq(pobj.value, 3)
# Now pack all transactions; need to sleep a second to make # Now pack all transactions; need to sleep a second to make
...@@ -392,15 +383,15 @@ class PackableStorage(PackableStorageBase): ...@@ -392,15 +383,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj)) revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted # Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1) data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 1) eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2) data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 2) eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3) data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 3) eq(pobj.value, 3)
# Now pack just revisions 1 and 2. The object's current revision # Now pack just revisions 1 and 2. The object's current revision
...@@ -417,12 +408,12 @@ class PackableStorage(PackableStorageBase): ...@@ -417,12 +408,12 @@ class PackableStorage(PackableStorageBase):
raises(KeyError, self._storage.loadSerial, oid, revid1) raises(KeyError, self._storage.loadSerial, oid, revid1)
raises(KeyError, self._storage.loadSerial, oid, revid2) raises(KeyError, self._storage.loadSerial, oid, revid2)
data = self._storage.loadSerial(oid, revid3) data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 3) eq(pobj.value, 3)
data, revid = self._storage.load(oid, '') data, revid = self._storage.load(oid, '')
eq(revid, revid3) eq(revid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 3) eq(pobj.value, 3)
...@@ -460,15 +451,15 @@ class PackableStorage(PackableStorageBase): ...@@ -460,15 +451,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid1, revid=revid2, data=pdumps(obj1)) revid3 = self._dostoreNP(oid1, revid=revid2, data=pdumps(obj1))
# Now make sure all three revisions can be extracted # Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid1, revid1) data = self._storage.loadSerial(oid1, revid1)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid1) eq(pobj.getoid(), oid1)
eq(pobj.value, 1) eq(pobj.value, 1)
data = self._storage.loadSerial(oid1, revid2) data = self._storage.loadSerial(oid1, revid2)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid1) eq(pobj.getoid(), oid1)
eq(pobj.value, 2) eq(pobj.value, 2)
data = self._storage.loadSerial(oid1, revid3) data = self._storage.loadSerial(oid1, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid1) eq(pobj.getoid(), oid1)
eq(pobj.value, 3) eq(pobj.value, 3)
# Now commit a revision of the second object # Now commit a revision of the second object
...@@ -476,7 +467,7 @@ class PackableStorage(PackableStorageBase): ...@@ -476,7 +467,7 @@ class PackableStorage(PackableStorageBase):
revid4 = self._dostoreNP(oid2, data=pdumps(obj2)) revid4 = self._dostoreNP(oid2, data=pdumps(obj2))
# And make sure the revision can be extracted # And make sure the revision can be extracted
data = self._storage.loadSerial(oid2, revid4) data = self._storage.loadSerial(oid2, revid4)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid2) eq(pobj.getoid(), oid2)
eq(pobj.value, 11) eq(pobj.value, 11)
# Now pack just revisions 1 and 2 of object1. Object1's current # Now pack just revisions 1 and 2 of object1. Object1's current
...@@ -494,19 +485,19 @@ class PackableStorage(PackableStorageBase): ...@@ -494,19 +485,19 @@ class PackableStorage(PackableStorageBase):
raises(KeyError, self._storage.loadSerial, oid1, revid1) raises(KeyError, self._storage.loadSerial, oid1, revid1)
raises(KeyError, self._storage.loadSerial, oid1, revid2) raises(KeyError, self._storage.loadSerial, oid1, revid2)
data = self._storage.loadSerial(oid1, revid3) data = self._storage.loadSerial(oid1, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid1) eq(pobj.getoid(), oid1)
eq(pobj.value, 3) eq(pobj.value, 3)
data, revid = self._storage.load(oid1, '') data, revid = self._storage.load(oid1, '')
eq(revid, revid3) eq(revid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid1) eq(pobj.getoid(), oid1)
eq(pobj.value, 3) eq(pobj.value, 3)
data, revid = self._storage.load(oid2, '') data, revid = self._storage.load(oid2, '')
eq(revid, revid4) eq(revid, revid4)
eq(loads(data).value, 11) eq(loads(data).value, 11)
data = self._storage.loadSerial(oid2, revid4) data = self._storage.loadSerial(oid2, revid4)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid2) eq(pobj.getoid(), oid2)
eq(pobj.value, 11) eq(pobj.value, 11)
...@@ -528,15 +519,15 @@ class PackableStorageWithOptionalGC(PackableStorage): ...@@ -528,15 +519,15 @@ class PackableStorageWithOptionalGC(PackableStorage):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj)) revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted # Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1) data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 1) eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2) data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 2) eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3) data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data) pobj = cPickle.loads(data)
eq(pobj.getoid(), oid) eq(pobj.getoid(), oid)
eq(pobj.value, 3) eq(pobj.value, 3)
# Now pack all transactions; need to sleep a second to make # Now pack all transactions; need to sleep a second to make
......
...@@ -52,7 +52,7 @@ def zodb_pickle(obj): ...@@ -52,7 +52,7 @@ def zodb_pickle(obj):
"""Create a pickle in the format expected by ZODB.""" """Create a pickle in the format expected by ZODB."""
f = StringIO() f = StringIO()
p = Pickler(f, 1) p = Pickler(f, 1)
p.persistent_id = _persistent_id p.inst_persistent_id = _persistent_id
klass = obj.__class__ klass = obj.__class__
assert not hasattr(obj, '__getinitargs__'), "not ready for constructors" assert not hasattr(obj, '__getinitargs__'), "not ready for constructors"
args = None args = None
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment