[pypy-commit] pypy rdict-experiments-3: (fijal, arigo) remove the mess from popitem that stored stuff in a global
fijal
noreply at buildbot.pypy.org
Wed Oct 9 19:12:48 CEST 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: rdict-experiments-3
Changeset: r67254:c6c3940285e7
Date: 2013-10-09 18:53 +0200
http://bitbucket.org/pypy/pypy/changeset/c6c3940285e7/
Log: (fijal, arigo) remove the mess from popitem that stored stuff in a
global structure.
diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -932,7 +932,7 @@
return entry.key
elif kind == 'values':
return entry.value
-
+
# clear the reference to the dict and prevent restarts
iter.dict = lltype.nullptr(lltype.typeOf(iter).TO.dict.TO)
raise StopIteration
@@ -1058,32 +1058,20 @@
i = ll_dict_lookup(d, key, d.keyhash(key))
return not i & HIGHEST_BIT
-POPITEMINDEX = lltype.Struct('PopItemIndex', ('nextindex', lltype.Signed))
-global_popitem_index = lltype.malloc(POPITEMINDEX, zero=True, immortal=True)
+def _ll_getnextitem(dic):
+ if dic.num_items == 0:
+ raise KeyError
-def _ll_getnextitem(dic):
entries = dic.entries
- ENTRY = lltype.typeOf(entries).TO.OF
- dmask = len(entries) - 1
- if hasattr(ENTRY, 'f_hash'):
- if entries.valid(0):
- return 0
- base = entries[0].f_hash
- else:
- base = global_popitem_index.nextindex
- counter = 0
- while counter <= dmask:
- i = (base + counter) & dmask
- counter += 1
+
+ i = dic.num_used_items - 1
+ while True:
if entries.valid(i):
break
- else:
- raise KeyError
- if hasattr(ENTRY, 'f_hash'):
- entries[0].f_hash = base + counter
- else:
- global_popitem_index.nextindex = base + counter
- return i
+ i -= 1
+
+ key = entries[i].key
+ return dic.lookup_function(dic, key, dic.keyhash(key), FLAG_DELETE)
def ll_popitem(ELEM, dic):
i = _ll_getnextitem(dic)
diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -146,11 +146,15 @@
ll_d = rdict.ll_newdict(DICT)
rdict.ll_dict_setitem(ll_d, llstr("k"), 1)
rdict.ll_dict_setitem(ll_d, llstr("j"), 2)
- ll_elem = rdict.ll_popitem(lltype.Ptr(
- lltype.GcStruct('x', ('item0', lltype.Ptr(rstr.STR)),
- ('item1', lltype.Signed))), ll_d)
+ TUP = lltype.Ptr(lltype.GcStruct('x', ('item0', lltype.Ptr(rstr.STR)),
+ ('item1', lltype.Signed)))
+ ll_elem = rdict.ll_popitem(TUP, ll_d)
assert hlstr(ll_elem.item0) == "j"
assert ll_elem.item1 == 2
+ ll_elem = rdict.ll_popitem(TUP, ll_d)
+ assert hlstr(ll_elem.item0) == "k"
+ assert ll_elem.item1 == 1
+ py.test.raises(KeyError, rdict.ll_popitem, TUP, ll_d)
def test_direct_enter_and_del(self):
def eq(a, b):
More information about the pypy-commit
mailing list