tahoe-lafs/src/allmydata/nodemaker.py
Brian Warner 131e05b155 clean up uri-vs-cap terminology, emphasize cap instances instead of URI strings
* "cap" means a python instance which encapsulates a filecap/dircap (uri.py)
 * "uri" means a string with a "URI:" prefix
 * FileNode instances are created with (and retain) a cap instance, and
   generate uri strings on demand
 * .get_cap/get_readcap/get_verifycap/get_repaircap return cap instances
 * .get_uri/get_readonly_uri return uri strings

* add filenode.download_to_filename() for control.py, should find a better way
* use MutableFileNode.init_from_cap, not .init_from_uri
* directory URI instances: use get_filenode_cap, not get_filenode_uri
* update/cleanup bench_dirnode.py to match, add Makefile target to run it
2009-11-11 14:26:19 -08:00

95 lines
4.2 KiB
Python

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, pack_children
from allmydata.unknown import UnknownNode
from allmydata import uri
class NodeMaker:
implements(INodeMaker)
def __init__(self, storage_broker, secret_holder, history,
uploader, downloader, download_cache_dirman,
default_encoding_parameters, key_generator):
self.storage_broker = storage_broker
self.secret_holder = secret_holder
self.history = history
self.uploader = uploader
self.downloader = downloader
self.download_cache_dirman = download_cache_dirman
self.default_encoding_parameters = default_encoding_parameters
self.key_generator = key_generator
self._node_cache = weakref.WeakValueDictionary() # uri -> node
def _create_lit(self, cap):
return LiteralFileNode(cap)
def _create_immutable(self, cap):
return FileNode(cap, self.storage_broker, self.secret_holder,
self.downloader, self.history,
self.download_cache_dirman)
def _create_mutable(self, cap):
n = MutableFileNode(self.storage_broker, self.secret_holder,
self.default_encoding_parameters,
self.history)
return n.init_from_cap(cap)
def _create_dirnode(self, filenode):
return DirectoryNode(filenode, self, self.uploader)
def create_from_cap(self, writecap, readcap=None):
# this returns synchronously. It starts with a "cap string".
assert isinstance(writecap, (str, type(None))), type(writecap)
assert isinstance(readcap, (str, type(None))), type(readcap)
bigcap = writecap or readcap
if not bigcap:
# maybe the writecap was hidden because we're in a readonly
# directory, and the future cap format doesn't have a readcap, or
# something.
return UnknownNode(writecap, readcap)
if bigcap in self._node_cache:
return self._node_cache[bigcap]
cap = uri.from_string(bigcap)
node = self._create_from_cap(cap)
if node:
self._node_cache[bigcap] = node # note: WeakValueDictionary
else:
node = UnknownNode(writecap, readcap) # don't cache UnknownNode
return node
def _create_from_cap(self, cap):
# This starts with a "cap instance"
if isinstance(cap, uri.LiteralFileURI):
return self._create_lit(cap)
if isinstance(cap, uri.CHKFileURI):
return self._create_immutable(cap)
if isinstance(cap, (uri.ReadonlySSKFileURI, uri.WriteableSSKFileURI)):
return self._create_mutable(cap)
if isinstance(cap, (uri.ReadonlyDirectoryURI, uri.DirectoryURI)):
filenode = self._create_from_cap(cap.get_filenode_cap())
return self._create_dirnode(filenode)
return None
def create_mutable_file(self, contents=None, keysize=None):
n = MutableFileNode(self.storage_broker, self.secret_holder,
self.default_encoding_parameters, self.history)
d = self.key_generator.generate(keysize)
d.addCallback(n.create_with_keys, contents)
d.addCallback(lambda res: n)
return d
def create_new_mutable_directory(self, initial_children={}):
# 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)
return d