[Zodb-checkins] CVS: ZODB3/ZODB - DemoStorage.py:1.21.2.2

Jeremy Hylton cvs-admin at zope.org
Tue Nov 18 14:07:30 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 Zodb-checkins mailing list