[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