[Zope-CVS] CVS: Packages/pypes/pypes - order.py:1.2

Casey Duncan casey at zope.com
Mon Nov 29 02:03:05 EST 2004


Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv29709

Modified Files:
	order.py 
Log Message:
refactor multi-expression sort algorithm, it now seems to return correct results and should hopefully be easier to follow.


=== Packages/pypes/pypes/order.py 1.1 => 1.2 ===
--- Packages/pypes/pypes/order.py:1.1	Fri Aug 20 16:21:23 2004
+++ Packages/pypes/pypes/order.py	Mon Nov 29 02:02:34 2004
@@ -80,7 +80,12 @@
                             yield value
                 else:
                     for key, value in sortiter:
-                        if key in groups:
+                        try:
+                            key_in_groups = key in groups
+                        except TypeError:
+                            # Key is unhashable and couldn't possibly be in a group
+                            key_in_groups = False
+                        if key_in_groups:
                             stack.append((sortiter, groups))
                             sorted, groups = groups[key]
                             depth += 1
@@ -180,54 +185,52 @@
     if len(exprs) == 1:
         return _sort_single(iterable, exprs[0])
     sortfuncs = _make_sort_funcs(exprs)
-    top_groups = {} # sort key => group trees
-    top_ordered = OOBTree() # sort key => object or group tree
-    deferred = []
-    for obj in itertools.chain(iterable, deferred):
-        groups = top_groups
-        ordered = top_ordered
-        for sortkey in sortfuncs:
-            key = sortkey(obj)
+    sortfunc_indexes = range(len(sortfuncs))
+    max_sortfunc_index = sortfunc_indexes[-1]
+    root_groups = {} # sort key => group trees
+    root_ordered = OOBTree() # sort key => object or group tree
+    for obj in iterable:
+        groups = root_groups
+        ordered = root_ordered
+        for i in sortfunc_indexes:
+            key = sortfuncs[i](obj)
             try:
                 ingroup = key in groups
             except TypeError:
                 # Key is not hashable, switch to BTree
                 if isinstance(groups, dict):
-                    if groups is top_groups:
-                        top_groups = groups = OOBTree(groups)
+                    if groups is root_groups:
+                        root_groups = groups = OOBTree(groups)
                     else:
                         groups = OOBTree(groups)
                 else:
                     raise
             if ingroup:
-                groups, ordered = groups[key]
+                # Duplicate key
+                ordered, groups = groups[key]
             elif ordered.insert(key, obj):
+                # New key inserted
                 break
             else:
-                depth = sortfuncs.index(sortkey) + 1
-                firstobj = ordered[key]
-                try:
-                    sortkey = sortfuncs[depth]
-                except IndexError:
-                    groups[key] = ordered[key] = [firstobj, obj]
+                # First collision for this key
+                if i < max_sortfunc_index:
+                    # Add a new child group and tree
+                    firstobj = ordered[key]
+                    groups[key] = ordered[key] = OOBTree(), {}
+                    ordered, groups = groups[key]
+                    firstobj_key = sortfuncs[i + 1](firstobj)
+                    ordered[firstobj_key] = firstobj
                 else:
-                    old_groups = groups
-                    groups = {}
-                    old_groups[key] = ordered[key] = groups, OOBTree()
-                    firstkey = sortkey(firstobj)
-                    if firstkey != key:
-                        ordered[firstkey] = firstobj
-                    else:
-                        # come back for this one later
-                        deferred.append(firstobj)
-                    ordered[key] = obj
-                break
+                    # This is the last sort function
+                    # collect the colliding objects into leaf list 
+                    groups[key] = ordered[key] = [firstobj, obj]
+                    break
         else:
             if key in groups:
                 groups[key].append(obj)
             else:
                 groups[key] = ordered[key] = [ordered[key], obj]
-    return top_ordered, top_groups
+    return root_ordered, root_groups
 
 
 def _make_sort_funcs(exprs):



More information about the Zope-CVS mailing list