[tor-commits] [stem/master] Caching hash values

atagar at torproject.org atagar at torproject.org
Mon Oct 14 00:42:16 UTC 2013


commit efe5fbdd56b28b3f76de144e71901c0c75ebe5ac
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Oct 12 20:14:59 2013 -0700

    Caching hash values
    
    Well, even if we can't use @lru_cache we can still do it the old fashioned way. :P
---
 stem/exit_policy.py |   40 ++++++++++++++++++++++++----------------
 stem/version.py     |   18 +++++++++++-------
 2 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 9c60bda..163f58b 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -502,6 +502,7 @@ class ExitPolicyRule(object):
     self._address_type = None
     self._masked_bits = None
     self.min_port = self.max_port = None
+    self._hash = None
 
     # Our mask in ip notation (ex. "255.255.255.0"). This is only set if we
     # either have a custom mask that can't be represented by a number of bits,
@@ -697,20 +698,23 @@ class ExitPolicyRule(object):
     return label
 
   def __hash__(self):
-    my_hash = 0
+    if self._hash is None:
+      my_hash = 0
 
-    for attr in ("is_accept", "address", "min_port", "max_port"):
-      my_hash *= 1024
+      for attr in ("is_accept", "address", "min_port", "max_port"):
+        my_hash *= 1024
+
+        attr_value = getattr(self, attr)
 
-      attr_value = getattr(self, attr)
+        if attr_value is not None:
+          my_hash += hash(attr_value)
 
-      if attr_value is not None:
-        my_hash += hash(attr_value)
+      my_hash *= 1024
+      my_hash += hash(self.get_mask(False))
 
-    my_hash *= 1024
-    my_hash += hash(self.get_mask(False))
+      self._hash = my_hash
 
-    return my_hash
+    return self._hash
 
   @lru_cache()
   def _get_mask_bin(self):
@@ -845,6 +849,7 @@ class MicroExitPolicyRule(ExitPolicyRule):
     self.address = None  # wildcard address
     self.min_port = min_port
     self.max_port = max_port
+    self._hash = None
 
   def is_address_wildcard(self):
     return True
@@ -859,14 +864,17 @@ class MicroExitPolicyRule(ExitPolicyRule):
     return None
 
   def __hash__(self):
-    my_hash = 0
+    if self._hash is None:
+      my_hash = 0
 
-    for attr in ("is_accept", "min_port", "max_port"):
-      my_hash *= 1024
+      for attr in ("is_accept", "min_port", "max_port"):
+        my_hash *= 1024
+
+        attr_value = getattr(self, attr)
 
-      attr_value = getattr(self, attr)
+        if attr_value is not None:
+          my_hash += hash(attr_value)
 
-      if attr_value is not None:
-        my_hash += hash(attr_value)
+      self._hash = my_hash
 
-    return my_hash
+    return self._hash
diff --git a/stem/version.py b/stem/version.py
index c87d325..44f1d02 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -150,6 +150,7 @@ class Version(object):
   def __init__(self, version_str):
     self.version_str = version_str
     version_parts = re.match(r'^([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]+)?(-\S*)?( \(\S*\))?$', version_str)
+    self._hash = None
 
     if version_parts:
       major, minor, micro, patch, status, extra = version_parts.groups()
@@ -248,17 +249,20 @@ class Version(object):
     return self._compare(other, lambda s, o: s >= o)
 
   def __hash__(self):
-    my_hash = 0
+    if self._hash is None:
+      my_hash = 0
 
-    for attr in ("major", "minor", "micro", "patch", "status"):
-      my_hash *= 1024
+      for attr in ("major", "minor", "micro", "patch", "status"):
+        my_hash *= 1024
 
-      attr_value = getattr(self, attr)
+        attr_value = getattr(self, attr)
 
-      if attr_value is not None:
-        my_hash += hash(attr_value)
+        if attr_value is not None:
+          my_hash += hash(attr_value)
 
-    return my_hash
+      self._hash = my_hash
+
+    return self._hash
 
 
 class _VersionRequirements(object):





More information about the tor-commits mailing list