Commits

Maciej Fijalkowski committed 063e02b

test and a fix

Comments (0)

Files changed (2)

pypy/rpython/lltypesystem/rdict.py

 
 def ll_dict_insertclean(d, key, value, hash):
     i = ll_dict_lookup_clean(d, hash)
-    return _ll_dict_setitem_lookup_done(d, key, value, hash, i)
+    return _ll_dict_setitem_lookup_done(d, key, value, hash, i | HIGHEST_BIT)
 
 def ll_dict_lookup_clean(d, hash):
     # a simplified version of ll_dict_lookup() which assumes that the
     # It only finds the next free slot for the given hash.
 
     # this is crucial during convert_const, where we cannot call keyhash
-    # directly. Unused otherwise
+    # directly.
     
     indexes = d.indexes
-    mask = len(indexes) - 1
+    mask = d.size - 1
     i = hash & mask
     perturb = r_uint(hash)
-    while indexes[i] >= 0:
+    while ll_index_getitem(d.size, indexes, i) >= 0:
         i = r_uint(i)
         i = (i << 2) + i + perturb + 1
         i = intmask(i) & mask
             freeslot = i
         perturb >>= PERTURB_SHIFT
 
-def ll_dict_lookup_clean(d, hash):
-    # a simplified version of ll_dict_lookup() which assumes that the
-    # key is new, and the dictionary doesn't contain deleted entries.
-    # It only finds the next free slot for the given hash.
-    indexes = d.indexes
-    mask = d.size - 1
-    i = hash & mask
-    perturb = r_uint(hash)
-    while ll_index_getitem(d.size, indexes, i) != FREE:
-        i = r_uint(i)
-        i = (i << 2) + i + perturb + 1
-        i = intmask(i) & mask
-        perturb >>= PERTURB_SHIFT
-    return i
-
 # ____________________________________________________________
 #
 #  Irregular operations.

pypy/rpython/test/test_rdict.py

         finally:
             lltype._array._check_range = original_check_range
 
+    def test_prebuilt_custom_dict(self):
+        class W(object):
+            def __init__(self, x):
+                self.x = x
+        
+        def hash(w):
+            return w.x
+
+        def eq(w1, w2):
+            return w1.x == w2.x
+        
+        d = r_dict(eq, hash)
+        w1 = W(1)
+        w2 = W(2)
+        w3 = W(3)
+        d[w1] = 3
+        d[w2] = 2
+        d[w3] = 8
+
+        def f(i):
+            return d[W(i)]
+
+        res = self.interpret(f, [2])
+        assert res == 2
+
     # ____________________________________________________________