[Zodb-checkins] SVN: ZODB/branches/3.8/ Merged bug fix, 82895, from trunk:

Jim Fulton jim at zope.com
Fri May 2 16:38:51 EDT 2008


Log message for revision 86134:
  Merged bug fix, 82895, from trunk:
  
  When using ZEO Client Storages, Errors occured when trying to store
  objects too big to fit in the ZEO cache file.
  

Changed:
  U   ZODB/branches/3.8/NEWS.txt
  U   ZODB/branches/3.8/src/ZEO/cache.py
  U   ZODB/branches/3.8/src/ZEO/tests/test_cache.py

-=-
Modified: ZODB/branches/3.8/NEWS.txt
===================================================================
--- ZODB/branches/3.8/NEWS.txt	2008-05-02 20:17:04 UTC (rev 86133)
+++ ZODB/branches/3.8/NEWS.txt	2008-05-02 20:38:51 UTC (rev 86134)
@@ -1,3 +1,11 @@
+Whats new in ZODB 3.8.1
+=======================
+
+Bugs Fixed:
+
+- When using ZEO Client Storages, Errors occured when trying to store
+  objects too big to fit in the ZEO cache file.
+
 What's new on ZODB 3.8.0
 ========================
 

Modified: ZODB/branches/3.8/src/ZEO/cache.py
===================================================================
--- ZODB/branches/3.8/src/ZEO/cache.py	2008-05-02 20:17:04 UTC (rev 86133)
+++ ZODB/branches/3.8/src/ZEO/cache.py	2008-05-02 20:38:51 UTC (rev 86134)
@@ -269,6 +269,8 @@
                 if self.version[oid] != (version, start_tid):
                     raise ValueError("data already exists for version %r"
                                      % self.version[oid][0])
+            if not self.fc.add(o):
+                return # too large
             self.version[oid] = version, start_tid
             self._trace(0x50, oid, version, start_tid, dlen=len(data))
         else:
@@ -280,6 +282,8 @@
                             "already have current data for oid")
                     else:
                         return
+                if not self.fc.add(o):
+                    return # too large
                 self.current[oid] = start_tid
                 self._trace(0x52, oid, version, start_tid, dlen=len(data))
             else:
@@ -287,10 +291,11 @@
                 p = start_tid, end_tid
                 if p in L:
                     return # duplicate store
+                if not self.fc.add(o):
+                    return # too large
                 bisect.insort_left(L, p)
                 self._trace(0x54, oid, version, start_tid, end_tid,
                             dlen=len(data))
-        self.fc.add(o)
 
     ##
     # Remove all knowledge of noncurrent revisions of oid, both in
@@ -960,7 +965,8 @@
     ##
     # Add Object object to the cache.  This may evict existing objects, to
     # make room (and almost certainly will, in steady state once the cache
-    # is first full).  The object must not already be in the cache.
+    # is first full).  The object must not already be in the cache.  If the
+    # object is too large for the cache, False is returned, otherwise True.
     def add(self, object):
         size = OBJECT_HEADER_SIZE + object.size
         # A number of cache simulation experiments all concluded that the
@@ -968,7 +974,7 @@
         # objects simply weren't cached.  For now, we ignore the request
         # only if the entire cache file is too small to hold the object.
         if size > self.maxsize - ZEC3_HEADER_SIZE:
-            return
+            return False
 
         assert object.key not in self.key2entry
         assert len(object.key[0]) == 8
@@ -979,6 +985,7 @@
 
         available = self._makeroom(size)
         self._writeobj(object, available)
+        return True
 
     ##
     # Evict the object represented by Entry `e` from the cache, freeing

Modified: ZODB/branches/3.8/src/ZEO/tests/test_cache.py
===================================================================
--- ZODB/branches/3.8/src/ZEO/tests/test_cache.py	2008-05-02 20:17:04 UTC (rev 86133)
+++ ZODB/branches/3.8/src/ZEO/tests/test_cache.py	2008-05-02 20:38:51 UTC (rev 86134)
@@ -152,5 +152,36 @@
         eq(copy.current, self.cache.current)
         eq(copy.noncurrent, self.cache.noncurrent)
 
+    def testCurrentObjectLargerThanCache(self):
+        if self.cache.path:
+            os.remove(self.cache.path)
+        cache = ZEO.cache.ClientCache(size=50)
+        cache.open()
+
+        # We store an object that is a bit larger than the cache can handle.
+        cache.store(n1, '', n2, None, "x"*64)
+        # We can see that it was not stored.
+        self.assertEquals(None, self.cache.load(n1))
+        # If an object cannot be stored in the cache, it must not be
+        # recorded as current.
+        self.assert_(n1 not in self.cache.current)
+        # Regression test: invalidation must still work.
+        cache.invalidate(n1, '', n2)
+  	 
+    def testOldObjectLargerThanCache(self):
+        if self.cache.path:
+            os.remove(self.cache.path)
+        cache = ZEO.cache.ClientCache(size=50)
+        cache.open()
+
+        # We store an object that is a bit larger than the cache can handle.
+        cache.store(n1, '', n2, n3, "x"*64)
+        # We can see that it was not stored.
+        self.assertEquals(None, self.cache.load(n1))
+        # If an object cannot be stored in the cache, it must not be
+        # recorded as non-current.
+        self.assert_((n2, n3) not in cache.noncurrent[n1])
+  	 
+
 def test_suite():
     return unittest.makeSuite(CacheTests)



More information about the Zodb-checkins mailing list