Commit 228604dd authored by Jason Madden's avatar Jason Madden

Connection.setstate passes the object's OID as a parameter to the helper Connection._setstate.

This is a performance optimization for PyPy (profiling shows many recursive calls to Persistent.__getattribute__, and recursive calls seem to trouble the PyPy JIT; this eliminates many of them when loading objects):

"Transaction",                 AFTER       BEFORE
"Add 3000 Objects",             20205      18505
"Update 3000 Objects",          24191      18807
"Read 3000 Warm Objects",       28920      26671
"Read 3000 Cold Objects",       28745      27487
"Read 3000 Hot Objects",        29563      27487
"Read 3000 Steamin' Objects", 1033758     916587
parent 8840c09a
...@@ -866,7 +866,7 @@ class Connection(ExportImport, object): ...@@ -866,7 +866,7 @@ class Connection(ExportImport, object):
raise raise
try: try:
self._setstate(obj) self._setstate(obj, oid)
except ConflictError: except ConflictError:
raise raise
except: except:
...@@ -874,8 +874,11 @@ class Connection(ExportImport, object): ...@@ -874,8 +874,11 @@ class Connection(ExportImport, object):
className(obj), oid_repr(oid)) className(obj), oid_repr(oid))
raise raise
def _setstate(self, obj): def _setstate(self, obj, oid):
# Helper for setstate(), which provides logging of failures. # Helper for setstate(), which provides logging of failures.
# We accept the oid param, which must be the same as obj._p_oid,
# as a performance optimization for the pure-Python persistent implementation
# where accessing an attribute involves __getattribute__ calls
# The control flow is complicated here to avoid loading an # The control flow is complicated here to avoid loading an
# object revision that we are sure we aren't going to use. As # object revision that we are sure we aren't going to use. As
...@@ -890,7 +893,7 @@ class Connection(ExportImport, object): ...@@ -890,7 +893,7 @@ class Connection(ExportImport, object):
if self.before is not None: if self.before is not None:
# Load data that was current before the time we have. # Load data that was current before the time we have.
before = self.before before = self.before
t = self._storage.loadBefore(obj._p_oid, before) t = self._storage.loadBefore(oid, before)
if t is None: if t is None:
raise POSKeyError() # historical connection! raise POSKeyError() # historical connection!
p, serial, end = t p, serial, end = t
...@@ -903,16 +906,16 @@ class Connection(ExportImport, object): ...@@ -903,16 +906,16 @@ class Connection(ExportImport, object):
if self._invalidatedCache: if self._invalidatedCache:
raise ReadConflictError() raise ReadConflictError()
if (obj._p_oid in self._invalidated): if (oid in self._invalidated):
self._load_before_or_conflict(obj) self._load_before_or_conflict(obj)
return return
p, serial = self._storage.load(obj._p_oid, '') p, serial = self._storage.load(oid, '')
self._load_count += 1 self._load_count += 1
self._inv_lock.acquire() self._inv_lock.acquire()
try: try:
invalid = obj._p_oid in self._invalidated invalid = oid in self._invalidated
finally: finally:
self._inv_lock.release() self._inv_lock.release()
...@@ -922,13 +925,13 @@ class Connection(ExportImport, object): ...@@ -922,13 +925,13 @@ class Connection(ExportImport, object):
self._reader.setGhostState(obj, p) self._reader.setGhostState(obj, p)
obj._p_serial = serial obj._p_serial = serial
self._cache.update_object_size_estimation(obj._p_oid, len(p)) self._cache.update_object_size_estimation(oid, len(p))
obj._p_estimated_size = len(p) obj._p_estimated_size = len(p)
# Blob support # Blob support
if isinstance(obj, Blob): if isinstance(obj, Blob):
obj._p_blob_uncommitted = None obj._p_blob_uncommitted = None
obj._p_blob_committed = self._storage.loadBlob(obj._p_oid, serial) obj._p_blob_committed = self._storage.loadBlob(oid, serial)
def _load_before_or_conflict(self, obj): def _load_before_or_conflict(self, obj):
"""Load non-current state for obj or raise ReadConflictError.""" """Load non-current state for obj or raise ReadConflictError."""
......
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