]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
filetree: mark leaf nodes by adding is_leaf_subtree(), stop traversing when we hit...
authorBrian Warner <warner@lothar.com>
Sun, 21 Jan 2007 20:31:16 +0000 (13:31 -0700)
committerBrian Warner <warner@lothar.com>
Sun, 21 Jan 2007 20:31:16 +0000 (13:31 -0700)
src/allmydata/filetree/directory.py
src/allmydata/filetree/file.py
src/allmydata/filetree/interfaces.py
src/allmydata/filetree/redirect.py
src/allmydata/filetree/vdrive.py
src/allmydata/test/test_filetree_new.py

index 91613e6e205081cca5b67fd545f257e87831afbb..93a3f2915222e2b1455cc0149441dcdd4469c295 100644 (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
index e08f2f9a58bf9edfaf440e67dde85ace901be2cc..8dced32ba49efbef6c04f302dcd9ab17f0183e85 100644 (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
+
index 665d1b63138c6ae912440f4f101fd5e1d5dd7936..e39cd5c861fe715e9c9e9cc7f57bb1bab049616c 100644 (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
index bfd540163bf7b99e0de5660dbe5a93586ff7f6ff..3e2f108663469f6d500f2b1ef78cefa168704b14 100644 (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
 
index 8a44f3436376e23a06c806d9fa8450ab822fe9f6..473257ca5ee47cdd8cfe55f980de8ffc808fd3fc 100644 (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
index 2f1eccb3bde3023cea04b0fd25936ed20d801f03..3d23f843386c88e8d892ac8da4ce514e15b01052 100644 (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):