Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit