[Zodb-checkins] CVS: ZODB3/ZEO - ClientStorage.py:1.110.2.9 ServerStub.py:1.17.2.6 StorageServer.py:1.101.2.4 cache.py:1.1.2.12

Jeremy Hylton cvs-admin at zope.org
Tue Dec 2 02:11:01 EST 2003


Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv24432/ZEO

Modified Files:
      Tag: ZODB3-mvcc-2-branch
	ClientStorage.py ServerStub.py StorageServer.py cache.py 
Log Message:
First cut at removal of serial numbers.
Rename loadNonCurrent() to loadBefore() (Jim's suggestion).

A few tests fail, but it's close enough to share the code with Tim.

In all case, the _p_serial attribute of a Persistent object matches
the id of the transaction that wrote the current revision.  Within the
storage API, we eliminate the abortVersion case where the txn id is
greater than the serial number.

Rename as many variables and attributes from serial to tid, with the
exception of store() and restore() arguments.  They're being passed in
from a client, which is getting the value from _p_serial; it makes
some sense there.

When tid and serial were both returned, eliminate serial and just use
tid.  

Replace "serial" with "tid" in some methods names, but not all.  I'll
get to the rest tomorrow.  The remaining ones are just used a lot.

Add XXX comment about now-bogus ZEO protocol that passes identical
serialnos for every object committed.


=== ZODB3/ZEO/ClientStorage.py 1.110.2.8 => 1.110.2.9 ===
--- ZODB3/ZEO/ClientStorage.py:1.110.2.8	Mon Dec  1 10:16:08 2003
+++ ZODB3/ZEO/ClientStorage.py	Tue Dec  2 02:10:29 2003
@@ -258,6 +258,12 @@
         # _serials: stores (oid, serialno) as returned by server
         # _seriald: _check_serials() moves from _serials to _seriald,
         #           which maps oid to serialno
+
+        # XXX If serial number matches transaction id, then there is
+        # no need to have all this extra infrastructure for handling
+        # serial numbers.  The vote call can just return the tid.
+        # If there is a conflict error, we can't have a special method
+        # called just to propagate the error.
         self._serials = []
         self._seriald = {}
 
@@ -575,8 +581,8 @@
         self._pickler.fast = 1 # Don't use the memo
 
         # XXX should batch these operations for efficiency
-        for oid, tid, version, serial in self._cache.contents():
-            server.verify(oid, version, serial)
+        for oid, tid, version in self._cache.contents():
+            server.verify(oid, version, tid)
         self._pending_server = server
         server.endZeoVerify()
         return "full verification"
@@ -728,9 +734,9 @@
     def loadEx(self, oid, version):
         self._lock.acquire()    # for atomic processing of invalidations
         try:
-            quad = self._cache.load(oid, version)
-            if quad:
-                return quad
+            t = self._cache.load(oid, version)
+            if t:
+                return t
         finally:
             self._lock.release()
 
@@ -746,33 +752,33 @@
             finally:
                 self._lock.release()
 
-            data, serial, tid, ver = self._server.loadEx(oid, version)
+            data, tid, ver = self._server.loadEx(oid, version)
 
             self._lock.acquire()    # for atomic processing of invalidations
             try:
                 if self._load_status:
-                    self._cache.store(oid, ver, serial, tid, None, data)
+                    self._cache.store(oid, ver, tid, None, data)
                 self._load_oid = None
             finally:
                 self._lock.release()
         finally:
             self._load_lock.release()
 
-        return data, serial, tid, ver
+        return data, tid, ver
 
-    def loadNonCurrent(self, oid, tid):
+    def loadBefore(self, oid, tid):
         self._lock.acquire()
         try:
-            t = self._cache.loadNonCurrent(oid, tid)
+            t = self._cache.loadBefore(oid, tid)
             if t is not None:
                 return t
         finally:
             self._lock.release()
 
-        t = self._server.loadNonCurrent(oid, tid)
+        t = self._server.loadBefore(oid, tid)
         if t is None:
             return None
-        data, serial, start, end = t
+        data, start, end = t
         if end is None:
             # This method should not be used to get current data.  It
             # doesn't use the _load_lock, so it is possble to overlap
@@ -787,14 +793,14 @@
             # I don't think real application code will ever care about
             # it.
 
-            return data, serial, start, end
+            return data, start, end
         self._lock.acquire()
         try:
-            self._cache.store(oid, "", serial, start, end, data)
+            self._cache.store(oid, "", start, end, data)
         finally:
             self._lock.release()
 
-        return data, serial, start, end
+        return data, start, end
 
     def modifiedInVersion(self, oid):
         """Storage API: return the version, if any, that modfied an object.
@@ -846,6 +852,8 @@
 
     def _check_serials(self):
         """Internal helper to move data from _serials to _seriald."""
+        # XXX serials are always going to be the same, the only
+        # question is whether an exception has been raised.
         if self._serials:
             l = len(self._serials)
             r = self._serials[:l]
@@ -993,7 +1001,8 @@
             if data is not None:
                 s = self._seriald[oid]
                 if s != ResolvedSerial:
-                    self._cache.store(oid, version, s, tid, None, data)
+                    assert s == tid, (s, tid)
+                    self._cache.store(oid, version, s, None, data)
         self._tbuf.clear()
 
     def transactionalUndo(self, trans_id, txn):


=== ZODB3/ZEO/ServerStub.py 1.17.2.5 => 1.17.2.6 ===
--- ZODB3/ZEO/ServerStub.py:1.17.2.5	Sat Nov 22 00:07:48 2003
+++ ZODB3/ZEO/ServerStub.py	Tue Dec  2 02:10:29 2003
@@ -191,13 +191,13 @@
     # the lifetime of the specific revision.
     # @param oid object id
     # @param tid a transaction id that provides an upper bound on
-    #            the lifetime of the revision.  That is, loadNonCurrent
+    #            the lifetime of the revision.  That is, loadBefore
     #            returns the revision that was current before tid committed.
     # @defreturn 4-tuple
     # @return data, serial numbr, start transaction id, end transaction id
 
-    def loadNonCurrent(self, oid, tid):
-        return self.rpc.call("loadNonCurrent", oid, tid)
+    def loadBefore(self, oid, tid):
+        return self.rpc.call("loadBefore", oid, tid)
 
     ##
     # Storage new revision of oid.


=== ZODB3/ZEO/StorageServer.py 1.101.2.3 => 1.101.2.4 ===
--- ZODB3/ZEO/StorageServer.py:1.101.2.3	Wed Nov 12 17:24:25 2003
+++ ZODB3/ZEO/StorageServer.py	Tue Dec  2 02:10:29 2003
@@ -241,9 +241,9 @@
         self.stats.loads += 1
         return self.storage.loadEx(oid, version)
 
-    def loadNonCurrent(self, oid, tid):
+    def loadBefore(self, oid, tid):
         self.stats.loads += 1
-        return self.storage.loadNonCurrent(oid, tid)
+        return self.storage.loadBefore(oid, tid)
 
     def zeoLoad(self, oid):
         self.stats.loads += 1
@@ -270,24 +270,26 @@
                  % (len(invlist), u64(invtid)))
         return invtid, invlist
 
-    def verify(self, oid, version, serial):
+    def verify(self, oid, version, tid):
         try:
-            s = self.storage.getSerial(oid)
+            t = self.storage.getTid(oid)
         except KeyError:
             self.client.invalidateVerify((oid, ""))
-        if serial != os:
-            # This will invalidate non-version data when the client only
-            # has invalid version data.  Since this is an uncommon case,
-            # we avoid the cost of checking whether the serial number
-            # matches the current non-version data.
-            self.client.invalidateVerify((oid, version))
+        else:
+            if tid != t:
+                # This will invalidate non-version data when the
+                # client only has invalid version data.  Since this is
+                # an uncommon case, we avoid the cost of checking
+                # whether the serial number matches the current
+                # non-version data.
+                self.client.invalidateVerify((oid, version))
 
     def zeoVerify(self, oid, s, sv):
         if not self.verifying:
             self.verifying = 1
             self.stats.verifying_clients += 1
         try:
-            os = self.storage.getSerial(oid)
+            os = self.storage.getTid(oid)
         except KeyError:
             self.client.invalidateVerify((oid, ''))
             # XXX It's not clear what we should do now.  The KeyError


=== ZODB3/ZEO/cache.py 1.1.2.11 => 1.1.2.12 ===
--- ZODB3/ZEO/cache.py:1.1.2.11	Mon Dec  1 10:16:08 2003
+++ ZODB3/ZEO/cache.py	Tue Dec  2 02:10:30 2003
@@ -197,7 +197,7 @@
         if o is None:
             return None
         self._trace(0x22, oid, version, o.start_tid, o.end_tid, len(o.data))
-        return o.data, o.serialno, tid, o.version
+        return o.data, tid, o.version
 
     ##
     # Return a non-current revision of oid that was current before tid.
@@ -206,7 +206,7 @@
     # @return data record, serial number, start tid, and end tid
     # @defreturn 4-tuple: (string, string, string, string)
 
-    def loadNonCurrent(self, oid, tid):
+    def loadBefore(self, oid, tid):
         L = self.noncurrent.get(oid)
         if L is None:
             self._trace(0x24, oid, tid)
@@ -226,7 +226,7 @@
             return None
         o = self.dll.access((oid, lo))
         self._trace(0x26, oid, tid)
-        return o.data, o.serialno, o.start_tid, o.end_tid
+        return o.data, o.start_tid, o.end_tid
 
     ##
     # Return the version an object is modified in or None for an
@@ -255,7 +255,7 @@
     # @param data the actual data
     # @exception ValueError tried to store non-current version data
 
-    def store(self, oid, version, serial, start_tid, end_tid, data):
+    def store(self, oid, version, start_tid, end_tid, data):
         # It's hard for the client to avoid storing the same object
         # more than once.  One case is whether the client requests
         # version data that doesn't exist.  It checks the cache for
@@ -264,8 +264,7 @@
         # which may already by in the cache.
         if (oid, start_tid) in self.dll:
             return
-        o = Object((oid, start_tid), version, serial, data, start_tid, end_tid,
-                   self)
+        o = Object((oid, start_tid), version, data, start_tid, end_tid, self)
         if version:
             if end_tid is not None:
                 raise ValueError("cache only stores current version data")
@@ -350,15 +349,15 @@
         # XXX May need to materialize list instead of iterating,
         # depends on whether the caller may change the cache.
         for o in self.dll:
-            yield o.key[0], o.key[1], o.version, o.serialno
+            yield o.key[0], o.key[1], o.version
 
     def dump(self):
         from ZODB.utils import oid_repr
         print "cache size", len(self)
         L = list(self.contents())
         L.sort()
-        for oid, tid, version, serialno in L:
-            print oid_repr(oid), oid_repr(tid), repr(version), oid_repr(serialno)
+        for oid, tid, version in L:
+            print oid_repr(oid), oid_repr(tid), repr(version)
         print "dll contents"
         L = list(self.dll)
         L.sort(lambda x,y:cmp(x.key, y.key))
@@ -488,19 +487,16 @@
                  "end_tid", # string, id of txn that wrote next revision
                             # or None
                  "version", # string, name of version
-                 "serialno", # string, serial number assigned by txn
                  "data", # string, the actual data record for the object
 
                  "cache", # ClientCache instance containing Object
                 )
 
-    def __init__(self, key, version, serialno, data, start_tid, end_tid,
-                 cache):
+    def __init__(self, key, version, data, start_tid, end_tid, cache):
         self.key = key
         self.msize = len(data)
         self.worth = None
         self.version = version
-        self.serialno = serialno
         self.data = data
         self.start_tid = start_tid
         self.end_tid = end_tid
@@ -517,7 +513,7 @@
 
     def serialize(self, f):
         # Write standard form of Object to file, f.
-        s = struct.pack(">8s8s8s8shi", self.key[0], self.serialno,
+        s = struct.pack(">8s8s8shi", self.key[0], 
                         self.start_tid, self.end_tid or "\0" * 8,
                         len(self.version), len(self.data))
         f.write(s)
@@ -526,11 +522,11 @@
         f.write(struct.pack(">8s", s))
 
     def fromFile(cls, f, cache):
-        fmt = ">8s8s8s8shi"
+        fmt = ">8s8s8shi"
         s = f.read(struct.calcsize(fmt))
         if not s:
             return None
-        oid, serialno, start_tid, end_tid, vlen, dlen = struct.unpack(fmt, s)
+        oid, start_tid, end_tid, vlen, dlen = struct.unpack(fmt, s)
         if end_tid == "\0" * 8:
             end_tid = None
         version = f.read(vlen)
@@ -542,14 +538,12 @@
         s = f.read(8)
         if struct.pack(">8s", s) != oid:
             raise ValueError("corrupted record, oid")
-        return cls((oid, start_tid), version, serialno, data,
-                   start_tid, end_tid, cache)
+        return cls((oid, start_tid), version, data, start_tid, end_tid, cache)
 
     fromFile = classmethod(fromFile)
 
 # Serialized format is:
 #     8-byte oid
-#     8-byte serialno
 #     8-byte start_tid
 #     8-byte end_end
 #     2-byte version length




More information about the Zodb-checkins mailing list