Please review this at http://codereview.appspot.com/186206/show

Affected files:
  M trytond/tools/misc.py


Index: trytond/tools/misc.py
===================================================================
--- a/trytond/tools/misc.py
+++ b/trytond/tools/misc.py
@@ -458,6 +458,8 @@
     def __ne__(self, y):
         return self.dict.__ne__(y)

+_REDUCE_IDS_CACHE = {}
+
 def reduce_ids(field, ids):
     '''
     Return a small SQL clause for ids
@@ -468,39 +470,46 @@
     '''
     if not ids:
         return '(%s)', [False]
-    ids = ids[:]
-    ids.sort()
-    prev = ids.pop(0)
-    continue_list = [prev, prev]
-    discontinue_list = []
-    sql = []
-    args = []
-    for i in ids:
-        if i == prev:
-            continue
-        if i != prev + 1:
-            if continue_list[-1] - continue_list[0] < 5:
-                discontinue_list.extend([continue_list[0] + x for x in
-                    range(continue_list[-1] - continue_list[0] + 1)])
-            else:
-                sql.append('((' + field + ' >= %s) AND (' + field + '
<= %s))')
-                args.append(continue_list[0])
-                args.append(continue_list[-1])
-            continue_list = []
-        continue_list.append(i)
-        prev = i
-    if continue_list[-1] - continue_list[0] < 5:
-        discontinue_list.extend([continue_list[0] + x for x in
-            range(int(continue_list[-1] - continue_list[0] + 1))])
-    else:
-        sql.append('((' + field + ' >= %s) AND (' + field + ' <= %s))')
-        args.append(continue_list[0])
-        args.append(continue_list[-1])
-    if discontinue_list:
-        sql.append('(' + field + ' IN (' + \
-                ','.join(('%s',) * len(discontinue_list)) + '))')
-        args.extend(discontinue_list)
-    return '(' + ' OR '.join(sql) + ')', args
+    key = (field, str(set(ids)))
+    res = _REDUCE_IDS_CACHE.get(key)
+    if not res:
+        ids = ids[:]
+        ids.sort()
+        prev = ids.pop(0)
+        continue_list = [prev, prev]
+        discontinue_list = []
+        sql = []
+        args = []
+        for i in ids:
+            if i == prev:
+                continue
+            if i != prev + 1:
+                if continue_list[-1] - continue_list[0] < 5:
+                    discontinue_list.extend([continue_list[0] + x for x in
+                        range(continue_list[-1] - continue_list[0] + 1)])
+                else:
+                    sql.append('((' + field + ' >= %s) AND (' + field
+ ' <= %s))')
+                    args.append(continue_list[0])
+                    args.append(continue_list[-1])
+                continue_list = []
+            continue_list.append(i)
+            prev = i
+        if continue_list[-1] - continue_list[0] < 5:
+            discontinue_list.extend([continue_list[0] + x for x in
+                range(int(continue_list[-1] - continue_list[0] + 1))])
+        else:
+            sql.append('((' + field + ' >= %s) AND (' + field + ' <= %s))')
+            args.append(continue_list[0])
+            args.append(continue_list[-1])
+        if discontinue_list:
+            sql.append('(' + field + ' IN (' + \
+                    ','.join(('%s',) * len(discontinue_list)) + '))')
+            args.extend(discontinue_list)
+        res = '(' + ' OR '.join(sql) + ')', args
+        if len(_REDUCE_IDS_CACHE) > 1024:
+            _REDUCE_IDS_CACHE.clear()
+        _REDUCE_IDS_CACHE[key] = res
+    return res

 _ALLOWED_CODES = set(dis.opmap[x] for x in [
     'POP_TOP','ROT_TWO','ROT_THREE','ROT_FOUR','DUP_TOP',



-- 
Cédric Krier

B2CK SPRL
Rue de Rotterdam, 4
4000 Liège
Belgium
Tel: +32 472 54 46 59
Email: [email protected]
Jabber: [email protected]
Website: http://www.b2ck.com/
twitter: http://twitter.com/cedrickrier
identi.ca: http://identi.ca/cedrickrier

Attachment: pgpm89MHcha4L.pgp
Description: PGP signature

Reply via email to