[Checkins] SVN: Products.ZCatalog/trunk/ Preserve the `actual_result_count` on all lazy return values. This allows to get proper batching information from catalog results which have been restricted by `sort_limit`.
Hanno Schlichting
hannosch at hannosch.eu
Sun Dec 26 14:20:28 EST 2010
Log message for revision 119146:
Preserve the `actual_result_count` on all lazy return values. This allows to get proper batching information from catalog results which have been restricted by `sort_limit`.
Changed:
U Products.ZCatalog/trunk/CHANGES.txt
U Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py
U Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py
-=-
Modified: Products.ZCatalog/trunk/CHANGES.txt
===================================================================
--- Products.ZCatalog/trunk/CHANGES.txt 2010-12-26 19:03:16 UTC (rev 119145)
+++ Products.ZCatalog/trunk/CHANGES.txt 2010-12-26 19:20:27 UTC (rev 119146)
@@ -4,6 +4,10 @@
2.13.2 (unreleased)
-------------------
+- Preserve the `actual_result_count` on all lazy return values. This allows
+ to get proper batching information from catalog results which have been
+ restricted by `sort_limit`.
+
- Made sure `actual_result_count` is available on all lazy classes and falls
back to `__len__` if not explicitly provided.
Modified: Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py 2010-12-26 19:03:16 UTC (rev 119145)
+++ Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py 2010-12-26 19:20:27 UTC (rev 119146)
@@ -561,18 +561,22 @@
'to be returned.' % repr(make_key(self, query)),
DeprecationWarning, stacklevel=3)
+ rlen = len(self)
if sort_index is None:
- result = LazyMap(self.instantiate, self.data.items(), len(self))
+ result = LazyMap(self.instantiate, self.data.items(), rlen,
+ actual_result_count=rlen)
else:
cr.start_split('sort_on')
result = self.sortResults(
- self.data, sort_index, reverse, limit, merge)
+ self.data, sort_index, reverse, limit, merge,
+ actual_result_count=rlen)
cr.stop_split('sort_on', None)
elif rs:
# We got some results from the indexes.
# Sort and convert to sequences.
# XXX: The check for 'values' is really stupid since we call
# items() and *not* values()
+ rlen = len(rs)
if sort_index is None and hasattr(rs, 'values'):
# having a 'values' means we have a data structure with
# scores. Build a new result set, sort it by score, reverse
@@ -608,21 +612,24 @@
r.data_record_normalized_score_ = int(100. * score / max)
return r
- result = LazyMap(getScoredResult, rs, len(rs))
+ result = LazyMap(getScoredResult, rs, rlen,
+ actual_result_count=rlen)
cr.stop_split('sort_on', None)
elif sort_index is None and not hasattr(rs, 'values'):
# no scores
if hasattr(rs, 'keys'):
rs = rs.keys()
- result = LazyMap(self.__getitem__, rs, len(rs))
+ result = LazyMap(self.__getitem__, rs, rlen,
+ actual_result_count=rlen)
else:
# sort. If there are scores, then this block is not
# reached, therefore 'sort-on' does not happen in the
# context of a text index query. This should probably
# sort by relevance first, then the 'sort-on' attribute.
cr.start_split('sort_on')
- result = self.sortResults(rs, sort_index, reverse, limit, merge)
+ result = self.sortResults(rs, sort_index, reverse, limit,
+ merge, actual_result_count=rlen)
cr.stop_split('sort_on', None)
else:
# Empty result set
@@ -630,7 +637,8 @@
cr.stop()
return result
- def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1):
+ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
+ actual_result_count=None):
# Sort a result set using a sort index. Return a lazy
# result set in sorted order if merge is true otherwise
# returns a list of (sortkey, uid, getter_function) tuples
@@ -648,7 +656,11 @@
append = result.append
if hasattr(rs, 'keys'):
rs = rs.keys()
- rlen = len(rs)
+ if actual_result_count is None:
+ rlen = len(rs)
+ actual_result_count = rlen
+ else:
+ rlen = actual_result_count
if merge and limit is None and (
rlen > (len(sort_index) * (rlen / 100 + 1))):
@@ -683,7 +695,7 @@
result.sort(reverse=True)
else:
result.sort()
- result = LazyCat(LazyValues(result), length)
+ result = LazyCat(LazyValues(result), length, actual_result_count)
elif limit is None or (limit * 4 > rlen):
# Iterate over the result set getting sort keys from the index
for did in rs:
@@ -706,6 +718,7 @@
if limit is not None:
result = result[:limit]
result = LazyValues(result)
+ result.actual_result_count = actual_result_count
else:
return result
elif reverse:
@@ -735,6 +748,7 @@
result.reverse()
if merge:
result = LazyValues(result)
+ result.actual_result_count = actual_result_count
else:
return result
elif not reverse:
@@ -761,12 +775,12 @@
best = keys[-1]
if merge:
result = LazyValues(result)
+ result.actual_result_count = actual_result_count
else:
return result
- result = LazyMap(self.__getitem__, result, len(result))
- result.actual_result_count = rlen
- return result
+ return LazyMap(self.__getitem__, result, len(result),
+ actual_result_count=actual_result_count)
def _get_sort_attr(self, attr, kw):
"""Helper function to find sort-on or sort-order."""
Modified: Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py 2010-12-26 19:03:16 UTC (rev 119145)
+++ Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py 2010-12-26 19:20:27 UTC (rev 119146)
@@ -326,6 +326,7 @@
# set is much larger than the sort index.
a = self._catalog(att1='att1', sort_on='att1')
self.assertEqual(len(a), self.upper)
+ self.assertEqual(a.actual_result_count, self.upper)
def testSortLimit(self):
full = self._catalog(att1='att1', sort_on='num')
More information about the checkins
mailing list