| Home | Trees | Indices | Help |
|---|
|
|
1 import logging 2 import threading 3 4 from concurrent_tree_crawler.abstract_tree_accessor import \ 5 AbstractTreeAccessor, NodeAction 6 from concurrent_tree_crawler.abstract_node import NodeState 79 """ 10 An interface for the tree made of L{AbstractNode}s. 11 Access to sensitive methods is protected by concurrent programming objects: 12 locks and conditions. 13 """12615 """ 16 @param sentinel: a technical node which will be made parent of the 17 root node. 18 @type sentinel: L{AbstractNode} 19 """ 20 21 self.__sentinel = sentinel 22 """ 23 The sentinel is a purely technical object. It shouldn't be 24 analyzed by the navigator. It is here just to make sure that the 25 root of the tree has a parent. This is because it is required by our 26 algorithm that all of the nodes in the tree have a parent. 27 """ 28 29 self.__root = None 30 """The main business-level element of the tree""" 31 32 ## The one and only child of the sentinel is the root node 33 if self.__sentinel.has_child("root"): 34 self.__root = self.__sentinel.get_child("root") 35 else: 36 self.__root = self.__sentinel.add_child("root", NodeState.OPEN)37 40 4345 while True: 46 node.get_children_cond().acquire() 47 try: 48 child = node.update_and_get_child(possible_children_names) 49 if child is None: ## No accessible children are available 50 return None 51 state = child.get_state() 52 if state == NodeState.OPEN: 53 child.set_state(NodeState.PROCESSING) 54 return (child, NodeAction.TO_PROCESS) 55 elif state == NodeState.VISITED: 56 return (child, NodeAction.TO_VISIT) 57 elif state == NodeState.PROCESSING: 58 self.__log("Starting to wait on \"{}\" node children".\ 59 format(node.get_name())) 60 node.get_children_cond().wait() 61 self.__log("Done waiting on \"{}\" node children".format( 62 node.get_name())) 63 else: 64 assert False, "Unknown node state: {}".format(state) 65 finally: 66 node.get_children_cond().release()6769 assert node != self.__sentinel, "Processing sentinel is not allowed" 70 parent = node.get_parent() 71 parent.get_children_cond().acquire() 72 try: 73 if is_leaf: 74 node.set_state(NodeState.CLOSED) 75 self.__internal_update_node_state(parent) 76 else: 77 node.set_state(NodeState.VISITED) 78 finally: 79 parent.get_children_cond().notify_all() 80 parent.get_children_cond().release()81 8486 assert node != self.__sentinel, "Changing sentinel state is not allowed" 87 parent = node.get_parent() 88 parent.get_children_cond().acquire() 89 try: 90 node.set_state(new_state) 91 self.__internal_update_node_state(parent) 92 finally: 93 parent.get_children_cond().notify_all() 94 parent.get_children_cond().release()9597 """@param node: L{AbstractNode}""" 98 if node == self.__sentinel: 99 ## The state of the sentinel is undefined and not used 100 ## in the program, it should not be changed 101 return 102 new_state = None 103 if node.all_children_are_in_one_of_states({NodeState.CLOSED}): 104 new_state = NodeState.CLOSED 105 elif node.all_children_are_in_one_of_states( 106 {NodeState.ERROR, NodeState.CLOSED}): 107 new_state = NodeState.ERROR 108 ## Node state does not have to be changed 109 if new_state is None: 110 return 111 parent = node.get_parent() 112 parent.get_children_cond().acquire() 113 try: 114 node.set_state(new_state) 115 self.__internal_update_node_state(parent) 116 finally: 117 parent.get_children_cond().notify_all() 118 parent.get_children_cond().release()119
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Sun Sep 25 22:18:23 2011 | http://epydoc.sourceforge.net |