[Zope-CVS] CVS: Products/BTreeFolder2 - BTreeFolder2.py:1.15

Shane Hathaway shane at zope.com
Wed Aug 27 11:07:25 EDT 2003


Update of /cvs-repository/Products/BTreeFolder2
In directory cvs.zope.org:/tmp/cvs-serv23448

Modified Files:
	BTreeFolder2.py 
Log Message:
Added a manage_cleanup to BTreeFolder2.

Certain ZODB bugs have caused BTrees to become slightly insane.
manage_cleanup detects damage and fixes it.



=== Products/BTreeFolder2/BTreeFolder2.py 1.14 => 1.15 ===
--- Products/BTreeFolder2/BTreeFolder2.py:1.14	Thu Aug 22 09:50:18 2002
+++ Products/BTreeFolder2/BTreeFolder2.py	Wed Aug 27 10:06:53 2003
@@ -34,7 +34,7 @@
 from AccessControl import getSecurityManager, ClassSecurityInfo
 from AccessControl.Permissions import access_contents_information, \
      view_management_screens
-from zLOG import LOG, ERROR, WARNING
+from zLOG import LOG, INFO, ERROR, WARNING
 from Products.ZCatalog.Lazy import LazyMap
 
 
@@ -122,6 +122,64 @@
                     ids = OIBTree()
                     mti[meta_type] = ids
                 ids[name] = 1
+
+
+    security.declareProtected(view_management_screens, 'manage_cleanup')
+    def manage_cleanup(self):
+        v = self._cleanup()
+        path = '/'.join(self.getPhysicalPath())
+        if v:
+            return "No damage detected in BTreeFolder2 at %s." % path
+        else:
+            return ("Fixed BTreeFolder2 at %s.  "
+                    "See the log for more details." % path)
+
+
+    def _cleanup(self):
+        """Cleans up errors in the BTrees.
+
+        Certain ZODB bugs have caused BTrees to become slightly insane.
+        Fortunately, there is a way to clean up damaged BTrees that
+        always seems to work: make a new BTree containing the items()
+        of the old one.
+
+        Returns 1 if no damage was detected, or 0 if damage was
+        detected and fixed.
+        """
+        from BTrees.check import check
+        path = '/'.join(self.getPhysicalPath())
+        try:
+            check(self._tree)
+            for key in self._tree.keys():
+                if not self._tree.has_key(key):
+                    raise AssertionError
+            check(self._mt_index)
+            for key, value in self._mt_index.items():
+                if (not self._mt_index.has_key(key)
+                    or self._mt_index[key] is not value):
+                    raise AssertionError
+                check(value)
+                for k in value.keys():
+                    if not value.has_key(k):
+                        raise AssertionError
+            return 1
+        except AssertionError:
+            LOG('BTreeFolder2', WARNING,
+                'Detected damage to %s. Fixing now.' % path,
+                error=sys.exc_info())
+            try:
+                self._tree = OOBTree(self._tree)
+                mt_index = OOBTree()
+                for key, value in self._mt_index.items():
+                    mt_index[key] = OIBTree(value)
+                self._mt_index = mt_index
+            except:
+                LOG('BTreeFolder2', ERROR, 'Failed to fix %s.' % path,
+                    error=sys.exc_info())
+                raise
+            else:
+                LOG('BTreeFolder2', INFO, 'Fixed %s.' % path)
+            return 0
 
 
     def _getOb(self, id, default=_marker):




More information about the Zope-CVS mailing list