Commit b9cd866a authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

* optimise sortValueList().

  * use sort(key=func) instead of sort(cmp=func) if possible.
  * cache keyword arguments for sort().


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@23875 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 146e7c6c
...@@ -65,62 +65,94 @@ from Accessor.TypeDefinition import list_types ...@@ -65,62 +65,94 @@ from Accessor.TypeDefinition import list_types
# Generic sort method # Generic sort method
##################################################### #####################################################
sort_kw_cache = {}
def sortValueList(value_list, sort_on=None, sort_order=None, **kw): def sortValueList(value_list, sort_on=None, sort_order=None, **kw):
"""Sort values in a way compatible with ZSQLCatalog. """Sort values in a way compatible with ZSQLCatalog.
""" """
if sort_on is not None: if sort_on is not None:
if isinstance(sort_on, str): if isinstance(sort_on, str):
sort_on = (sort_on,) sort_on = (sort_on,)
reverse = (sort_order in ('descending', 'reverse', 'DESC')) # try to cache keyword arguments for sort()
new_sort_on = [] sort_on = tuple([isinstance(x, str) and x or tuple(x) for x in sort_on])
for key in sort_on: try:
if isinstance(key, str): sort_kw = sort_kw_cache[sort_on]
new_sort_on.append((key, reverse, None)) except KeyError:
else: new_sort_on = []
if len(key) == 1: reverse_dict = {}
new_sort_on.append((key[0], reverse, None)) for key in sort_on:
elif len(key) == 2: if isinstance(key, str):
new_sort_on.append((key[0], reverse = (sort_order in ('descending', 'reverse', 'DESC'))
key[1] in ('descending', 'reverse', 'DESC'), new_sort_on.append((key, reverse, None))
None)) reverse_dict[reverse] = True
else: else:
# Emulate MySQL types if len(key) == 1:
as_type = key[2].lower() reverse = (sort_order in ('descending', 'reverse', 'DESC'))
if as_type in ('int', 'bigint'): new_sort_on.append((key[0], reverse, None))
f=int reverse_dict[reverse] = True
elif as_type in ('float', 'real', 'double'): elif len(key) == 2:
f=float reverse = (key[1] in ('descending', 'reverse', 'DESC'))
new_sort_on.append((key[0], reverse, None))
reverse_dict[reverse] = True
else: else:
# XXX: For an unknown type, use a string. # Emulate MySQL types
f=str as_type = key[2].lower()
new_sort_on.append((key[0], if as_type in ('int', 'bigint'):
key[1] in ('descending', 'reverse', 'DESC'), f=int
f)) elif as_type in ('float', 'real', 'double'):
sort_on = new_sort_on f=float
else:
def sortValues(a, b): # XXX: For an unknown type, use a string.
result = 0 f=str
for key, reverse, as_type in sort_on: reverse = (key[1] in ('descending', 'reverse', 'DESC'))
x = a.getProperty(key, None) new_sort_on.append((key[0], reverse, f))
y = b.getProperty(key, None) reverse_dict[reverse] = True
if as_type is not None:
try: if len(reverse_dict) == 1:
x = as_type(x) # if we have only one kind of reverse value (i.e. all True or all
y = as_type(y) # False), we can use sort(key=func) that is faster than
except TypeError: # sort(cmp=func).
pass def sortValue(a):
result = cmp(x, y) value_list = []
if reverse: for key, reverse, as_type in new_sort_on:
result = -result x = a.getProperty(key, None)
if result != 0: if as_type is not None:
break try:
return result x = as_type(x)
except TypeError:
pass
value_list.append(x)
return value_list
sort_kw = {'key':sortValue, 'reverse':reverse}
sort_kw_cache[sort_on] = sort_kw
else:
# otherwise we use sort(cmp=func).
def sortValues(a, b):
result = 0
for key, reverse, as_type in new_sort_on:
x = a.getProperty(key, None)
y = b.getProperty(key, None)
if as_type is not None:
try:
x = as_type(x)
y = as_type(y)
except TypeError:
pass
result = cmp(x, y)
if reverse:
result = -result
if result != 0:
break
return result
sort_kw = {'cmp':sortValues, 'reverse':reverse}
sort_kw_cache[sort_on] = sort_kw
if isinstance(value_list, LazyMap): if isinstance(value_list, LazyMap):
new_value_list = [x for x in value_list] new_value_list = [x for x in value_list]
value_list = new_value_list value_list = new_value_list
value_list.sort(sortValues)
value_list.sort(**sort_kw)
return value_list return value_list
##################################################### #####################################################
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment