Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit