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)
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)
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.
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
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])
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
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):
# 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
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)