[Zope-Checkins] CVS: Zope/lib/python/Products/ZCatalog - Catalog.py:1.98.6.3 Lazy.py:1.7.6.2
Casey Duncan
casey@zope.com
Wed, 11 Dec 2002 14:12:15 -0500
Update of /cvs-repository/Zope/lib/python/Products/ZCatalog
In directory cvs.zope.org:/tmp/cvs-serv12102/lib/python/Products/ZCatalog
Modified Files:
Tag: Zope-2_6-branch
Catalog.py Lazy.py
Log Message:
Backport Lazy concatenation fix from the head, this also makes empty result sets coming from the Catalog consistent
=== Zope/lib/python/Products/ZCatalog/Catalog.py 1.98.6.2 => 1.98.6.3 ===
--- Zope/lib/python/Products/ZCatalog/Catalog.py:1.98.6.2 Tue Dec 10 10:55:00 2002
+++ Zope/lib/python/Products/ZCatalog/Catalog.py Wed Dec 11 14:12:14 2002
@@ -519,7 +519,7 @@
return self.sortResults(rs, sort_index, reverse, limit, merge)
else:
# Empty result set
- return LazyCat(rs)
+ return LazyCat([])
def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1):
# Sort a result set using a sort index. Return a lazy
=== Zope/lib/python/Products/ZCatalog/Lazy.py 1.7.6.1 => 1.7.6.2 ===
--- Zope/lib/python/Products/ZCatalog/Lazy.py:1.7.6.1 Tue Dec 10 10:55:00 2002
+++ Zope/lib/python/Products/ZCatalog/Lazy.py Wed Dec 11 14:12:14 2002
@@ -22,7 +22,7 @@
def __repr__(self): return `list(self)`
def __len__(self):
-
+ # This is a worst-case len, subclasses should try to do better
try: return self._len
except AttributeError: pass
@@ -34,34 +34,13 @@
except:
self._len=l
return l
+
def __add__(self, other):
- try:
- for base in other.__class__.__bases__:
- if base.__name__ == 'Lazy':
- break
- else:
- raise TypeError
- except:
- raise TypeError, "Can not concatenate objects. Both must be lazy sequences."
-
- if self.__class__.__name__ == 'LazyCat':
- if hasattr(self, '_seq'):
- seq = self._seq
- else:
- seq = [self._data]
- else:
- seq = [self]
-
- if other.__class__.__name__ == 'LazyCat':
- if hasattr(other, '_seq'):
- seq = seq + other._seq
- else:
- seq.append(other._data)
- else:
- seq.append(other)
-
- return LazyCat(seq)
+ if not isinstance(other, Lazy):
+ raise TypeError(
+ "Can not concatenate objects. Both must be lazy sequences.")
+ return LazyCat([self, other])
def __getslice__(self,i1,i2):
r=[]
@@ -77,6 +56,19 @@
# for accessing small parts of big searches.
def __init__(self, sequences, length=None):
+ if len(sequences) < 100:
+ # Optimize structure of LazyCats to avoid nesting
+ # We don't do this for large numbers of input sequences
+ # to make instantiation faster instead
+ flattened_seq = []
+ for s in sequences:
+ if isinstance(s, LazyCat):
+ # If one of the sequences passed is itself a LazyCat, add
+ # its base sequences rather than nest LazyCats
+ flattened_seq.extend(s._seq)
+ else:
+ flattened_seq.append(s)
+ sequences = flattened_seq
self._seq=sequences
self._data=[]
self._sindex=0
@@ -118,6 +110,18 @@
self._eindex=eindex=-1
self._eindex=eindex
return data[i]
+
+ def __len__(self):
+ # Make len of LazyCat only as expensive as the lens
+ # of its underlying sequences
+ try:
+ return self._len
+ except:
+ l = 0
+ for s in self._seq:
+ l += len(s)
+ self._len = l
+ return l
class LazyMap(Lazy):
# Act like a sequence, but get data from a filtering process.