[pypy-svn] r39909 - in pypy/branch/rope-branch/pypy/objspace/std: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Mar 4 18:42:27 CET 2007


Author: cfbolz
Date: Sun Mar  4 18:42:24 2007
New Revision: 39909

Modified:
   pypy/branch/rope-branch/pypy/objspace/std/rope.py
   pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py
Log:
cache hashes, always making sure that the highest bit is set (so that 0 is
recognized as "not computed yet").


Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py
==============================================================================
--- pypy/branch/rope-branch/pypy/objspace/std/rope.py	(original)
+++ pypy/branch/rope-branch/pypy/objspace/std/rope.py	Sun Mar  4 18:42:24 2007
@@ -25,6 +25,7 @@
         i += 1
 
 class StringNode(object):
+    hash_cache = 0
     def length(self):
         return 0
 
@@ -80,10 +81,15 @@
         return self.s
 
     def hash_part(self):
-        x = 0
-        for c in self.s:
-            x = (1000003*x) + ord(c)
-        return intmask(x)
+        h = self.hash_cache
+        if not h:
+            x = 0
+            for c in self.s:
+                x = (1000003*x) + ord(c)
+            x = intmask(x)
+            x |= intmask(1L << (NBITS - 1))
+            h = self.hash_cache = x
+        return h
 
     def getitem(self, index):
         return self.s[index]
@@ -146,9 +152,14 @@
         return "".join([node.flatten() for node in f])
  
     def hash_part(self):
-        h1 = self.left.hash_part()
-        h2 = self.right.hash_part()
-        return intmask(h1 + h2 * (1000003 ** self.left.length()))
+        h = self.hash_cache
+        if not h:
+            h1 = self.left.hash_part()
+            h2 = self.right.hash_part()
+            x = intmask(h1 + h2 * (1000003 ** self.left.length()))
+            x |= intmask(1L << (NBITS - 1))
+            h = self.hash_cache = x
+        return h
 
     def rebalance(self):
         return rebalance([self], self.len)
@@ -190,10 +201,15 @@
         return self.node.flatten()[self.start: self.stop]
 
     def hash_part(self):
-        x = 0
-        for i in range(self.start, self.stop):
-            x = (1000003*x) + ord(self.node.getitem(i))
-        return intmask(x)
+        h = self.hash_cache
+        if not h:
+            x = 0
+            for i in range(self.start, self.stop):
+                x = (1000003*x) + ord(self.node.getitem(i))
+            x = intmask(x)
+            x |= intmask(1L << (NBITS - 1))
+            h = self.hash_cache = x
+        return h
 
     def dot(self, seen, toplevel=False):
         if self in seen:

Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py
==============================================================================
--- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py	(original)
+++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py	Sun Mar  4 18:42:24 2007
@@ -320,6 +320,8 @@
         if h is None:
             h = s.hash_part()
         else:
+            # try twice due to caching reasons
+            assert s.hash_part() == h
             assert s.hash_part() == h
 
 def test_equality():



More information about the Pypy-commit mailing list