[Zope-Checkins] CVS: Zope/lib/python/Products/ZCatalog - Catalog.py:1.82.14.1
Toby Dickenson
tdickenson@geminidataloggers.com
Wed, 20 Mar 2002 07:30:17 -0500
Update of /cvs-repository/Zope/lib/python/Products/ZCatalog
In directory cvs.zope.org:/tmp/cvs-serv9292
Modified Files:
Tag: toby-catalog-optimisation
Catalog.py
Log Message:
three major optimisation; Collector 304
=== Zope/lib/python/Products/ZCatalog/Catalog.py 1.82 => 1.82.14.1 ===
for name in u: used[name]=1
w, rs = weightedIntersection(rs, r)
-
+
#assert rs==None or hasattr(rs, 'values') or hasattr(rs, 'keys')
if rs is None:
# return everything
@@ -480,16 +480,7 @@
rs=data.items()
append(LazyMap(self.instantiate, rs, len(self)))
else:
- try:
- for k, intset in sort_index.items():
- if hasattr(intset, 'keys'): intset=intset.keys()
- append((k,LazyMap(self.__getitem__, intset)))
- except AttributeError:
- raise ValueError, (
- "Incorrect index name passed as"
- " 'sort_on' parameter. Note that you may only"
- " sort on values for which there is a matching"
- " index available.")
+ self._build_sorted_results(data,sort_index,append)
elif rs:
# this is reached by having an empty result set (ie non-None)
if sort_index is None and hasattr(rs, 'values'):
@@ -513,28 +504,47 @@
# reached, therefor 'sort-on' does not happen in the
# context of text index query. This should probably
# sort by relevance first, then the 'sort-on' attribute.
- if ((len(rs) / 4) > len(sort_index)):
- # if the sorted index has a quarter as many keys as
- # the result set
- for k, intset in sort_index.items():
- # We have an index that has a set of values for
- # each sort key, so we interset with each set and
- # get a sorted sequence of the intersections.
-
- # This only makes sense if the number of
- # keys is much less then the number of results.
- intset = intersection(rs, intset)
- if intset:
- if hasattr(intset, 'keys'): intset=intset.keys()
- append((k,LazyMap(self.__getitem__, intset)))
- else:
- if hasattr(rs, 'keys'): rs=rs.keys()
- for did in rs:
- append((sort_index.keyForDocument(did),
- LazyMap(self.__getitem__,[did])))
+ self._build_sorted_results(rs,sort_index,append)
return used
+ def _build_sorted_results(self,rs,sort_index,append):
+ # The two 'for' loops in here contribute a significant
+ # proportion of the time to perform an indexed search.
+ # Try to avoid all non-local attribute lookup inside
+ # those loops.
+ _lazymap = LazyMap
+ _intersection = intersection
+ _self__getitem__ = self.__getitem__
+ _None = None
+ if ((len(rs) / 4) > len(sort_index)):
+ # if the sorted index has a quarter as many keys as
+ # the result set
+ for k, intset in sort_index.items():
+ # We have an index that has a set of values for
+ # each sort key, so we interset with each set and
+ # get a sorted sequence of the intersections.
+
+ # This only makes sense if the number of
+ # keys is much less then the number of results.
+ intset = _intersection(rs, intset)
+ if intset:
+ keys = getattr(intset,'keys',_None)
+ if keys is not _None:
+ # Is this ever true?
+ intset = keys()
+ append((k,_lazymap(_self__getitem__, intset)))
+ else:
+ if hasattr(rs, 'keys'): rs=rs.keys()
+ _sort_index_keyForDocument = sort_index.keyForDocument
+ _keyerror = KeyError
+ for did in rs:
+ try:
+ append((_sort_index_keyForDocument(did),
+ _lazymap(_self__getitem__,[did])))
+ except _keyerror:
+ pass
+
def searchResults(self, REQUEST=None, used=None, **kw):
# Get search arguments:
@@ -595,7 +605,7 @@
so.lower() in ('reverse', 'descending')):
r.reverse()
- r=map(lambda i: i[1], r)
+ r= [i[1] for i in r]
r=LazyCat(r, reduce(lambda x,y: x+len(y), r, 0))
return r