mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-12 07:52:38 +00:00
dirnode: update to use MutableFileNode.modify
This commit is contained in:
parent
b6b3b6b1bd
commit
1bff08a7df
@ -38,6 +38,71 @@ def split_netstring(data, numstrings, allow_leftover=False):
|
|||||||
raise ValueError("leftover data in netstrings")
|
raise ValueError("leftover data in netstrings")
|
||||||
return tuple(elements)
|
return tuple(elements)
|
||||||
|
|
||||||
|
class Deleter:
|
||||||
|
def __init__(self, node, name):
|
||||||
|
self.node = node
|
||||||
|
self.name = name
|
||||||
|
def modify(self, old_contents):
|
||||||
|
children = self.node._unpack_contents(old_contents)
|
||||||
|
if self.name not in children:
|
||||||
|
self.old_child = None
|
||||||
|
return None
|
||||||
|
self.old_child, metadata = children[self.name]
|
||||||
|
del children[self.name]
|
||||||
|
new_contents = self.node._pack_contents(children)
|
||||||
|
return new_contents
|
||||||
|
|
||||||
|
class MetadataSetter:
|
||||||
|
def __init__(self, node, name, metadata):
|
||||||
|
self.node = node
|
||||||
|
self.name = name
|
||||||
|
self.metadata = metadata
|
||||||
|
|
||||||
|
def modify(self, old_contents):
|
||||||
|
children = self.node._unpack_contents(old_contents)
|
||||||
|
children[self.name] = (children[self.name][0], self.metadata)
|
||||||
|
new_contents = self.node._pack_contents(children)
|
||||||
|
return new_contents
|
||||||
|
|
||||||
|
|
||||||
|
class Adder:
|
||||||
|
def __init__(self, node, entries=None):
|
||||||
|
self.node = node
|
||||||
|
if entries is None:
|
||||||
|
entries = []
|
||||||
|
self.entries = entries
|
||||||
|
|
||||||
|
def set_node(self, name, node, metadata):
|
||||||
|
self.entries.append( [name, node, metadata] )
|
||||||
|
|
||||||
|
def modify(self, old_contents):
|
||||||
|
children = self.node._unpack_contents(old_contents)
|
||||||
|
now = time.time()
|
||||||
|
for e in self.entries:
|
||||||
|
if len(e) == 2:
|
||||||
|
name, child = e
|
||||||
|
new_metadata = None
|
||||||
|
else:
|
||||||
|
assert len(e) == 3
|
||||||
|
name, child, new_metadata = e
|
||||||
|
assert isinstance(name, unicode)
|
||||||
|
if name in children:
|
||||||
|
metadata = children[name][1].copy()
|
||||||
|
else:
|
||||||
|
metadata = {"ctime": now,
|
||||||
|
"mtime": now}
|
||||||
|
if new_metadata is None:
|
||||||
|
# update timestamps
|
||||||
|
if "ctime" not in metadata:
|
||||||
|
metadata["ctime"] = now
|
||||||
|
metadata["mtime"] = now
|
||||||
|
else:
|
||||||
|
# just replace it
|
||||||
|
metadata = new_metadata.copy()
|
||||||
|
children[name] = (child, metadata)
|
||||||
|
new_contents = self.node._pack_contents(children)
|
||||||
|
return new_contents
|
||||||
|
|
||||||
class NewDirectoryNode:
|
class NewDirectoryNode:
|
||||||
implements(IDirectoryNode)
|
implements(IDirectoryNode)
|
||||||
filenode_class = MutableFileNode
|
filenode_class = MutableFileNode
|
||||||
@ -199,12 +264,8 @@ class NewDirectoryNode:
|
|||||||
if self.is_readonly():
|
if self.is_readonly():
|
||||||
return defer.fail(NotMutableError())
|
return defer.fail(NotMutableError())
|
||||||
assert isinstance(metadata, dict)
|
assert isinstance(metadata, dict)
|
||||||
d = self._read()
|
s = MetadataSetter(self, name, metadata)
|
||||||
def _update(children):
|
d = self._node.modify(s.modify)
|
||||||
children[name] = (children[name][0], metadata)
|
|
||||||
new_contents = self._pack_contents(children)
|
|
||||||
return self._node.overwrite(new_contents)
|
|
||||||
d.addCallback(_update)
|
|
||||||
d.addCallback(lambda res: self)
|
d.addCallback(lambda res: self)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -247,9 +308,14 @@ class NewDirectoryNode:
|
|||||||
If this directory node is read-only, the Deferred will errback with a
|
If this directory node is read-only, the Deferred will errback with a
|
||||||
NotMutableError."""
|
NotMutableError."""
|
||||||
assert isinstance(name, unicode)
|
assert isinstance(name, unicode)
|
||||||
return self.set_node(name, self._create_node(child_uri), metadata)
|
child_node = self._create_node(child_uri)
|
||||||
|
d = self.set_node(name, child_node, metadata)
|
||||||
|
d.addCallback(lambda res: child_node)
|
||||||
|
return d
|
||||||
|
|
||||||
def set_children(self, entries):
|
def set_children(self, entries):
|
||||||
|
# this takes URIs
|
||||||
|
a = Adder(self)
|
||||||
node_entries = []
|
node_entries = []
|
||||||
for e in entries:
|
for e in entries:
|
||||||
if len(e) == 2:
|
if len(e) == 2:
|
||||||
@ -259,8 +325,8 @@ class NewDirectoryNode:
|
|||||||
assert len(e) == 3
|
assert len(e) == 3
|
||||||
name, child_uri, metadata = e
|
name, child_uri, metadata = e
|
||||||
assert isinstance(name, unicode)
|
assert isinstance(name, unicode)
|
||||||
node_entries.append( (name,self._create_node(child_uri),metadata) )
|
a.set_node(name, self._create_node(child_uri), metadata)
|
||||||
return self.set_nodes(node_entries)
|
return self._node.modify(a.modify)
|
||||||
|
|
||||||
def set_node(self, name, child, metadata=None):
|
def set_node(self, name, child, metadata=None):
|
||||||
"""I add a child at the specific name. I return a Deferred that fires
|
"""I add a child at the specific name. I return a Deferred that fires
|
||||||
@ -270,43 +336,22 @@ class NewDirectoryNode:
|
|||||||
|
|
||||||
If this directory node is read-only, the Deferred will errback with a
|
If this directory node is read-only, the Deferred will errback with a
|
||||||
NotMutableError."""
|
NotMutableError."""
|
||||||
|
|
||||||
|
if self.is_readonly():
|
||||||
|
return defer.fail(NotMutableError())
|
||||||
assert isinstance(name, unicode)
|
assert isinstance(name, unicode)
|
||||||
assert IFilesystemNode.providedBy(child), child
|
assert IFilesystemNode.providedBy(child), child
|
||||||
d = self.set_nodes( [(name, child, metadata)])
|
a = Adder(self)
|
||||||
|
a.set_node(name, child, metadata)
|
||||||
|
d = self._node.modify(a.modify)
|
||||||
d.addCallback(lambda res: child)
|
d.addCallback(lambda res: child)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def set_nodes(self, entries):
|
def set_nodes(self, entries):
|
||||||
if self.is_readonly():
|
if self.is_readonly():
|
||||||
return defer.fail(NotMutableError())
|
return defer.fail(NotMutableError())
|
||||||
d = self._read()
|
a = Adder(self, entries)
|
||||||
def _add(children):
|
d = self._node.modify(a.modify)
|
||||||
now = time.time()
|
|
||||||
for e in entries:
|
|
||||||
if len(e) == 2:
|
|
||||||
name, child = e
|
|
||||||
new_metadata = None
|
|
||||||
else:
|
|
||||||
assert len(e) == 3
|
|
||||||
name, child, new_metadata = e
|
|
||||||
assert isinstance(name, unicode)
|
|
||||||
if name in children:
|
|
||||||
metadata = children[name][1].copy()
|
|
||||||
else:
|
|
||||||
metadata = {"ctime": now,
|
|
||||||
"mtime": now}
|
|
||||||
if new_metadata is None:
|
|
||||||
# update timestamps
|
|
||||||
if "ctime" not in metadata:
|
|
||||||
metadata["ctime"] = now
|
|
||||||
metadata["mtime"] = now
|
|
||||||
else:
|
|
||||||
# just replace it
|
|
||||||
metadata = new_metadata.copy()
|
|
||||||
children[name] = (child, metadata)
|
|
||||||
new_contents = self._pack_contents(children)
|
|
||||||
return self._node.overwrite(new_contents)
|
|
||||||
d.addCallback(_add)
|
|
||||||
d.addCallback(lambda res: None)
|
d.addCallback(lambda res: None)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -331,17 +376,9 @@ class NewDirectoryNode:
|
|||||||
assert isinstance(name, unicode)
|
assert isinstance(name, unicode)
|
||||||
if self.is_readonly():
|
if self.is_readonly():
|
||||||
return defer.fail(NotMutableError())
|
return defer.fail(NotMutableError())
|
||||||
d = self._read()
|
deleter = Deleter(self, name)
|
||||||
def _delete(children):
|
d = self._node.modify(deleter.modify)
|
||||||
old_child, metadata = children[name]
|
d.addCallback(lambda res: deleter.old_child)
|
||||||
del children[name]
|
|
||||||
new_contents = self._pack_contents(children)
|
|
||||||
d = self._node.overwrite(new_contents)
|
|
||||||
def _done(res):
|
|
||||||
return old_child
|
|
||||||
d.addCallback(_done)
|
|
||||||
return d
|
|
||||||
d.addCallback(_delete)
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def create_empty_directory(self, name):
|
def create_empty_directory(self, name):
|
||||||
@ -353,7 +390,9 @@ class NewDirectoryNode:
|
|||||||
return defer.fail(NotMutableError())
|
return defer.fail(NotMutableError())
|
||||||
d = self._client.create_empty_dirnode()
|
d = self._client.create_empty_dirnode()
|
||||||
def _created(child):
|
def _created(child):
|
||||||
d = self.set_node(name, child)
|
entries = [(name, child, None)]
|
||||||
|
a = Adder(self, entries)
|
||||||
|
d = self._node.modify(a.modify)
|
||||||
d.addCallback(lambda res: child)
|
d.addCallback(lambda res: child)
|
||||||
return d
|
return d
|
||||||
d.addCallback(_created)
|
d.addCallback(_created)
|
||||||
|
@ -101,6 +101,11 @@ class FakeMutableFileNode:
|
|||||||
assert not self.is_readonly()
|
assert not self.is_readonly()
|
||||||
self.all_contents[self.storage_index] = new_contents
|
self.all_contents[self.storage_index] = new_contents
|
||||||
return defer.succeed(None)
|
return defer.succeed(None)
|
||||||
|
def modify(self, modifier):
|
||||||
|
assert not self.is_readonly()
|
||||||
|
old_contents = self.all_contents[self.storage_index]
|
||||||
|
self.all_contents[self.storage_index] = modifier(old_contents)
|
||||||
|
return defer.succeed(None)
|
||||||
|
|
||||||
|
|
||||||
def make_mutable_file_uri():
|
def make_mutable_file_uri():
|
||||||
|
Loading…
Reference in New Issue
Block a user