[Zope-Checkins] CVS: Zope2 - ConflictResolution.py:1.1.2.2
Jim Fulton
jim@digiciool.com
Wed, 14 Mar 2001 11:46:45 -0500 (EST)
Update of /cvs-repository/Zope2/lib/python/ZODB
In directory korak:/tmp/cvs-serv8196
Modified Files:
Tag: Catalog-BTrees-Integration
ConflictResolution.py
Log Message:
Added support for objects with persistent references. This was to
allow conflict resolution of buckets containing persistent objects and
to handle buckets with next-buckets.
Note that the persistent references don't have meaningful values other
than addresses and aren't of the normal object type. This means that
conflict-resolution logic can't rely on the any semantics of refered
objects other than identity-based comparison.
--- Updated File ConflictResolution.py in package Zope2 --
--- ConflictResolution.py 2001/03/01 00:36:37 1.1.2.1
+++ ConflictResolution.py 2001/03/14 16:46:45 1.1.2.2
@@ -85,6 +85,8 @@
from cStringIO import StringIO
from cPickle import Unpickler, Pickler
+#import sys, traceback
+
bad_classes={}
bad_class=bad_classes.has_key
@@ -95,23 +97,62 @@
return getattr(__import__(location, _globals, _globals, _silly),
name)
-def state(self, oid, serial):
+def state(self, oid, serial, prfactory):
p=self.loadSerial(oid, serial)
file=StringIO(p)
unpickler=Unpickler(file)
+ unpickler.persistent_load=prfactory
class_tuple=unpickler.load()
state=unpickler.load()
return state
+
+class PersistentReference:
+
+ def __repr__(self):
+ return "PR(%s %s)" % (id(self), self.data)
+
+class PersistentReferenceFactory:
+
+ data=None
+
+ def __call__(self, oid,
+ getattr=getattr, None=None):
+
+ data=self.data
+ if not data: data=self.data={}
+
+ r=data.get(oid, None)
+ if r is None:
+ r=PersistentReference()
+ r.data=oid
+ data[oid]=r
+
+ return r
+
+def persistent_id(object,
+ PersistentReference=PersistentReference,
+ getattr=getattr
+ ):
+ if getattr(object, '__class__', 0) is not PersistentReference:
+ return None
+ return object.data
+
class ConflictResolvingStorage:
"Mix-in class that provides conflict resolution handling for storages"
def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle):
+ #class_tuple, old, committed, newstate = ('',''), 0, 0, 0
try:
file=StringIO(newpickle)
unpickler=Unpickler(file)
+ prfactory=PersistentReferenceFactory()
+ unpickler.persistent_load=prfactory
class_tuple=unpickler.load()[0]
- if bad_class(class_tuple): return 0
+ if bad_class(class_tuple):
+ #sys.stderr.write(' b%s ' % class_tuple[1]); sys.stderr.flush()
+ return 0
+
try:
newstate=unpickler.load()
klass=_classFactory(class_tuple[0], class_tuple[1])
@@ -120,15 +161,34 @@
resolve=inst._p_resolveConflict
except:
bad_classes[class_tuple]=1
+ #traceback.print_exc()
+ #sys.stderr.write(' b%s ' % class_tuple[1]); sys.stderr.flush()
return 0
- old=state(self, oid, oldSerial)
- committed=state(self, oid, committedSerial)
+ old=state(self, oid, oldSerial, prfactory)
+ committed=state(self, oid, committedSerial, prfactory)
resolved=resolve(old, committed, newstate)
+
file=StringIO()
pickler=Pickler(file,1)
+ pickler.persistent_id=persistent_id
pickler.dump(class_tuple)
pickler.dump(resolved)
+ #sys.stderr.write(' r%s ' % class_tuple[1]); sys.stderr.flush()
return file.getvalue(1)
- except: return 0
+ except Exception, v:
+ #print '='*70
+ #print v, v.args
+ #print '='*70
+ #print old
+ #print '='*70
+ #print committed
+ #print '='*70
+ #print newstate
+ #print '='*70
+
+ #traceback.print_exc()
+ #sys.stderr.write(' c%s ' % class_tuple[1]); sys.stderr.flush()
+ return 0
+