From d43baa2ad7008cad79815676f059303789d12737 Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@allmydata.com>
Date: Tue, 12 Aug 2008 19:02:52 -0700
Subject: [PATCH] mutable: add get_size_of_best_version to the interface, to
 simplify the web HEAD code, and tests

---
 src/allmydata/interfaces.py        |  7 +++++++
 src/allmydata/mutable/node.py      | 10 ++++++++++
 src/allmydata/test/common.py       |  2 ++
 src/allmydata/test/test_mutable.py |  3 +++
 4 files changed, 22 insertions(+)

diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py
index 19f4b126..5900537a 100644
--- a/src/allmydata/interfaces.py
+++ b/src/allmydata/interfaces.py
@@ -539,6 +539,13 @@ class IMutableFileNode(IFileNode, IMutableFilesystemNode):
         UnrecoverableFileError.
         """
 
+    def get_size_of_best_version():
+        """Find the size of the version that would be downloaded with
+        download_best_version(), without actually downloading the whole file.
+
+        I return a Deferred that fires with an integer.
+        """
+
     def overwrite(new_contents):
         """Unconditionally replace the contents of the mutable file with new
         ones. This simply chains get_servermap(MODE_WRITE) and upload(). This
diff --git a/src/allmydata/mutable/node.py b/src/allmydata/mutable/node.py
index e850c675..cf95ec55 100644
--- a/src/allmydata/mutable/node.py
+++ b/src/allmydata/mutable/node.py
@@ -310,6 +310,16 @@ class MutableFileNode:
             raise UnrecoverableFileError("no recoverable versions")
         return self._try_once_to_download_version(servermap, goal)
 
+    def get_size_of_best_version(self):
+        d = self.get_servermap(MODE_READ)
+        def _got_servermap(smap):
+            ver = smap.best_recoverable_version()
+            if not ver:
+                raise UnrecoverableFileError("no recoverable version")
+            return smap.size_of_version(ver)
+        d.addCallback(_got_servermap)
+        return d
+
     def overwrite(self, new_contents):
         return self._do_serialized(self._overwrite, new_contents)
     def _overwrite(self, new_contents):
diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py
index fc3a32a9..e3af2eee 100644
--- a/src/allmydata/test/common.py
+++ b/src/allmydata/test/common.py
@@ -130,6 +130,8 @@ class FakeMutableFileNode:
         return "\x00"*16
     def get_size(self):
         return "?" # TODO: see mutable.MutableFileNode.get_size
+    def get_size_of_best_version(self):
+        return defer.succeed(len(self.all_contents[self.storage_index]))
 
     def get_storage_index(self):
         return self.storage_index
diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py
index ca78bbb2..3b05a866 100644
--- a/src/allmydata/test/test_mutable.py
+++ b/src/allmydata/test/test_mutable.py
@@ -306,6 +306,9 @@ class Filenode(unittest.TestCase, testutil.ShouldFailMixin):
             d.addCallback(lambda res: self.failUnlessIdentical(res, None))
             d.addCallback(lambda res: n.download_best_version())
             d.addCallback(lambda res: self.failUnlessEqual(res, "contents 1"))
+            d.addCallback(lambda res: n.get_size_of_best_version())
+            d.addCallback(lambda size:
+                          self.failUnlessEqual(size, len("contents 1")))
             d.addCallback(lambda res: n.overwrite("contents 2"))
             d.addCallback(lambda res: n.download_best_version())
             d.addCallback(lambda res: self.failUnlessEqual(res, "contents 2"))
-- 
2.45.2