self._uri = wrap_dirnode_cap(filenode_cap)
self._nodemaker = nodemaker
self._uploader = uploader
- self._most_recent_size = None
def __repr__(self):
return "<%s %s-%s %s>" % (self.__class__.__name__,
hasattr(self, '_uri') and self._uri.abbrev())
def get_size(self):
- # return the size of our backing mutable file, in bytes, if we've
- # fetched it.
- if not self._node.is_mutable():
- # TODO?: consider using IMutableFileNode.providedBy(self._node)
- return self._node.get_size()
- return self._most_recent_size
+ """Return the size of our backing mutable file, in bytes, if we've
+ fetched it. Otherwise return None. This returns synchronously."""
+ return self._node.get_size()
- def _set_size(self, data):
- self._most_recent_size = len(data)
- return data
+ def get_current_size(self):
+ """Calculate the size of our backing mutable file, in bytes. Returns
+ a Deferred that fires with the result."""
+ return self._node.get_current_size()
def _read(self):
if self._node.is_mutable():
# use the IMutableFileNode API.
d = self._node.download_best_version()
- d.addCallback(self._set_size)
else:
d = self._node.download_to_data()
d.addCallback(self._unpack_contents)
def enter_directory(self, parent, children):
dirsize_bytes = parent.get_size()
+ if dirsize_bytes is not None:
+ self.add("size-directories", dirsize_bytes)
+ self.max("largest-directory", dirsize_bytes)
dirsize_children = len(children)
- self.add("size-directories", dirsize_bytes)
- self.max("largest-directory", dirsize_bytes)
self.max("largest-directory-children", dirsize_children)
def add(self, key, value=1):
def get_size(self):
return self.u.get_size()
+ def get_current_size(self):
+ return defer.succeed(self.get_size())
def get_cap(self):
return self.u
def get_size(self):
return len(self.u.data)
+ def get_current_size(self):
+ return defer.succeed(self.get_size())
def get_cap(self):
return self.u
file.
"""
+ def get_size():
+ """Return the length (in bytes) of the data this node represents. For
+ directory nodes, I return the size of the backing store. I return
+ synchronously and do not consult the network, so for mutable objects,
+ I will return the most recently observed size for the object, or None
+ if I don't remember a size. Use get_current_size, which returns a
+ Deferred, if you want more up-to-date information."""
+
+ def get_current_size():
+ """I return a Deferred that fires with the length (in bytes) of the
+ data this node represents.
+ """
+
class IMutableFilesystemNode(IFilesystemNode):
pass
"""Download the file's contents. Return a Deferred that fires
with those contents."""
- def get_size():
- """Return the length (in bytes) of the data this node represents."""
-
def read(consumer, offset=0, size=None):
"""Download a portion (possibly all) of the file's contents, making
them available to the given IConsumer. Return a Deferred that fires
self._total_shares = default_encoding_parameters["n"]
self._sharemap = {} # known shares, shnum-to-[nodeids]
self._cache = ResponseCache()
+ self._most_recent_size = None
# all users of this MutableFileNode go through the serializer. This
# takes advantage of the fact that Deferreds discard the callbacks
# IFilesystemNode
def get_size(self):
- return "?" # TODO: this is likely to cause problems, not being an int
+ return self._most_recent_size
+ def get_current_size(self):
+ d = self.get_size_of_best_version()
+ d.addCallback(self._stash_size)
+ return d
+ def _stash_size(self, size):
+ self._most_recent_size = size
+ return size
def get_cap(self):
return self._uri
r = Retrieve(self, servermap, version, fetch_privkey)
if self._history:
self._history.notify_retrieve(r.get_status())
- return r.download()
+ d = r.download()
+ d.addCallback(self._downloaded_version)
+ return d
+ def _downloaded_version(self, data):
+ self._most_recent_size = len(data)
+ return data
def upload(self, new_contents, servermap):
return self._do_serialized(self._upload, new_contents, servermap)
p = Publish(self, self._storage_broker, servermap)
if self._history:
self._history.notify_publish(p.get_status(), len(new_contents))
- return p.publish(new_contents)
+ d = p.publish(new_contents)
+ d.addCallback(self._did_upload, len(new_contents))
+ return d
+ def _did_upload(self, res, size):
+ self._most_recent_size = size
+ return res
def get_writekey(self):
return "\x00"*16
def get_size(self):
- return "?" # TODO: see mutable.MutableFileNode.get_size
+ return len(self.all_contents[self.storage_index])
+ def get_current_size(self):
+ return self.get_size_of_best_version()
def get_size_of_best_version(self):
return defer.succeed(len(self.all_contents[self.storage_index]))
return None
def get_repair_cap(self):
return None
+ def get_size(self):
+ return None
+ def get_current_size(self):
+ return defer.succeed(None)
def check(self, monitor, verify, add_lease):
return defer.succeed(None)
def check_and_repair(self, monitor, verify, add_lease):
def render_size(self, ctx, data):
node = self.original
si = node.get_storage_index()
- if IDirectoryNode.providedBy(node):
- d = node._node.get_size_of_best_version()
- elif IFileNode.providedBy(node):
- if node.is_mutable():
- d = node.get_size_of_best_version()
- else:
- # for immutable files and LIT files, we get the size from the
- # URI
- d = defer.succeed(node.get_size())
- else:
- d = defer.succeed("?")
+ d = node.get_current_size()
+ def _no_size(size):
+ if size is None:
+ return "?"
+ return size
+ d.addCallback(_no_size)
def _handle_unrecoverable(f):
f.trap(UnrecoverableFileError)
return "?"