Skip to content

Commit

Permalink
cover n-best/n-worst sort algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
hannosch committed Mar 25, 2012
1 parent f7ec41c commit d56b783
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
31 changes: 19 additions & 12 deletions src/Products/ZCatalog/Catalog.py
Expand Up @@ -677,13 +677,10 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
if len(sort_index) > 1:
index2 = sort_index[1]
sort_index = sort_index[0]
_intersection = intersection
_self__getitem__ = self.__getitem__
index_key_map = sort_index.documentToKeyMap()
index2_key_map = (index2 is not None and
index2.documentToKeyMap() or None)
_None = None
_keyerror = KeyError
result = []
append = result.append
if hasattr(rs, 'keys'):
Expand Down Expand Up @@ -736,10 +733,10 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
# We have an index that has a set of values for
# each sort key, so we intersect with each set and
# get a sorted sequence of the intersections.
intset = _intersection(rs, intset)
intset = intersection(rs, intset)
if intset:
keys = getattr(intset, 'keys', _None)
if keys is not _None:
keys = getattr(intset, 'keys', None)
if keys is not None:
# Is this ever true?
intset = keys()
length += len(intset)
Expand All @@ -763,10 +760,11 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
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
# import pdb; pdb.set_trace()
for did in rs:
try:
key = index_key_map[did]
except _keyerror:
except KeyError:
# This document is not in the sort key index, skip it.
pass
else:
Expand Down Expand Up @@ -800,21 +798,26 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
for did in rs:
try:
key = index_key_map[did]
except _keyerror:
key2 = (index2_key_map is not None and
index2_key_map.get(did) or None)
except KeyError:
# This document is not in the sort key index, skip it.
pass
else:
if n >= limit and key <= worst:
continue
i = bisect(keys, key)
keys.insert(i, key)
result.insert(i, (key, did, _self__getitem__))
result.insert(i, ((key, key2), did, _self__getitem__))
if n == limit:
del keys[0], result[0]
else:
n += 1
worst = keys[0]
result.reverse()
if index2 is not None:
result.sort(reverse=True)
else:
result.reverse()
if merge:
sequence, _ = self._limit_sequence(result, 0, b_start, b_size,
switched_reverse)
Expand All @@ -832,20 +835,24 @@ def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1,
for did in rs:
try:
key = index_key_map[did]
except _keyerror:
key2 = (index2_key_map is not None and
index2_key_map.get(did) or None)
except KeyError:
# This document is not in the sort key index, skip it.
pass
else:
if n >= limit and key >= best:
continue
i = bisect(keys, key)
keys.insert(i, key)
result.insert(i, (key, did, _self__getitem__))
result.insert(i, ((key, key2), did, _self__getitem__))
if n == limit:
del keys[-1], result[-1]
else:
n += 1
best = keys[-1]
if index2 is not None:
result.sort()
if merge:
sequence, _ = self._limit_sequence(result, 0, b_start, b_size,
switched_reverse)
Expand Down
13 changes: 13 additions & 0 deletions src/Products/ZCatalog/tests/test_catalog.py
Expand Up @@ -507,6 +507,19 @@ def test_sort_on_two(self):
for x in range(self.upper):
self.assertEqual(a[x].num, x)

def test_sort_on_two_small_limit(self):
a = self._catalog(sort_on=('att1', 'num'), att1='att1', sort_limit=10)
self.assertEqual(len(a), 10)
for x in range(9):
self.assertTrue(a[x].num < a[x + 1].num)

def test_sort_on_two_small_limit_reverse(self):
a = self._catalog(sort_on=('att1', 'num'), att1='att1',
sort_limit=10, sort_order='reverse')
self.assertEqual(len(a), 10)
for x in range(9):
self.assertTrue(a[x].num > a[x + 1].num)

def testKeywordIndexWithMinRange(self):
a = self._catalog(att3={'query': 'att', 'range': 'min'})
self.assertEqual(len(a), self.upper)
Expand Down

0 comments on commit d56b783

Please sign in to comment.