[Checkins] SVN: Products.ZCatalog/trunk/ If batching arguments are provided, limit the returned lazy sequence to the items in the required batch instead of returning trailing items falling outside of the requested batch.
Hanno Schlichting
hannosch at hannosch.eu
Wed Jan 26 16:32:13 EST 2011
Log message for revision 119951:
If batching arguments are provided, limit the returned lazy sequence to the items in the required batch instead of returning trailing items falling outside of the requested batch.
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 2011-01-26 16:42:43 UTC (rev 119950)
+++ Products.ZCatalog/trunk/CHANGES.txt 2011-01-26 21:32:13 UTC (rev 119951)
@@ -4,6 +4,10 @@
2.13.4 (unreleased)
-------------------
+- If batching arguments are provided, limit the returned lazy sequence to the
+ items in the required batch instead of returning trailing items falling
+ outside of the requested batch.
+
- Fixed inline `IISet` to `IITreeSet` conversion code inside DateRangeIndex'
`_insertForwardIndexEntry` method.
Modified: Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py 2011-01-26 16:42:43 UTC (rev 119950)
+++ Products.ZCatalog/trunk/src/Products/ZCatalog/Catalog.py 2011-01-26 21:32:13 UTC (rev 119951)
@@ -480,6 +480,13 @@
order.sort()
return [i[1] for i in order]
+ def _limit_sequence(self, sequence, slen, b_start=0, b_size=None):
+ if b_size is not None:
+ sequence = sequence[b_start:b_start + b_size]
+ if slen:
+ slen = len(sequence)
+ return (sequence, slen)
+
def search(self, query, sort_index=None, reverse=0, limit=None, merge=1):
"""Iterate through the indexes, applying the query to each one. If
merge is true then return a lazy result set (sorted if appropriate)
@@ -547,10 +554,16 @@
cr.stop_split(i, result=None, limit=limit_result)
# Try to deduce the sort limit from batching arguments
- if limit is None:
- if 'b_start' in query and 'b_size' in query:
- limit = int(query['b_start']) + int(query['b_size'])
+ b_start = int(query.get('b_start', 0))
+ b_size = query.get('b_size', None)
+ if b_size is not None:
+ b_size = int(b_size)
+ if b_size is not None:
+ limit = b_start + b_size
+ elif limit and b_size is None:
+ b_size = limit
+
if rs is None:
# None of the indexes found anything to do with the query
# We take this to mean that the query was empty (an empty filter)
@@ -563,13 +576,16 @@
rlen = len(self)
if sort_index is None:
- result = LazyMap(self.instantiate, self.data.items(), rlen,
+ sequence, slen = self._limit_sequence(self.data.items(), rlen,
+ b_start, b_size)
+ result = LazyMap(self.instantiate, sequence, slen,
actual_result_count=rlen)
else:
cr.start_split('sort_on')
result = self.sortResults(
self.data, sort_index, reverse, limit, merge,
- actual_result_count=rlen)
+ actual_result_count=rlen, b_start=b_start,
+ b_size=b_size)
cr.stop_split('sort_on', None)
elif rs:
# We got some results from the indexes.
@@ -612,7 +628,9 @@
r.data_record_normalized_score_ = int(100. * score / max)
return r
- result = LazyMap(getScoredResult, rs, rlen,
+ sequence, slen = self._limit_sequence(rs, rlen, b_start,
+ b_size)
+ result = LazyMap(getScoredResult, sequence, slen,
actual_result_count=rlen)
cr.stop_split('sort_on', None)
@@ -620,7 +638,9 @@
# no scores
if hasattr(rs, 'keys'):
rs = rs.keys()
- result = LazyMap(self.__getitem__, rs, rlen,
+ sequence, slen = self._limit_sequence(rs, rlen, b_start,
+ b_size)
+ result = LazyMap(self.__getitem__, sequence, slen,
actual_result_count=rlen)
else:
# sort. If there are scores, then this block is not
@@ -629,7 +649,8 @@
# sort by relevance first, then the 'sort-on' attribute.
cr.start_split('sort_on')
result = self.sortResults(rs, sort_index, reverse, limit,
- merge, actual_result_count=rlen)
+ merge, actual_result_count=rlen, b_start=b_start,
+ b_size=b_size)
cr.stop_split('sort_on', None)
else:
# Empty result set
@@ -638,7 +659,7 @@
return result
def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
- actual_result_count=None):
+ actual_result_count=None, b_start=0, b_size=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
@@ -695,7 +716,9 @@
result.sort(reverse=True)
else:
result.sort()
- result = LazyCat(LazyValues(result), length, actual_result_count)
+ sequence, slen = self._limit_sequence(result, length, b_start,
+ b_size)
+ result = LazyCat(LazyValues(sequence), slen, 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:
@@ -717,10 +740,12 @@
result.sort()
if limit is not None:
result = result[:limit]
- result = LazyValues(result)
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ result = LazyValues(sequence)
result.actual_result_count = actual_result_count
else:
- return result
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ return sequence
elif reverse:
# Limit/sort results using N-Best algorithm
# This is faster for large sets then a full sort
@@ -747,10 +772,12 @@
worst = keys[0]
result.reverse()
if merge:
- result = LazyValues(result)
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ result = LazyValues(sequence)
result.actual_result_count = actual_result_count
else:
- return result
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ return sequence
elif not reverse:
# Limit/sort results using N-Best algorithm in reverse (N-Worst?)
keys = []
@@ -774,10 +801,12 @@
n += 1
best = keys[-1]
if merge:
- result = LazyValues(result)
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ result = LazyValues(sequence)
result.actual_result_count = actual_result_count
else:
- return result
+ sequence, _ = self._limit_sequence(result, 0, b_start, b_size)
+ return sequence
return LazyMap(self.__getitem__, result, len(result),
actual_result_count=actual_result_count)
Modified: Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py 2011-01-26 16:42:43 UTC (rev 119950)
+++ Products.ZCatalog/trunk/src/Products/ZCatalog/tests/test_catalog.py 2011-01-26 21:32:13 UTC (rev 119951)
@@ -359,13 +359,13 @@
query = dict(att1='att1', sort_on='num', b_start=11, b_size=17)
result = self._catalog(query)
self.assertEqual(result.actual_result_count, 100)
- self.assertEqual([r.num for r in result], range(28))
+ self.assertEqual([r.num for r in result], range(11, 28))
def testSortLimitViaBatchingArgsEnd(self):
query = dict(att1='att1', sort_on='num', b_start=90, b_size=15)
result = self._catalog(query)
self.assertEqual(result.actual_result_count, 100)
- self.assertEqual([r.num for r in result], range(100))
+ self.assertEqual([r.num for r in result], range(90, 100))
# _get_sort_attr
# _getSortIndex
More information about the checkins
mailing list