Author: Maciej Fijalkowski <fij...@gmail.com> Branch: rdict-experiments-2 Changeset: r59812:b07d28a54bea Date: 2013-01-06 19:29 +0200 http://bitbucket.org/pypy/pypy/changeset/b07d28a54bea/
Log: hack hack and test test 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 @@ -339,7 +339,7 @@ return ENTRIES.fasthashfn(entries[i].key) def ll_get_value(d, i): - return d.entries[i].value + return d.entries[d.indexes[i]].value def ll_keyhash_custom(d, key): DICT = lltype.typeOf(d).TO @@ -384,7 +384,7 @@ rc = d.resize_counter - 3 if rc <= 0: # if needed, resize the dict -- before the insertion ll_dict_resize(d) - index = ll_dict_lookup_clean(d, hash) + index = d.indexes[ll_dict_lookup_clean(d, hash)] # then redo the lookup for 'key' entry = d.entries[index] rc = d.resize_counter - 3 @@ -431,13 +431,24 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): - XXX - d.entries.mark_deleted(i) + index = d.indexes[i] + d.indexes[i] = DELETED d.num_items -= 1 - # clear the key and the value if they are GC pointers ENTRIES = lltype.typeOf(d.entries).TO ENTRY = ENTRIES.OF - entry = d.entries[i] + if index != d.num_items: + old_entry = d.entries[d.num_items] + key = old_entry.key + to_insert_i = ll_dict_lookup(d, key, d.keyhash(key)) + d.indexes[to_insert_i] = index + # copy the value + new_entry = d.entries[index] + new_entry.key = key + new_entry.value = old_entry.value + if hasattr(ENTRY, 'f_hash'): + new_entry.f_hash = old_entry.f_hash + # clear the key and the value if they are GC pointers + entry = d.entries[d.num_items] if ENTRIES.must_clear_key: entry.key = lltype.nullptr(ENTRY.key.TO) if ENTRIES.must_clear_value: @@ -499,7 +510,7 @@ if index >= 0: checkingkey = entries[index].key if checkingkey == key: - return index # found the entry + return i # found the entry if d.keyeq is not None and entries.hash(index) == hash: # correct hash, maybe the key is e.g. a different pointer to # an equal object @@ -510,7 +521,7 @@ # the compare did major nasty stuff to the dict: start over return ll_dict_lookup(d, key, hash) if found: - return index # found the entry + return i # found the entry freeslot = -1 elif index == DELETED: freeslot = i @@ -548,7 +559,7 @@ # start over return ll_dict_lookup(d, key, hash) if found: - return index # found the entry + return i # found the entry elif freeslot == -1: freeslot = i perturb >>= PERTURB_SHIFT 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 @@ -25,17 +25,43 @@ class TestRDictDirect(object): - def test_dict_creation(self): + def _get_str_dict(self): + # STR -> lltype.Signed DICT = rdict.get_ll_dict(lltype.Ptr(rstr.STR), lltype.Signed, ll_fasthash_function=rstr.LLHelpers.ll_strhash, ll_hash_function=rstr.LLHelpers.ll_strhash, ll_eq_function=rstr.LLHelpers.ll_streq) + return DICT + + def test_dict_creation(self): + DICT = self._get_str_dict() ll_d = rdict.ll_newdict(DICT) rdict.ll_dict_setitem(ll_d, llstr("abc"), 13) assert (len([i for i in ll_d.indexes if i == rdict.FREE]) == rdict.DICT_INITSIZE - 1) assert rdict.ll_dict_getitem(ll_d, llstr("abc")) == 13 + def test_dict_del_lastitem(self): + DICT = self._get_str_dict() + ll_d = rdict.ll_newdict(DICT) + py.test.raises(KeyError, rdict.ll_dict_delitem, ll_d, llstr("abc")) + rdict.ll_dict_setitem(ll_d, llstr("abc"), 13) + py.test.raises(KeyError, rdict.ll_dict_delitem, ll_d, llstr("def")) + rdict.ll_dict_delitem(ll_d, llstr("abc")) + assert (len([i for i in ll_d.indexes if i == rdict.FREE]) == + rdict.DICT_INITSIZE - 1) + assert (len([i for i in ll_d.indexes if i == rdict.DELETED]) == 1) + py.test.raises(KeyError, rdict.ll_dict_getitem, ll_d, llstr("abc")) + + def test_dict_del_not_lastitem(self): + DICT = self._get_str_dict() + ll_d = rdict.ll_newdict(DICT) + rdict.ll_dict_setitem(ll_d, llstr("abc"), 13) + rdict.ll_dict_setitem(ll_d, llstr("def"), 15) + rdict.ll_dict_delitem(ll_d, llstr("abc")) + assert (len([i for i in ll_d.indexes if i == rdict.FREE]) == + rdict.DICT_INITSIZE - 2) + assert (len([i for i in ll_d.indexes if i == rdict.DELETED]) == 1) class BaseTestRdict(BaseRtypingTest): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit