filetree: mark leaf nodes by adding is_leaf_subtree(), stop traversing when we hit them, to make vdrive._get_file_uri() work

This commit is contained in:
Brian Warner 2007-01-21 13:31:16 -07:00
parent 9e7dbf20bc
commit 124d531b41
6 changed files with 47 additions and 3 deletions

View File

@ -104,6 +104,8 @@ class SubTreeNode:
child = node_maker.make_node_from_serialized(child_data)
self.children[name] = child
def is_leaf_subtree(self):
return False
class _DirectorySubTree(object):
@ -190,6 +192,9 @@ class LocalFileSubTreeNode(BaseDataNode):
def set_base_data(self, data):
self.filename = data
def is_leaf_subtree(self):
return False
class LocalFileSubTree(_DirectorySubTree):
node_class = LocalFileSubTreeNode
@ -238,6 +243,9 @@ class CHKDirectorySubTreeNode(BaseDataNode):
def get_uri(self):
return self.uri
def is_leaf_subtree(self):
return False
class CHKDirectorySubTree(_DirectorySubTree):
# maybe mutable, maybe not
@ -306,6 +314,9 @@ class SSKDirectorySubTreeNode(object):
def set_write_capability(self, write_cap):
self.write_cap = write_cap
def is_leaf_subtree(self):
return False
class SSKDirectorySubTree(_DirectorySubTree):
node_class = SSKDirectorySubTreeNode

View File

@ -20,6 +20,9 @@ class CHKFileNode(BaseDataNode):
def get_uri(self):
return self.uri
def is_leaf_subtree(self):
return True
class SSKFileNode(object):
implements(INode, IFileNode)
prefix = "SSKFile"
@ -37,3 +40,6 @@ class SSKFileNode(object):
def get_write_capability(self):
return self.write_cap
def is_leaf_subtree(self):
return True

View File

@ -23,6 +23,27 @@ class INode(Interface):
provides that same make_node_from_serialized function to create any
internal child nodes that might be necessary."""
def is_leaf_subtree():
"""Return True if this node does not refer to a traversable
subtree. When searching for the node that describes a path, the
search will stop at the first leaf node found. IFileNodes should
return True here.
"""
# TODO: there is a slightly confusing mixture of IDirectoryNodes and all
# other kinds of nodes. It is convenient to mix them because that way list()
# can point at nodes of all sorts, but IDirectoryNodes are very different
# than the rest (because they to not represent distinct subtrees). There
# might be a better way to factor this.
# TODO: 'node' is a problematic term here. It refers to nodes in the graph of
# connected subtrees. It also refers to nodes in the graph of directories and
# links within a single subtree. And the interface named INode is
# unfortunately a homonym with "inode", the data structure we previously used
# to represent information about an uploaded file which was too large to keep
# locally (the list of blockids), which meant the inode itself was uploaded.
# We no longer use inodes, but using a word that sounds just like it may
# cause confusion.
class IFileNode(Interface):
"""This is a file which can be retrieved."""
# TODO: not sure which of these to provide.. should URIs contain "CHK" or

View File

@ -19,6 +19,9 @@ class LocalFileRedirectionNode(BaseDataNode):
def set_base_data(self, data):
self.handle = data
def is_leaf_subtree(self):
return False
class _BaseRedirection(object):
implements(ISubTree)
@ -231,6 +234,9 @@ class HTTPRedirectionNode(BaseDataNode):
def set_base_data(self, data):
self.url = data
def is_leaf_subtree(self):
return False
class HTTPRedirection(_BaseRedirection):
node_class = HTTPRedirectionNode

View File

@ -106,7 +106,7 @@ class VirtualDrive(object):
def _get_closest_node_1(self, subtree, path):
(found_path, node, remaining_path) = subtree.get_node_for_path(path)
parent_is_mutable = subtree.is_mutable()
if IDirectoryNode.providedBy(node):
if IDirectoryNode.providedBy(node) or node.is_leaf_subtree():
# traversal done
return (node, remaining_path)
# otherwise, we must open and recurse into a new subtree

View File

@ -469,8 +469,8 @@ class Stuff(unittest.TestCase):
{"c": child2, "d": child3})
d.addCallback(_listed4)
#d.addCallback(lambda res: v._get_file_uri(["b","c"]))
#d.addCallback(self.failUnlessEqual, "uri2")
d.addCallback(lambda res: v._get_file_uri(["b","c"]))
d.addCallback(self.failUnlessEqual, "uri2")
d.addCallback(lambda res: v.list(["bogus"]))
def _listed_bogus(res):