[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