]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
dependency sort....bleah
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 31 Oct 2005 00:14:01 +0000 (00:14 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 31 Oct 2005 00:14:01 +0000 (00:14 +0000)
lib/sqlalchemy/mapper.py
lib/sqlalchemy/objectstore.py
lib/sqlalchemy/util.py
test/dependency.py

index b91095b50eb8767eabee13ee76d86d23b3f2cd92..4fc5fbc8b412bb111292afa531b719572fe097a3 100644 (file)
@@ -911,7 +911,7 @@ class PropertyLoader(MapperProperty):
                 for child in childlist.added_items():
                     self._synchronize(obj, child, None, False)
                     if self.direction == PropertyLoader.LEFT:
-                        uowcommit.register_object(child, sort=True)
+                        uowcommit.register_object(child)
                 if self.direction != PropertyLoader.RIGHT or len(childlist.added_items()) == 0:
                     for child in childlist.deleted_items():
                         self._synchronize(obj, child, None, True)
index 28c551a781e1a4f48d77f01147ac75473a1d103a..3d5b3851f1cc3898c17b81532aa7ec5a80dee257 100644 (file)
@@ -324,7 +324,7 @@ class UOWTransaction(object):
             task.mapper.register_dependencies(self)
 
         head = self._sort_dependencies()
-        print "Task dump:\n" + head.dump()
+        #print "Task dump:\n" + head.dump()
         if head is not None:
             head.execute(self)
             
@@ -408,7 +408,7 @@ class UOWTask(object):
     def is_empty(self):
         return len(self.objects) == 0 and len(self.dependencies) == 0 and len(self.childtasks) == 0
             
-    def append(self, obj, listonly = False, childtask = None, isdelete = False, sort=False):
+    def append(self, obj, listonly = False, childtask = None, isdelete = False):
         """appends an object to this task, to be either saved or deleted
         depending on the 'isdelete' attribute of this UOWTask.  'listonly' indicates
         that the object should only be processed as a dependency and not actually saved/deleted.
@@ -417,8 +417,6 @@ class UOWTask(object):
         tasks, to assign dependent operations at the per-object instead of per-task level."""
         try:
             rec = self.objects[obj]
-            if sort:
-                self.objects.toend(obj)
         except KeyError:
             rec = UOWTaskElement(obj)
             self.objects[obj] = rec
index 2f6abcccd89d285ae1bc784da8b4684b9cf57406..bae5d6bad52b7031b1d2b480ef9dcb3a2ae7e8c0 100644 (file)
@@ -57,15 +57,6 @@ class OrderedDict(dict):
         self.list = []
         dict.clear(self)
     
-    def toend(self, key):
-        # TODO: optimize this 
-        try:
-            del self.list[self.list.index(key)]
-            self.list.append(key)
-            print "toend: " + repr(key)
-        except ValueError:
-            raise KeyError(key)
-        
     def update(self, dict):
         for key in dict.keys():
             self.__setitem__(key, dict[key])
@@ -340,6 +331,7 @@ class DependencySorter(object):
     is marked as "circular", indicating the node is dependent on itself.
     """
     class Node:
+        """represents a node in a tree.  stores an 'item' which represents the dependent thing we are talking about.  if node 'a' is an ancestor node of node 'b', it means 'a's item is *not* dependent on that of 'b'."""
         def __init__(self, item):
             #print "new node on " + str(item)
             self.item = item
@@ -347,10 +339,32 @@ class DependencySorter(object):
             self.parent = None
             self.circular = False
         def append(self, node):
+            """appends the given node as a child on this node.  removes the node from its preexisting parent."""
             if node.parent is not None:
                 del node.parent.children[node]
             self.children.append(node)
             node.parent = self
+        def is_descendant_of(self, node):
+            """returns true if this node is a descendant of the given node"""
+            n = self
+            while n is not None:
+                if n is node:
+                    return True
+                else:
+                    n = n.parent
+            return False
+        def get_root(self):
+            """returns the highest ancestor node of this node, i.e. which has no parent"""
+            n = self
+            while n.parent is not None:
+                n = n.parent
+            return n
+        def get_highest_sibling(self, node):
+            """returns the highest ancestor node of this one which is either the root node, or the common parent of this node and the given node"""
+            n = self
+            while n.parent is not None and n.parent is not node.parent:
+                n = n.parent
+            return n
         def __str__(self):
             return self.safestr({})
         def safestr(self, hash, indent = 0):
@@ -385,28 +399,23 @@ class DependencySorter(object):
 
             # get child node
             childnode = nodes[child]
-                    
-            # now see, if the parent is an ancestor of the child
-            c = childnode
-            while c is not None and c is not parentnode:
-                root = c
-                c = c.parent
+            
+            if parentnode.parent is childnode:
+                # check for "a switch"
+                t = parentnode.item
+                parentnode.item = childnode.item
+                childnode.item = t
+                nodes[parentnode.item] = parentnode
+                nodes[childnode.item] = childnode
+            elif parentnode.is_descendant_of(childnode):
+                # check for a line thats backwards with nodes in between, this is a 
+                # circular dependency (although confirmation on this would be helpful)
+                raise "Circular dependency detected"
+            elif not childnode.is_descendant_of(parentnode):
+                # if relationship doesnt exist, connect nodes together
+                root = childnode.get_highest_sibling(parentnode)
+                parentnode.append(root)
 
-            # nope, so we have to move the child down from whereever
-            # it currently is to a child of the parent
-            if c is None:
-                if childnode.parent is None:
-                    print "moving down " + str(childnode.item) + ", has no parent"
-                    parentnode.append(childnode)
-                else:
-                    print "item " + str(childnode.item)  + " has a parent " +  str(childnode.parent.item)
-                    for c in parentnode.children:
-                        c.parent = root
-                        root.children.append(c)
-                        del parentnode.children[c]
-                    root.parent = parentnode
-                    parentnode.children.append(root)
-        
         # now we have a collection of subtrees which represent dependencies.
         # go through the collection root nodes wire them together into one tree        
         head = None
index d08df45e93105d9775bc46f2b72eb94e46d5dbf9..5dbc9be4accaf9bd4e10a4de0f004310c5721dd9 100644 (file)
@@ -59,31 +59,29 @@ class DependencySortTest(PersistTest):
         node3 = thingy('items')
         tuples = [
             (node1, node2),
-            (node3, node2)
+            (node3, node2),
+            (node1,node3)
         ]
-#        head1 = util.DependencySorter(tuples, [node1, node2, node3]).sort()
+        head1 = util.DependencySorter(tuples, [node1, node2, node3]).sort()
         head2 = util.DependencySorter(tuples, [node3, node1, node2]).sort()
#       head3 = util.DependencySorter(tuples, [node3, node2, node1]).sort()
+        head3 = util.DependencySorter(tuples, [node3, node2, node1]).sort()
         
         # TODO: figure out a "node == node2" function
         #self.assert_(str(head1) == str(head2) == str(head3))
-  #      print "\n" + str(head1)
+        print "\n" + str(head1)
         print "\n" + str(head2)
-   #     print "\n" + str(head3)
+        print "\n" + str(head3)
 
     def testsort4(self):
         node1 = thingy('keywords')
         node2 = thingy('itemkeyowrds')
         node3 = thingy('items')
-        node4 = thingy('lala')
-        node5 = thingy('hoho')
-        
+        node4 = thingy('hoho')
         tuples = [
             (node1, node2),
-            (node5, node3),
-            (node4, node2),
-            (node3, node2),
-            
+            (node4, node1),
+            (node1, node3),
+            (node3, node2)
         ]
         head = util.DependencySorter(tuples, []).sort()
         print "\n" + str(head)