Add tree/sub-tree traversal to Trie

Accurately retrieve listeners for a specific error code
This commit is contained in:
Ian Cordasco 2015-12-29 08:07:47 -06:00
parent 75f15340ac
commit 57e8583e29
2 changed files with 32 additions and 8 deletions

View file

@ -35,6 +35,16 @@ class Trie(object):
node = child node = child
return node return node
def traverse(self):
"""Traverse this tree.
This performs a depth-first pre-order traversal of children in this
tree. It returns the results consistently by first sorting the
children based on their prefix and then traversing them in
alphabetical order.
"""
return self.root.traverse()
class TrieNode(object): class TrieNode(object):
"""The majority of the implementation details of a Trie.""" """The majority of the implementation details of a Trie."""
@ -47,8 +57,8 @@ class TrieNode(object):
def __repr__(self): def __repr__(self):
"""Generate an easy to read representation of the node.""" """Generate an easy to read representation of the node."""
return 'TrieNode(prefix={0}, data={1}, children={2})'.format( return 'TrieNode(prefix={0}, data={1})'.format(
self.prefix, self.data, dict(self.children) self.prefix, self.data
) )
def find_prefix(self, prefix): def find_prefix(self, prefix):
@ -70,5 +80,18 @@ class TrieNode(object):
return new_node return new_node
def traverse(self): def traverse(self):
"""Traverse children of this node in order.""" """Traverse children of this node.
raise NotImplementedError()
This performs a depth-first pre-order traversal of the remaining
children in this sub-tree. It returns the results consistently by
first sorting the children based on their prefix and then traversing
them in alphabetical order.
"""
if not self.children:
return
for prefix in sorted(self.children.keys()):
child = self.children[prefix]
yield child
for child in child.traverse():
yield child

View file

@ -7,12 +7,13 @@ class Notifier(object):
def listeners_for(self, error_code): def listeners_for(self, error_code):
node = self.listeners.find(error_code) node = self.listeners.find(error_code)
if node is None:
return
for listener in node.data: for listener in node.data:
yield listener yield listener
if node.children: for child in node.traverse():
for child in node.traverse(): for listener in child.data:
for listener in child.data: yield listener
yield listener
def notify(self, error_code, *args, **kwargs): def notify(self, error_code, *args, **kwargs):
for listener in self.listeners_for(error_code): for listener in self.listeners_for(error_code):