[Zope-Checkins] CVS: Zope/lib/python/Products/ZCatalog - Catalog.py:1.104 Lazy.py:1.9
Casey Duncan
casey@zope.com
Wed, 11 Dec 2002 13:56:58 -0500
Update of /cvs-repository/Zope/lib/python/Products/ZCatalog
In directory cvs.zope.org:/tmp/cvs-serv9541
Modified Files:
Catalog.py Lazy.py
Log Message:
Refactor Lazy concatenation to remove some old cruft and simplify the code
Catalog empty results are now always a LazyCat([]) rather than a LazyCat(SomeEmptySequencishThingFromTheIndexes)
=== Zope/lib/python/Products/ZCatalog/Catalog.py 1.103 => 1.104 ===
--- Zope/lib/python/Products/ZCatalog/Catalog.py:1.103 Mon Dec 9 17:58:18 2002
+++ Zope/lib/python/Products/ZCatalog/Catalog.py Wed Dec 11 13:56:58 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.8 => 1.9 ===
--- Zope/lib/python/Products/ZCatalog/Lazy.py:1.8 Thu Dec 5 16:17:05 2002
+++ Zope/lib/python/Products/ZCatalog/Lazy.py Wed Dec 11 13:56:58 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.