From fa302544fa65894e0e196d2901c9bd90103d8003 Mon Sep 17 00:00:00 2001
From: Zooko O'Whielacronx <zooko@zooko.com>
Date: Tue, 23 Sep 2008 11:52:49 -0700
Subject: [PATCH] immutable: refactor immutable filenodes and comparison
 thereof * the two kinds of immutable filenode now have a common base class *
 they store only an instance of their URI, not both an instance and a string *
 they delegate comparison to that instance

---
 src/allmydata/immutable/filenode.py | 82 ++++++++++++-----------------
 src/allmydata/uri.py                | 18 ++++---
 2 files changed, 45 insertions(+), 55 deletions(-)

diff --git a/src/allmydata/immutable/filenode.py b/src/allmydata/immutable/filenode.py
index 810e5e3f..da05e07d 100644
--- a/src/allmydata/immutable/filenode.py
+++ b/src/allmydata/immutable/filenode.py
@@ -6,19 +6,17 @@ from allmydata import uri
 from allmydata.immutable.checker import SimpleCHKFileChecker, \
      SimpleCHKFileVerifier
 
-class FileNode:
+class ImmutableFileNode(object):
     implements(IFileNode, ICheckable)
     checker_class = SimpleCHKFileChecker
     verifier_class = SimpleCHKFileVerifier
 
     def __init__(self, uri, client):
-        u = IFileURI(uri)
-        self.u = u
-        self.uri = u.to_string()
+        self.u = IFileURI(uri)
         self._client = client
 
-    def get_uri(self):
-        return self.uri
+    def get_readonly_uri(self):
+        return self.get_uri()
 
     def is_mutable(self):
         return False
@@ -26,21 +24,31 @@ class FileNode:
     def is_readonly(self):
         return True
 
-    def get_readonly_uri(self):
-        return self.uri
+    def __hash__(self):
+        return self.u.__hash__()
+    def __eq__(self, other):
+        if IFileNode.providedBy(other):
+            return self.u.__eq__(other.u)
+        else:
+            return False
+    def __ne__(self, other):
+        if IFileNode.providedBy(other):
+            return self.u.__eq__(other.u)
+        else:
+            return True
+
+class FileNode(ImmutableFileNode):
+    checker_class = SimpleCHKFileChecker
+
+    def __init__(self, uri, client):
+        ImmutableFileNode.__init__(self, uri, client)
+
+    def get_uri(self):
+        return self.u.to_string()
 
     def get_size(self):
         return self.u.get_size()
 
-    def __hash__(self):
-        return hash((self.__class__, self.uri))
-    def __cmp__(self, them):
-        if cmp(type(self), type(them)):
-            return cmp(type(self), type(them))
-        if cmp(self.__class__, them.__class__):
-            return cmp(self.__class__, them.__class__)
-        return cmp(self.uri, them.uri)
-
     def get_verifier(self):
         return self.u.get_verifier()
 
@@ -75,46 +83,24 @@ class FileNode:
 
     def download(self, target):
         downloader = self._client.getServiceNamed("downloader")
-        return downloader.download(self.uri, target)
+        return downloader.download(self.get_uri(), target)
 
     def download_to_data(self):
         downloader = self._client.getServiceNamed("downloader")
-        return downloader.download_to_data(self.uri)
+        return downloader.download_to_data(self.get_uri())
 
 
 
-class LiteralFileNode:
-    implements(IFileNode, ICheckable)
+class LiteralFileNode(ImmutableFileNode):
 
-    def __init__(self, my_uri, client):
-        u = IFileURI(my_uri)
-        assert isinstance(u, uri.LiteralFileURI)
-        self.uri = u.to_string()
-        self._client = client
+    def __init__(self, uri, client):
+        ImmutableFileNode.__init__(self, uri, client)
 
     def get_uri(self):
-        return self.uri
-
-    def is_mutable(self):
-        return False
-
-    def is_readonly(self):
-        return True
-
-    def get_readonly_uri(self):
-        return self.uri
+        return self.u.to_string()
 
     def get_size(self):
-        return len(IURI(self.uri).data)
-
-    def __hash__(self):
-        return hash((self.__class__, self.uri))
-    def __cmp__(self, them):
-        if cmp(type(self), type(them)):
-            return cmp(type(self), type(them))
-        if cmp(self.__class__, them.__class__):
-            return cmp(self.__class__, them.__class__)
-        return cmp(self.uri, them.uri)
+        return len(self.u.data)
 
     def get_verifier(self):
         return None
@@ -132,12 +118,12 @@ class LiteralFileNode:
 
     def download(self, target):
         # note that this does not update the stats_provider
-        data = IURI(self.uri).data
+        data = self.u.data
         target.open(len(data))
         target.write(data)
         target.close()
         return defer.maybeDeferred(target.finish)
 
     def download_to_data(self):
-        data = IURI(self.uri).data
+        data = self.u.data
         return defer.succeed(data)
diff --git a/src/allmydata/uri.py b/src/allmydata/uri.py
index e3e14a39..c917ed38 100644
--- a/src/allmydata/uri.py
+++ b/src/allmydata/uri.py
@@ -24,13 +24,17 @@ OPTIONALHTTPLEAD=r'(?:https?://(?:127.0.0.1|localhost):8123/uri/)?'
 
 class _BaseURI:
     def __hash__(self):
-        return hash((self.__class__, self.to_string()))
-    def __cmp__(self, them):
-        if cmp(type(self), type(them)):
-            return cmp(type(self), type(them))
-        if cmp(self.__class__, them.__class__):
-            return cmp(self.__class__, them.__class__)
-        return cmp(self.to_string(), them.to_string())
+        return self.to_string().__hash__()
+    def __eq__(self, them):
+        if isinstance(them, _BaseURI):
+            return self.to_string() == them.to_string()
+        else:
+            return False
+    def __ne__(self, them):
+        if isinstance(them, _BaseURI):
+            return self.to_string() != them.to_string()
+        else:
+            return True
     def to_human_encoding(self):
         return 'http://127.0.0.1:8123/uri/'+self.to_string()
 
-- 
2.45.2