[Zope-Checkins] SVN: Zope/trunk/ Collector #1332: added in-place migration for

Andreas Jung andreas at andreas-jung.com
Tue Oct 12 11:47:01 EDT 2004


Log message for revision 28011:
  Collector #1332: added in-place migration for 
  Catalog.__len__ -> Catalog._length
  


Changed:
  U   Zope/trunk/doc/CHANGES.txt
  U   Zope/trunk/lib/python/Products/ZCatalog/Catalog.py
  U   Zope/trunk/lib/python/Products/ZCatalog/ZCatalog.py


-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt	2004-10-12 15:13:59 UTC (rev 28010)
+++ Zope/trunk/doc/CHANGES.txt	2004-10-12 15:46:59 UTC (rev 28011)
@@ -156,6 +156,9 @@
        is now installed into the 'bin' folder.
 
     Bugs fixed
+
+     - Collector #1332: Added in-place migration of the Catalog.__len__
+       attribute to avoid new-style class caching problems.
  
      - Collector #1457: ZCTextIndex's QueryError and ParseError 
        are now available for import from untrusted code.

Modified: Zope/trunk/lib/python/Products/ZCatalog/Catalog.py
===================================================================
--- Zope/trunk/lib/python/Products/ZCatalog/Catalog.py	2004-10-12 15:13:59 UTC (rev 28010)
+++ Zope/trunk/lib/python/Products/ZCatalog/Catalog.py	2004-10-12 15:46:59 UTC (rev 28011)
@@ -78,13 +78,7 @@
         # object unique identifier to the rid, and self.paths is a
         # mapping of the rid to the unique identifier.
 
-        # Note that it was unfortunate to use __len__ as the attribute
-        # name here. New-style classes cache slot methods in C slot
-        # pointers. The result is that instances can't override slots.
-        # This is not easy to change on account of old objects with
-        # __len__ attr.
-
-        self.__len__ = BTrees.Length.Length()
+        self._length = BTrees.Length.Length()
         self.clear()
 
         if brains is not None:
@@ -92,52 +86,28 @@
 
         self.updateBrains()
 
+    
     def __len__(self):
-        try:
-            return self.__dict__['__len__']()
-        except KeyError:
-            # Fallback for *really* old catalogs that don't have
-            # Length objects. 
-            return len(self.data)
+        return self._length()
 
+    def migrate__len__(self):
+        """ migration of old __len__ magic for Zope 2.8 """
+        if not hasattr(self, '_length'):
+            n = self.__dict__['__len__']()
+            del self.__dict__['__len__'] 
+            self._length = BTrees.Length.Length(n)
+
     def clear(self):
         """ clear catalog """
 
         self.data  = IOBTree()  # mapping of rid to meta_data
         self.uids  = OIBTree()  # mapping of uid to rid
         self.paths = IOBTree()  # mapping of rid to uid
+        self._length.set(0)
 
-        # convert old-style Catalog object to new in-place
-        try: self.__len__.set(0)
-        except AttributeError: self.__len__=BTrees.Length.Length()
-
         for index in self.indexes.keys():
             self.getIndex(index).clear()
 
-    def _convertBTrees(self, threshold=200):
-
-        from BTrees.convert import convert
-
-        if type(self.data) is not IOBTree:
-            data=self.data
-            self.data=IOBTree()
-            convert(data, self.data, threshold)
-
-            self.__len__=BTrees.Length.Length(len(data))
-
-            uids=self.uids
-            self.uids=OIBTree()
-            convert(uids, self.uids, threshold)
-
-            paths=self.paths
-            self.paths=IOBTree()
-            convert(paths, self.paths, threshold)
-
-
-        for index in self.indexes.values():
-            if hasattr(index, '__of__'): index=index.__of__(self)
-            index._convertBTrees(threshold)
-
     def updateBrains(self):
         self.useBrains(self._v_brains)
 
@@ -369,9 +339,7 @@
         if index is None:  # we are inserting new data
             index = self.updateMetadata(object, uid)
 
-            try: self.__len__.change(1)
-            except AttributeError: pass # No managed length (old-style)
-
+            self._length.change(1)
             self.uids[uid] = index
             self.paths[index] = uid
 
@@ -421,8 +389,8 @@
             del data[rid]
             del paths[rid]
             del uids[uid]
-            try: self.__len__.change(-1)
-            except AttributeError: pass # No managed length
+            self._length.change(-1)
+            
         else:
             LOG.error('uncatalogObject unsuccessfully '
                       'attempted to uncatalog an object '

Modified: Zope/trunk/lib/python/Products/ZCatalog/ZCatalog.py
===================================================================
--- Zope/trunk/lib/python/Products/ZCatalog/ZCatalog.py	2004-10-12 15:13:59 UTC (rev 28010)
+++ Zope/trunk/lib/python/Products/ZCatalog/ZCatalog.py	2004-10-12 15:46:59 UTC (rev 28011)
@@ -183,6 +183,9 @@
         self._catalog = Catalog()
 
     def __len__(self):
+        # Perform a migration of _catalog.__len__ to _catalog._length
+        # to avoid with new-style class caching issues (see #1332)
+        self._catalog.migrate__len__()
         return len(self._catalog)
 
 



More information about the Zope-Checkins mailing list