"New instance %s with identity key %s conflicts "
"with persistent instance %s" %
(state_str(state), instance_key, state_str(existing)))
-
+
self._log_debug(
- "detected row switch for identity %s. will update %s, remove %s from "
- "transaction", instance_key, state_str(state), state_str(existing))
-
+ "detected row switch for identity %s. "
+ "will update %s, remove %s from "
+ "transaction", instance_key,
+ state_str(state), state_str(existing))
+
# remove the "delete" flag from the existing element
- uowtransaction.set_row_switch(existing)
+ uowtransaction.remove_state_actions(existing)
- row_switches[state] = existing
-
+ row_switch = existing
+
+ tups.append(
+ (state,
+ mapper,
+ conn,
+ has_identity,
+ instance_key,
+ row_switch)
+ )
+
table_to_mapper = self._sorted_tables
- for table in table_to_mapper.iterkeys():
+ for table in table_to_mapper:
insert = []
update = []
queue.append(childnode)
return output
-def _organize_as_tree(nodes):
- """Given a list of nodes from a topological sort, organize the
- nodes into a tree structure, with as many non-dependent nodes
- set as siblings to each other as possible.
-
- returns nodes as 3-tuples (item, cycles, children).
- """
-
- if not nodes:
- return None
- # a list of all currently independent subtrees as a tuple of
- # (root_node, set_of_all_tree_nodes, set_of_all_cycle_nodes_in_tree)
- # order of the list has no semantics for the algorithmic
- independents = []
- # in reverse topological order
- for node in reversed(nodes):
- # nodes subtree and cycles contain the node itself
- subtree = set([node])
- if node.cycles is not None:
- cycles = set(node.cycles)
- else:
- cycles = set()
- # get a set of dependent nodes of node and its cycles
- nodealldeps = node.all_deps()
- if nodealldeps:
- # iterate over independent node indexes in reverse order so we can efficiently remove them
- for index in xrange(len(independents) - 1, -1, -1):
- child, childsubtree, childcycles = independents[index]
- # if there is a dependency between this node and an independent node
- if (childsubtree.intersection(nodealldeps) or childcycles.intersection(node.dependencies)):
- # prepend child to nodes children
- # (append should be fine, but previous implemetation used prepend)
- node.children[0:0] = [(child.item, [n.item for n in child.cycles or []], child.children)]
- # merge childs subtree and cycles
- subtree.update(childsubtree)
- cycles.update(childcycles)
- # remove the child from list of independent subtrees
- independents[index:index+1] = []
- # add node as a new independent subtree
- independents.append((node, subtree, cycles))
- # choose an arbitrary node from list of all independent subtrees
- head = independents.pop()[0]
- # add all other independent subtrees as a child of the chosen root
- # used prepend [0:0] instead of extend to maintain exact behaviour of previous implementation
- head.children[0:0] = [(i[0].item, [n.item for n in i[0].cycles or []], i[0].children) for i in independents]
- return (head.item, [n.item for n in head.cycles or []], head.children)
-
-def _find_cycles(edges):
- cycles = {}
-
- def traverse(node, cycle, goal):
- for (n, key) in edges.edges_by_parent(node):
- if key in cycle:
- continue
- cycle.append(key)
- if key is goal:
- cycset = set(cycle)
- for x in cycle:
- if x in cycles:
- existing_set = cycles[x]
- existing_set.update(cycset)
- for y in existing_set:
- cycles[y] = existing_set
- cycset = existing_set
- else:
- cycles[x] = cycset
- else:
- traverse(key, cycle, goal)
- cycle.pop()
-
- for parent in edges.get_parents():
- traverse(parent, [], parent)
+def find_cycles(tuples, allitems):
+ # straight from gvr with some mods
+ todo = set(allitems)
+ edges = _EdgeCollection()
- unique_cycles = set(tuple(s) for s in cycles.values())
+ for t in tuples:
+ todo.update(t)
+ edges.add(t)
- for cycle in unique_cycles:
- edgecollection = [edge for edge in edges
- if edge[0] in cycle and edge[1] in cycle]
- yield edgecollection
+ output = set()
+
+ while todo:
+ node = todo.pop()
+ stack = [node]
+ while stack:
+ top = stack[-1]
+ for node in edges.outgoing(top):
+ if node in stack:
+ cyc = stack[stack.index(node):]
+ todo.difference_update(cyc)
+ output.update(cyc)
+
+ if node in todo:
+ stack.append(node)
+ todo.remove(node)
+ break
+ else:
+ node = stack.pop()
+ return output
-