mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-24 23:26:43 +00:00
nodemaker.create_new_mutable_directory: pack_children() in initial_contents=
instead of creating an empty file and then adding the children later. This should speed up mkdir(initial_children) considerably, removing two roundtrips and an entire read-modify-write cycle, probably bringing it down to a single roundtrip. A quick test (against the volunteergrid) suggests a 30% speedup. test_dirnode: add new tests to enforce the restrictions that interfaces.py claims for create_new_mutable_directory(): no UnknownNodes, metadata dicts
This commit is contained in:
parent
59ee02e82f
commit
1273b5c233
@ -1,9 +1,10 @@
|
||||
import weakref
|
||||
from zope.interface import implements
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.interfaces import INodeMaker
|
||||
from allmydata.immutable.filenode import FileNode, LiteralFileNode
|
||||
from allmydata.mutable.filenode import MutableFileNode
|
||||
from allmydata.dirnode import DirectoryNode
|
||||
from allmydata.dirnode import DirectoryNode, pack_children
|
||||
from allmydata.unknown import UnknownNode
|
||||
from allmydata.uri import DirectoryURI, ReadonlyDirectoryURI
|
||||
|
||||
@ -79,8 +80,14 @@ class NodeMaker:
|
||||
return d
|
||||
|
||||
def create_new_mutable_directory(self, initial_children={}):
|
||||
d = self.create_mutable_file()
|
||||
# initial_children must have metadata (i.e. {} instead of None), and
|
||||
# should not contain UnknownNodes
|
||||
for (name, (node, metadata)) in initial_children.iteritems():
|
||||
precondition(not isinstance(node, UnknownNode),
|
||||
"create_new_mutable_directory does not accept UnknownNode", node)
|
||||
precondition(isinstance(metadata, dict),
|
||||
"create_new_mutable_directory requires metadata to be a dict, not None", metadata)
|
||||
d = self.create_mutable_file(lambda n:
|
||||
pack_children(n, initial_children))
|
||||
d.addCallback(self._create_dirnode)
|
||||
if initial_children:
|
||||
d.addCallback(lambda n: n.set_nodes(initial_children))
|
||||
return d
|
||||
|
@ -40,10 +40,11 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
self.basedir = "dirnode/Dirnode/test_initial_children"
|
||||
self.set_up_grid()
|
||||
c = self.g.clients[0]
|
||||
nm = c.nodemaker
|
||||
setup_py_uri = "URI:CHK:n7r3m6wmomelk4sep3kw5cvduq:os7ijw5c3maek7pg65e5254k2fzjflavtpejjyhshpsxuqzhcwwq:3:20:14861"
|
||||
one_uri = "URI:LIT:n5xgk" # LIT for "one"
|
||||
kids = {u"one": (c.nodemaker.create_from_cap(one_uri), {}),
|
||||
u"two": (c.nodemaker.create_from_cap(setup_py_uri),
|
||||
kids = {u"one": (nm.create_from_cap(one_uri), {}),
|
||||
u"two": (nm.create_from_cap(setup_py_uri),
|
||||
{"metakey": "metavalue"}),
|
||||
}
|
||||
d = c.create_dirnode(kids)
|
||||
@ -62,10 +63,24 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
self.failUnless(isinstance(one_metadata, dict), one_metadata)
|
||||
self.failUnlessEqual(two_metadata["metakey"], "metavalue")
|
||||
d.addCallback(_check_kids)
|
||||
d.addCallback(lambda ign:
|
||||
c.nodemaker.create_new_mutable_directory(kids))
|
||||
d.addCallback(lambda ign: nm.create_new_mutable_directory(kids))
|
||||
d.addCallback(lambda dn: dn.list())
|
||||
d.addCallback(_check_kids)
|
||||
future_writecap = "x-tahoe-crazy://I_am_from_the_future."
|
||||
future_readcap = "x-tahoe-crazy-readonly://I_am_from_the_future."
|
||||
future_node = UnknownNode(future_writecap, future_readcap)
|
||||
bad_kids1 = {u"one": (future_node, {})}
|
||||
d.addCallback(lambda ign:
|
||||
self.shouldFail(AssertionError, "bad_kids1",
|
||||
"does not accept UnknownNode",
|
||||
nm.create_new_mutable_directory,
|
||||
bad_kids1))
|
||||
bad_kids2 = {u"one": (nm.create_from_cap(one_uri), None)}
|
||||
d.addCallback(lambda ign:
|
||||
self.shouldFail(AssertionError, "bad_kids2",
|
||||
"requires metadata to be a dict",
|
||||
nm.create_new_mutable_directory,
|
||||
bad_kids2))
|
||||
return d
|
||||
|
||||
def test_check(self):
|
||||
@ -726,7 +741,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
fake_file_uri = make_mutable_file_uri()
|
||||
other_file_uri = make_mutable_file_uri()
|
||||
md = {"metakey": "metavalue"}
|
||||
kids = {u"kid1": (nm.create_from_cap(fake_file_uri), None),
|
||||
kids = {u"kid1": (nm.create_from_cap(fake_file_uri), {}),
|
||||
u"kid2": (nm.create_from_cap(other_file_uri), md),
|
||||
}
|
||||
d = n.create_subdirectory(u"subdir", kids)
|
||||
@ -811,12 +826,22 @@ class Packing(unittest.TestCase):
|
||||
class FakeMutableFile:
|
||||
counter = 0
|
||||
def __init__(self, initial_contents=""):
|
||||
self.data = initial_contents
|
||||
self.data = self._get_initial_contents(initial_contents)
|
||||
counter = FakeMutableFile.counter
|
||||
FakeMutableFile.counter += 1
|
||||
writekey = hashutil.ssk_writekey_hash(str(counter))
|
||||
fingerprint = hashutil.ssk_pubkey_fingerprint_hash(str(counter))
|
||||
self.uri = uri.WriteableSSKFileURI(writekey, fingerprint)
|
||||
|
||||
def _get_initial_contents(self, contents):
|
||||
if isinstance(contents, str):
|
||||
return contents
|
||||
if contents is None:
|
||||
return ""
|
||||
assert callable(contents), "%s should be callable, not %s" % \
|
||||
(contents, type(contents))
|
||||
return contents(self)
|
||||
|
||||
def get_uri(self):
|
||||
return self.uri.to_string()
|
||||
def download_best_version(self):
|
||||
|
Loading…
Reference in New Issue
Block a user