[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