Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r45197:2baa8e3dcdff Date: 2011-06-30 15:14 +0200 http://bitbucket.org/pypy/pypy/changeset/2baa8e3dcdff/
Log: Improve popitem() to use the same hack as CPython: store the next index in the hash field (at least when there is a hash field, e.g. with r_dicts visible at app-level). diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py --- a/pypy/rpython/lltypesystem/rdict.py +++ b/pypy/rpython/lltypesystem/rdict.py @@ -847,8 +847,12 @@ def ll_popitem(ELEM, dic): entries = dic.entries + ENTRY = lltype.typeOf(entries).TO.OF dmask = len(entries) - 1 - base = global_popitem_index.nextindex + if hasattr(ENTRY, 'f_hash'): + base = entries[0].f_hash + else: + base = global_popitem_index.nextindex counter = 0 while counter <= dmask: i = (base + counter) & dmask @@ -857,7 +861,10 @@ break else: raise KeyError - global_popitem_index.nextindex += counter + if hasattr(ENTRY, 'f_hash'): + entries[0].f_hash = base + counter + else: + global_popitem_index.nextindex = base + counter entry = entries[i] r = lltype.malloc(ELEM.TO) r.item0 = recast(ELEM.TO.item0, entry.key) diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py --- a/pypy/rpython/test/test_rdict.py +++ b/pypy/rpython/test/test_rdict.py @@ -598,6 +598,30 @@ res = self.interpret(func, []) assert res in [5263, 6352] + def test_dict_popitem_hash(self): + def deq(n, m): + return n == m + def dhash(n): + return ~n + def func(): + d = r_dict(deq, dhash) + d[5] = 2 + d[6] = 3 + k1, v1 = d.popitem() + assert len(d) == 1 + k2, v2 = d.popitem() + try: + d.popitem() + except KeyError: + pass + else: + assert 0, "should have raised KeyError" + assert len(d) == 0 + return k1*1000 + v1*100 + k2*10 + v2 + + res = self.interpret(func, []) + assert res in [5263, 6352] + class TestLLtype(BaseTestRdict, LLRtypeMixin): def test_dict_but_not_with_char_keys(self): def func(i): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit