[pypy-commit] pypy keys_with_hash: getitem_with_hash
arigo
noreply at buildbot.pypy.org
Tue Sep 1 10:38:50 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: keys_with_hash
Changeset: r79336:a2de5fee1e30
Date: 2015-09-01 10:34 +0200
http://bitbucket.org/pypy/pypy/changeset/a2de5fee1e30/
Log: getitem_with_hash
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -475,6 +475,10 @@
pair(self, s_key).setitem(s_value)
method_setitem_with_hash.can_only_throw = _dict_can_only_throw_nothing
+ def method_getitem_with_hash(self, s_key, s_hash):
+ return pair(self, s_key).getitem()
+ method_getitem_with_hash.can_only_throw = _dict_can_only_throw_keyerror
+
@op.contains.register(SomeString)
@op.contains.register(SomeUnicodeString)
def contains_String(annotator, string, char):
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -788,23 +788,23 @@
d = d.keys()
return reversed(d)
+def _expected_hash(d, key):
+ if isinstance(d, r_dict):
+ xxx
+ else:
+ return compute_hash(key)
+
def iterkeys_with_hash(d):
"""Iterates (key, hash) pairs without recomputing the hash."""
if not we_are_translated():
- if isinstance(d, r_dict):
- xxx
- else:
- return ((k, compute_hash(k)) for k in d)
+ return ((k, _expected_hash(d, k)) for k in d)
return d.iterkeys_with_hash()
def contains_with_hash(d, key, h):
"""Same as 'key in d'. The extra argument is the hash. Use this only
if you got the hash just now from some other ..._with_hash() function."""
if not we_are_translated():
- if isinstance(d, r_dict):
- xxx
- else:
- assert compute_hash(key) == h
+ assert _expected_hash(d, key) == h
return key in d
return d.contains_with_hash(key, h)
@@ -812,14 +812,19 @@
"""Same as 'd[key] = value'. The extra argument is the hash. Use this only
if you got the hash just now from some other ..._with_hash() function."""
if not we_are_translated():
- if isinstance(d, r_dict):
- xxx
- else:
- assert compute_hash(key) == h
+ assert _expected_hash(d, key) == h
d[key] = value
return
d.setitem_with_hash(key, h, value)
+def getitem_with_hash(d, key, h):
+ """Same as 'd[key]'. The extra argument is the hash. Use this only
+ if you got the hash just now from some other ..._with_hash() function."""
+ if not we_are_translated():
+ assert _expected_hash(d, key) == h
+ return d[key]
+ return d.getitem_with_hash(key, h)
+
# ____________________________________________________________
def import_from_mixin(M, special_methods=['__init__', '__del__']):
diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -627,6 +627,15 @@
res = interpret(f, [27])
assert res == 42
+def test_getitem_with_hash():
+ def f(i):
+ d = {i+.5: 42, i+.6: -612}
+ return getitem_with_hash(d, i+.5, compute_hash(i+.5))
+
+ assert f(29) == 42
+ res = interpret(f, [27])
+ assert res == 42
+
def test_import_from_mixin():
class M: # old-style
def f(self): pass
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -379,6 +379,16 @@
hop.gendirectcall(ll_dict_setitem_with_hash,
v_dict, v_key, v_hash, v_value)
+ def rtype_method_getitem_with_hash(self, hop):
+ v_dict, v_key, v_hash = hop.inputargs(
+ self, self.key_repr, lltype.Signed)
+ if not self.custom_eq_hash:
+ hop.has_implicit_exception(KeyError) # record that we know about it
+ hop.exception_is_here()
+ v_res = hop.gendirectcall(ll_dict_getitem_with_hash,
+ v_dict, v_key, v_hash)
+ return self.recast_value(hop.llops, v_res)
+
class __extend__(pairtype(OrderedDictRepr, rmodel.Repr)):
def rtype_getitem((r_dict, r_key), hop):
@@ -568,6 +578,13 @@
else:
raise KeyError
+def ll_dict_getitem_with_hash(d, key, hash):
+ index = d.lookup_function(d, key, hash, FLAG_LOOKUP)
+ if index >= 0:
+ return d.entries[index].value
+ else:
+ raise KeyError
+
def ll_dict_setitem(d, key, value):
hash = d.keyhash(key)
index = d.lookup_function(d, key, hash, FLAG_STORE)
More information about the pypy-commit
mailing list