Commit e4a89f07 authored by Jim Fulton's avatar Jim Fulton

With new-style classes, is is no longer possible to override slots

(special '__' methods) on an instance-by instance basis. Changed the
handling of the length so that the __len__ method looks for a __len__
dictionary key. It would be better not to use a __len__ attribute name
for the BTree length object, but such a change would be problematic
for old instances.
parent 1b76d0d5
......@@ -13,7 +13,7 @@
"""Simple column indices"""
__version__='$Revision: 1.20 $'[11:-2]
__version__='$Revision: 1.21 $'[11:-2]
import sys
from cgi import escape
......@@ -21,8 +21,6 @@ from types import StringType, ListType, IntType, TupleType
from Globals import Persistent
from Acquisition import Implicit
import BTree
import IOBTree
from zLOG import LOG, ERROR
from BTrees.OOBTree import OOBTree, OOSet
......@@ -95,11 +93,27 @@ class UnIndex(Persistent, Implicit, SimpleItem):
except:
self.indexed_attrs = [ self.id ]
# It was a mistake to use a __len__ attribute here, but it's not
# worth changing at this point, as there is old data with this
# attribute name. :( See __len__ method docstring
self.__len__ = BTrees.Length.Length()
self.__len__=BTrees.Length.Length() # see __len__ method docstring
self.clear()
def getId(self): return self.id
def __len__(self):
"""Return the number of objects indexed.
"""
# The instance __len__ attr isn't effective because
# Python cached this method in a slot,
__len__ = self.__dict__.get('__len__')
if __len__ is not None:
return __len__()
return len(self._unindex)
def getId(self):
return self.id
def clear(self):
# inplace opportunistic conversion from old-style to new style BTrees
......@@ -140,15 +154,6 @@ class UnIndex(Persistent, Implicit, SimpleItem):
def __nonzero__(self):
return not not self._unindex
def __len__(self):
"""Return the number of objects indexed.
This method is only called for indexes which have "old" BTrees,
and the *only* reason that UnIndexes maintain a __len__ is for
the searching code in the catalog during sorting.
"""
return len(self._unindex)
def histogram(self):
"""Return a mapping which provides a histogram of the number of
elements found at each point in the index."""
......
......@@ -13,10 +13,10 @@
"""
Transient Object Container Class ('timeslice'-based design).
$Id: Transience.py,v 1.33 2003/11/18 13:17:08 tseaver Exp $
$Id: Transience.py,v 1.34 2003/11/28 16:46:11 jim Exp $
"""
__version__='$Revision: 1.33 $'[11:-2]
__version__='$Revision: 1.34 $'[11:-2]
import Globals
from Globals import HTMLFile
......@@ -427,8 +427,16 @@ class TransientObjectContainer(SimpleItem):
# our "__len__" is the length of _index.
# we need to maintain the length of the index structure separately
# because getting the length of a BTree is very expensive.
try: self.__len__.set(0)
except AttributeError: self.__len__ = self.getLen = Length()
# Note that it is a mistake to use the __len__ attr this way,
# because length methods are cached in C slots and out instance
# attr won't be used for len(foo) in new-style classes.
# See the __len__ method below. I (Jim) am not changing this now
# on account of ols instances. With some effort, we could fix this,
# bit I'm not up for it now.
try:
self.__len__.set(0)
except AttributeError:
self.__len__ = Length()
# set up last_timeslice and deindex_next integer pointers
# we set them to the current timeslice as it's the only sane
......@@ -438,6 +446,12 @@ class TransientObjectContainer(SimpleItem):
finally:
self.lock.release()
def __len__(self):
return self.__dict__['__len__']()
def getLen(self):
return self.__len__
def _getCurrentBucket(self):
"""
Do housekeeping if necessary, then return the 'current' bucket.
......
......@@ -76,7 +76,13 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
# object unique identifier to the rid, and self.paths is a
# mapping of the rid to the unique identifier.
self.__len__=BTrees.Length.Length()
# 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.clear()
if brains is not None:
......@@ -84,6 +90,14 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
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)
def clear(self):
""" clear catalog """
......@@ -122,11 +136,6 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
if hasattr(index, '__of__'): index=index.__of__(self)
index._convertBTrees(threshold)
def __len__(self):
# NOTE, this is never called for new catalogs, since
# each instance overrides this.
return len(self.data)
def updateBrains(self):
self.useBrains(self._v_brains)
......
......@@ -13,7 +13,7 @@
"""Simple column indices"""
__version__='$Revision: 1.33 $'[11:-2]
__version__='$Revision: 1.34 $'[11:-2]
from Globals import Persistent
from Acquisition import Implicit
......@@ -75,9 +75,22 @@ class UnIndex(Persistent, Implicit):
self.ignore_ex=ignore_ex # currently unimplimented
self.call_methods=call_methods
self.__len__=BTrees.Length.Length() # see __len__ method docstring
# 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.clear()
def __len__(self):
try:
return self.__dict__['__len__']()
except KeyError:
# Fallback for really old indexes
return len(self._unindex)
def clear(self):
# inplace opportunistic conversion from old-style to new style BTrees
try: self.__len__.set(0)
......@@ -117,15 +130,6 @@ class UnIndex(Persistent, Implicit):
def __nonzero__(self):
return not not self._unindex
def __len__(self):
"""Return the number of objects indexed.
This method is only called for indexes which have "old" BTrees,
and the *only* reason that UnIndexes maintain a __len__ is for
the searching code in the catalog during sorting.
"""
return len(self._unindex)
def histogram(self):
"""Return a mapping which provides a histogram of the number of
elements found at each point in the index."""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment