[Zope-Checkins] CVS: ZODB3/ZODB - DemoStorage.py:1.21.2.2
Jeremy Hylton
cvs-admin at zope.org
Tue Nov 18 14:07:29 EST 2003
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv21456/ZODB
Modified Files:
Tag: ZODB3-mvcc-2-branch
DemoStorage.py
Log Message:
Update DemoStorage to implement loadEx().
Add tid to the record data that is stored. It may be that this
information is redundant except for abort version, but this still
seemed like the simplest implementation.
Reformat a lot of the code along the way as I tried to figure it out.
XXX We should drop this storage in ZODB 3.3. in favor of the memory
storages for ZODB4.
=== ZODB3/ZODB/DemoStorage.py 1.21.2.1 => 1.21.2.2 ===
--- ZODB3/ZODB/DemoStorage.py:1.21.2.1 Tue Oct 7 01:10:31 2003
+++ ZODB3/ZODB/DemoStorage.py Tue Nov 18 14:07:28 2003
@@ -45,7 +45,7 @@
A record is a tuple:
- oid, serial, pre, vdata, p,
+ oid, serial, pre, vdata, p, tid
where:
@@ -62,6 +62,8 @@
p -- the pickle data or None
+ tid -- the transaction id that wrote the record (usually == serial)
+
The pickle data will be None for a record for an object created in
an aborted version.
@@ -93,12 +95,13 @@
BaseStorage.BaseStorage.__init__(self, name, base)
# We use a BTree because the items are sorted!
- self._data=OOBTree.OOBTree()
- self._index={}
- self._vindex={}
- self._base=base
- self._size=0
- self._quota=quota
+ self._data = OOBTree.OOBTree()
+ self._index = {}
+ self._vindex = {}
+ self._base = base
+ self._size = 0
+ self._quota = quota
+ self._ltid = None
self._clear_temp()
if base is not None and base.versions():
raise POSException.StorageError, (
@@ -113,7 +116,7 @@
s=100
for tid, (p, u, d, e, t) in self._data.items():
s=s+16+24+12+4+16+len(u)+16+len(d)+16+len(e)+16
- for oid, serial, pre, vdata, p in t:
+ for oid, serial, pre, vdata, p, tid in t:
s=s+16+24+24+4+4+(p and (16+len(p)) or 4)
if vdata: s=s+12+16+len(vdata[0])+4
@@ -139,14 +142,14 @@
oids = []
for r in v.values():
- oid, serial, pre, (version, nv), p = r
+ oid, serial, pre, (version, nv), p, tid = r
oids.append(oid)
if nv:
- oid, serial, pre, vdata, p = nv
- self._tindex.append([oid, serial, r, None, p])
+ oid, serial, pre, vdata, p, tid = nv
+ self._tindex.append([oid, serial, r, None, p, self._serial])
else:
# effectively, delete the thing
- self._tindex.append([oid, None, r, None, None])
+ self._tindex.append([oid, None, r, None, None, self._serial])
return self._serial, oids
@@ -171,25 +174,25 @@
tindex=self._tindex
oids=[]
for r in v.values():
- oid, serial, pre, vdata, p = r
+ oid, serial, pre, vdata, p, tid = r
assert vdata is not None
oids.append(oid)
if dest:
new_vdata = dest, vdata[1]
else:
new_vdata = None
- tindex.append([oid, newserial, r, new_vdata, p])
+ tindex.append([oid, newserial, r, new_vdata, p, self._serial])
return self._serial, oids
finally: self._lock_release()
- def load(self, oid, version):
+ def loadEx(self, oid, version):
self._lock_acquire()
try:
try:
- oid, serial, pre, vdata, p = self._index[oid]
+ oid, serial, pre, vdata, p, tid = self._index[oid]
except KeyError:
if self._base:
return self._base.load(oid, '')
@@ -199,21 +202,24 @@
oversion, nv = vdata
if oversion != version:
if nv:
- oid, serial, pre, vdata, p = nv
+ oid, serial, pre, vdata, p, tid = nv
else:
raise KeyError, oid
if p is None:
raise KeyError, oid
- return p, serial
+ return p, serial, tid
finally: self._lock_release()
+ def load(self, oid, version):
+ return self.loadEx(oid, version)[:2]
+
def modifiedInVersion(self, oid):
self._lock_acquire()
try:
try:
- oid, serial, pre, vdata, p = self._index[oid]
+ oid, serial, pre, vdata, p, tid = self._index[oid]
if vdata: return vdata[0]
return ''
except: return ''
@@ -238,7 +244,7 @@
nv=None
if old:
- oid, oserial, pre, vdata, p = old
+ oid, oserial, pre, vdata, p, tid = old
if vdata:
if vdata[0] != version:
@@ -252,7 +258,8 @@
raise POSException.ConflictError(serials=(oserial, serial))
serial=self._serial
- r=[oid, serial, old, version and (version, nv) or None, data]
+ r = [oid, serial, old, version and (version, nv) or None, data,
+ self._serial]
self._tindex.append(r)
s=self._tsize
@@ -268,13 +275,19 @@
finally: self._lock_release()
return serial
- def supportsUndo(self): return 1
- def supportsVersions(self): return 1
+ def supportsUndo(self):
+ return 1
+
+ def supportsVersions(self):
+ return 1
def _clear_temp(self):
self._tindex = []
self._tsize = self._size + 160
+ def lastTransaction(self):
+ return self._ltid
+
def _begin(self, tid, u, d, e):
self._tsize = self._size + 120 + len(u) + len(d) + len(e)
@@ -283,7 +296,7 @@
self._data[tid] = None, user, desc, ext, tuple(self._tindex)
for r in self._tindex:
- oid, serial, pre, vdata, p = r
+ oid, serial, pre, vdata, p, tid = r
old = self._index.get(oid)
# If the object had version data, remove the version data.
if old is not None:
@@ -304,6 +317,7 @@
if v is None:
v = self._vindex[version] = {}
v[oid] = r
+ self._ltid = self._serial
def undo(self, transaction_id):
self._lock_acquire()
@@ -322,7 +336,7 @@
oids=[]
for r in t:
- oid, serial, pre, vdata, p = r
+ oid, serial, pre, vdata, p, tid = r
if pre:
index[oid] = pre
@@ -335,7 +349,7 @@
if v: del v[oid]
# Add new version data (from pre):
- oid, serial, prepre, vdata, p = pre
+ oid, serial, prepre, vdata, p, tid = pre
if vdata:
version=vdata[0]
v=vindex.get(version, None)
@@ -402,13 +416,13 @@
def _build_indexes(self, stop='\377\377\377\377\377\377\377\377'):
# Rebuild index structures from transaction data
- index={}
- vindex={}
- _data=self._data
- for tid, (p, u, d, e, t) in _data.items():
- if tid >= stop: break
+ index = {}
+ vindex = {}
+ for tid, (p, u, d, e, t) in self._data.items():
+ if tid >= stop:
+ break
for r in t:
- oid, serial, pre, vdata, p = r
+ oid, serial, pre, vdata, p, tid = r
old=index.get(oid, None)
if old is not None:
@@ -437,54 +451,56 @@
try:
stop=`TimeStamp(*time.gmtime(t)[:5]+(t%60,))`
- _data=self._data
# Build indexes up to the pack time:
index, vindex = self._build_indexes(stop)
# Now build an index of *only* those objects reachable
# from the root.
- rootl=['\0\0\0\0\0\0\0\0']
- pop=rootl.pop
- pindex={}
- referenced=pindex.has_key
+ rootl = ['\0\0\0\0\0\0\0\0']
+ pindex = {}
while rootl:
- oid=pop()
- if referenced(oid): continue
+ oid = rootl.pop()
+ if oid in pindex:
+ continue
# Scan non-version pickle for references
- r=index.get(oid, None)
+ r = index.get(oid, None)
if r is None:
if self._base:
p, s = self._base.load(oid, '')
referencesf(p, rootl)
else:
- pindex[oid]=r
- oid, serial, pre, vdata, p = r
+ pindex[oid] = r
+ oid, serial, pre, vdata, p, tid = r
referencesf(p, rootl)
if vdata:
- nv=vdata[1]
+ nv = vdata[1]
if nv:
- oid, serial, pre, vdata, p = nv
+ oid, serial, pre, vdata, p, tid = nv
referencesf(p, rootl)
# Now we're ready to do the actual packing.
# We'll simply edit the transaction data in place.
# We'll defer deleting transactions till the end
# to avoid messing up the BTree items.
- deleted=[]
- for tid, (p, u, d, e, t) in _data.items():
- if tid >= stop: break
- o=[]
- for r in t:
- c=pindex.get(r[0])
+ deleted = []
+ for tid, (p, u, d, e, records) in self._data.items():
+ if tid >= stop:
+ break
+ o = []
+ for r in records:
+ c = pindex.get(r[0])
if c is None:
# GC this record, no longer referenced
continue
- elif c is not r:
+ if c == r:
+ # This is the most recent revision.
+ o.append(r)
+ else:
# This record is not the indexed record,
# so it may not be current. Let's see.
- oid, serial, pre, vdata, p = r
+ vdata = r[3]
if vdata:
# Version record are current *only* if they
# are indexed
@@ -492,7 +508,7 @@
else:
# OK, this isn't a version record, so it may be the
# non-version record for the indexed record.
- oid, serial, pre, vdata, p = c
+ vdata = c[3]
if vdata:
if vdata[1] != r:
# This record is not the non-version
@@ -503,17 +519,17 @@
# so this record can not be the non-version
# record for it.
continue
- o.append(r)
+ o.append(r)
if o:
- if len(o) != len(t):
- _data[tid] = 1, u, d, e, tuple(o) # Reset data
+ if len(o) != len(records):
+ self._data[tid] = 1, u, d, e, tuple(o) # Reset data
else:
deleted.append(tid)
# Now delete empty transactions
for tid in deleted:
- del _data[tid]
+ del self._data[tid]
# Now reset previous pointers for "current" records:
for r in pindex.values():
@@ -539,21 +555,22 @@
for tid, (p, u, d, e, t) in self._data.items():
o.append(" %s %s" % (TimeStamp(tid), p))
for r in t:
- oid, serial, pre, vdata, p = r
- oid=utils.u64(oid)
+ oid, serial, pre, vdata, p, tid = r
+ oid = utils.oid_repr(oid)
+ tid = utils.oid_repr(tid)
if serial is not None: serial=str(TimeStamp(serial))
pre=id(pre)
if vdata and vdata[1]: vdata=vdata[0], id(vdata[1])
if p: p=''
o.append(' %s: %s' %
- (id(r), `(oid, serial, pre, vdata, p)`))
+ (id(r), `(oid, serial, pre, vdata, p, tid)`))
o.append('\nIndex:')
items=self._index.items()
items.sort()
for oid, r in items:
if r: r=id(r)
- o.append(' %s: %s' % (utils.u64(oid), r))
+ o.append(' %s: %s' % (utils.oid_repr(oid), r))
o.append('\nVersion Index:')
items=self._vindex.items()
@@ -564,7 +581,6 @@
vitems.sort()
for oid, r in vitems:
if r: r=id(r)
- o.append(' %s: %s' % (utils.u64(oid), r))
-
+ o.append(' %s: %s' % (utils.oid_repr(oid), r))
return string.join(o,'\n')
More information about the Zope-Checkins
mailing list