[pypy-commit] pypy keys_with_hash: Use iteritems_with_hash() in dictmultiobject in order to let d1.update(d2)

arigo noreply at buildbot.pypy.org
Tue Sep 1 12:11:25 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: keys_with_hash
Changeset: r79346:f45fa5542e6b
Date: 2015-09-01 12:11 +0200
http://bitbucket.org/pypy/pypy/changeset/f45fa5542e6b/

Log:	Use iteritems_with_hash() in dictmultiobject in order to let
	d1.update(d2) not recompute hashes

diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -3,7 +3,7 @@
 indirection is introduced to make the version tag change less often.
 """
 
-from rpython.rlib import jit, rerased
+from rpython.rlib import jit, rerased, objectmodel
 
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.objspace.std.dictmultiobject import (
@@ -162,8 +162,8 @@
     def getitervalues(self, w_dict):
         return self.unerase(w_dict.dstorage).itervalues()
 
-    def getiteritems(self, w_dict):
-        return self.unerase(w_dict.dstorage).iteritems()
+    def getiteritems_with_hash(self, w_dict):
+        return objectmodel.iteritems_with_hash(self.unerase(w_dict.dstorage))
 
     wrapkey = _wrapkey
 
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -511,7 +511,7 @@
     def getitervalues(self, w_dict):
         raise NotImplementedError
 
-    def getiteritems(self, w_dict):
+    def getiteritems_with_hash(self, w_dict):
         raise NotImplementedError
 
     has_iterreversed = False
@@ -634,7 +634,7 @@
     def getitervalues(self, w_dict):
         return iter([])
 
-    def getiteritems(self, w_dict):
+    def getiteritems_with_hash(self, w_dict):
         return iter([])
 
     def getiterreversed(self, w_dict):
@@ -751,11 +751,11 @@
 
     class IterClassItems(BaseItemIterator):
         def __init__(self, space, strategy, impl):
-            self.iterator = strategy.getiteritems(impl)
+            self.iterator = strategy.getiteritems_with_hash(impl)
             BaseIteratorImplementation.__init__(self, space, strategy, impl)
 
         def next_item_entry(self):
-            for key, value in self.iterator:
+            for key, value, keyhash in self.iterator:
                 return (wrapkey(self.space, key),
                         wrapvalue(self.space, value))
             else:
@@ -793,10 +793,10 @@
         # the logic is to call prepare_dict_update() after the first setitem():
         # it gives the w_updatedict a chance to switch its strategy.
         if 1:     # (preserve indentation)
-            iteritems = self.getiteritems(w_dict)
+            iteritemsh = self.getiteritems_with_hash(w_dict)
             if not same_strategy(self, w_updatedict):
                 # Different strategy.  Try to copy one item of w_dict
-                for key, value in iteritems:
+                for key, value, keyhash in iteritemsh:
                     w_key = wrapkey(self.space, key)
                     w_value = wrapvalue(self.space, value)
                     w_updatedict.setitem(w_key, w_value)
@@ -807,7 +807,7 @@
                 w_updatedict.strategy.prepare_update(w_updatedict, count)
                 # If the strategy is still different, continue the slow way
                 if not same_strategy(self, w_updatedict):
-                    for key, value in iteritems:
+                    for key, value, keyhash in iteritemsh:
                         w_key = wrapkey(self.space, key)
                         w_value = wrapvalue(self.space, value)
                         w_updatedict.setitem(w_key, w_value)
@@ -820,8 +820,8 @@
             # wrapping/unwrapping the key.
             assert setitem_untyped is not None
             dstorage = w_updatedict.dstorage
-            for key, value in iteritems:
-                setitem_untyped(self, dstorage, key, value)
+            for key, value, keyhash in iteritemsh:
+                setitem_untyped(self, dstorage, key, value, keyhash)
 
     def same_strategy(self, w_otherdict):
         return (setitem_untyped is not None and
@@ -945,8 +945,8 @@
     def getitervalues(self, w_dict):
         return self.unerase(w_dict.dstorage).itervalues()
 
-    def getiteritems(self, w_dict):
-        return self.unerase(w_dict.dstorage).iteritems()
+    def getiteritems_with_hash(self, w_dict):
+        return objectmodel.iteritems_with_hash(self.unerase(w_dict.dstorage))
 
     def getiterreversed(self, w_dict):
         return objectmodel.reversed_dict(self.unerase(w_dict.dstorage))
@@ -955,8 +955,9 @@
         objectmodel.prepare_dict_update(self.unerase(w_dict.dstorage),
                                         num_extra)
 
-    def setitem_untyped(self, dstorage, key, w_value):
-        self.unerase(dstorage)[key] = w_value
+    def setitem_untyped(self, dstorage, key, w_value, keyhash):
+        d = self.unerase(dstorage)
+        objectmodel.setitem_with_hash(d, key, keyhash, w_value)
 
 
 class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -1,4 +1,5 @@
 from rpython.rlib import rerased
+from rpython.rlib.objectmodel import iteritems_with_hash
 
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.objspace.std.dictmultiobject import (
@@ -103,8 +104,8 @@
         return self.unerase(w_dict.dstorage).dict_w.iterkeys()
     def getitervalues(self, w_dict):
         return self.unerase(w_dict.dstorage).dict_w.itervalues()
-    def getiteritems(self, w_dict):
-        return self.unerase(w_dict.dstorage).dict_w.iteritems()
+    def getiteritems_with_hash(self, w_dict):
+        return iteritems_with_hash(self.unerase(w_dict.dstorage).dict_w)
     def wrapkey(space, key):
         return space.wrap(key)
     def wrapvalue(space, value):
diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py
--- a/pypy/objspace/std/kwargsdict.py
+++ b/pypy/objspace/std/kwargsdict.py
@@ -3,7 +3,7 @@
 Based on two lists containing unwrapped key value pairs.
 """
 
-from rpython.rlib import jit, rerased
+from rpython.rlib import jit, rerased, objectmodel
 
 from pypy.objspace.std.dictmultiobject import (
     BytesDictStrategy, DictStrategy, EmptyDictStrategy, ObjectDictStrategy,
@@ -165,13 +165,14 @@
     def getitervalues(self, w_dict):
         return iter(self.unerase(w_dict.dstorage)[1])
 
-    def getiteritems(self, w_dict):
-        return Zip(*self.unerase(w_dict.dstorage))
+    def getiteritems_with_hash(self, w_dict):
+        keys, values_w = self.unerase(w_dict.dstorage)
+        return ZipItemsWithHash(keys, values_w)
 
     wrapkey = _wrapkey
 
 
-class Zip(object):
+class ZipItemsWithHash(object):
     def __init__(self, list1, list2):
         assert len(list1) == len(list2)
         self.list1 = list1
@@ -186,6 +187,7 @@
         if i >= len(self.list1):
             raise StopIteration
         self.i = i + 1
-        return (self.list1[i], self.list2[i])
+        key = self.list1[i]
+        return (key, self.list2[i], objectmodel.compute_hash(key))
 
 create_iterator_classes(KwargsDictStrategy)


More information about the pypy-commit mailing list