Author: Maciej Fijalkowski <[email protected]>
Branch: rdict-experiments-2
Changeset: r59840:8ed7cb8c71e4
Date: 2013-01-07 16:20 +0200
http://bitbucket.org/pypy/pypy/changeset/8ed7cb8c71e4/
Log: change the API (again)
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
@@ -79,16 +79,12 @@
DICTENTRY = lltype.Struct("dictentry", *entryfields)
DICTENTRYARRAY = lltype.GcArray(DICTENTRY,
adtmeths=entrymeths)
- array_adtmeths = {'allocate': lltype.typeMethod(_ll_malloc_indexes),
- 'getitem': ll_dict_index_getitem,
- 'setitem': ll_dict_index_setitem}
fields = [("num_items", lltype.Signed),
("resize_counter", lltype.Signed),
("size", lltype.Signed),
("entries", lltype.Ptr(DICTENTRYARRAY)),
- ("indexes", lltype.Ptr(lltype.GcArray(lltype.Signed,
- adtmeths=array_adtmeths)))]
+ ("indexes", DICTINDEXARRAY)]
if get_custom_eq_hash is not None:
r_rdict_eqfn, r_rdict_hashfn = get_custom_eq_hash()
fields.extend([ ("fnkeyeq", r_rdict_eqfn.lowleveltype),
@@ -342,6 +338,32 @@
# be direct_call'ed from rtyped flow graphs, which means that they will
# get flowed and annotated, mostly with SomePtr.
+# --------------------- indexes ------------------
+
+DICTINDEXARRAY = lltype.Ptr(lltype.GcArray(lltype.Signed))
+
+def _ll_malloc_indexes(n):
+ res = lltype.malloc(DICTINDEXARRAY.TO, n)
+ i = 0
+ while i < n:
+ res[i] = FREE
+ i += 1
+ return res
+
+def ll_index_getitem(size, indexes, i):
+ return indexes[i]
+
+def ll_index_setitem(size, indexes, i, v):
+ indexes[i] = v
+
+def ll_dict_copy_indexes(size, from_indexes, to_indexes):
+ i = 0
+ while i < size:
+ ll_index_setitem(size, i, ll_index_getitem(size, from_indexes, i))
+ i += 1
+
+# ---------------------- hashes -------------------
+
def ll_hash_from_cache(entries, i):
return entries[i].f_hash
@@ -352,20 +374,8 @@
ENTRIES = lltype.typeOf(entries).TO
return ENTRIES.fasthashfn(entries[i].key)
-def ll_dict_index_getitem(indexes, i):
- return indexes[i]
-
-def ll_dict_index_setitem(indexes, i, v):
- indexes[i] = v
-
-def ll_dict_copy_indexes(size, from_indexes, to_indexes):
- i = 0
- while i < size:
- to_indexes.setitem(i, from_indexes.getitem(i))
- i += 1
-
def ll_get_value(d, i):
- return d.entries[d.indexes.getitem(i)].value
+ return d.entries[ll_index_getitem(d.size, d.indexes, i)].value
def ll_keyhash_custom(d, key):
DICT = lltype.typeOf(d).TO
@@ -405,7 +415,7 @@
valid = (i & HIGHEST_BIT) == 0
i = i & MASK
ENTRY = lltype.typeOf(d.entries).TO.OF
- index = d.indexes.getitem(i)
+ index = ll_index_getitem(d.size, d.indexes, i)
if index == FREE:
index = d.num_items
entry = d.entries[index]
@@ -421,12 +431,12 @@
ll_assert(rc > 0, "ll_dict_resize failed?")
ll_assert(index < len(d.entries), "invalid insert")
d.resize_counter = rc
- d.indexes.setitem(i, index)
+ ll_index_setitem(d.size, d.indexes, i, index)
entry.value = value
elif index == DELETED:
index = d.num_items
entry = d.entries[index]
- d.indexes.setitem(i, index)
+ ll_index_setitem(d.size, d.indexes, i, index)
entry.value = value
else:
# override an existing or deleted entry
@@ -446,7 +456,7 @@
@jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i))
def _ll_dict_del(d, i):
- index = d.indexes.getitem(i)
+ index = ll_index_getitem(d.size, d.indexes, i)
ENTRIES = lltype.typeOf(d.entries).TO
ENTRY = ENTRIES.OF
if index != d.num_items - 1:
@@ -454,7 +464,7 @@
key = old_entry.key
to_insert_i = ll_dict_lookup(d, key, d.keyhash(key))
ll_assert(not to_insert_i & HIGHEST_BIT, "invalid entry")
- d.indexes.setitem(to_insert_i, index)
+ ll_index_setitem(d.size, d.indexes, to_insert_i, index)
# copy the value
new_entry = d.entries[index]
new_entry.key = key
@@ -462,7 +472,7 @@
if hasattr(ENTRY, 'f_hash'):
new_entry.f_hash = old_entry.f_hash
# clear the key and the value if they are GC pointers
- d.indexes.setitem(i, DELETED)
+ ll_index_setitem(d.size, d.indexes, i, DELETED)
d.num_items -= 1
entry = d.entries[d.num_items]
if ENTRIES.clear_key:
@@ -498,16 +508,16 @@
new_size *= 2
#
new_item_size = new_size // 3 * 2 + 1
- d.indexes = lltype.typeOf(d).TO.indexes.TO.allocate(new_size)
+ d.indexes = _ll_malloc_indexes(new_size)
d.size = new_size
d.resize_counter = new_item_size - d.num_items
i = 0
indexes = d.indexes
while i < old_size:
- index = old_indexes.getitem(i)
+ index = ll_index_getitem(old_size, old_indexes, i)
if old_entries.valid(index):
pos = ll_dict_lookup_clean(d, old_entries.hash(index))
- indexes.setitem(pos, index)
+ ll_index_setitem(d.size, indexes, pos, index)
i += 1
if len(old_entries) != new_item_size:
d.entries = lltype.typeOf(old_entries).TO.allocate(new_item_size)
@@ -540,7 +550,7 @@
# do the first try before any looping
ENTRIES = lltype.typeOf(entries).TO
direct_compare = not hasattr(ENTRIES, 'no_direct_compare')
- index = indexes.getitem(i)
+ index = ll_index_getitem(d.size, indexes, i)
if entries.valid(index):
checkingkey = entries[index].key
if direct_compare and checkingkey == key:
@@ -552,7 +562,7 @@
#llop.debug_print(lltype.Void, "comparing keys",
ll_debugrepr(checkingkey), ll_debugrepr(key), found)
if d.paranoia:
if (entries != d.entries or
- not entries.valid(indexes.getitem(i))
+ not entries.valid(ll_index_getitem(d.size, indexes, i))
or entries[index].key != checkingkey):
# the compare did major nasty stuff to the dict: start over
return ll_dict_lookup(d, key, hash)
@@ -572,7 +582,7 @@
i = r_uint(i)
i = (i << 2) + i + perturb + 1
i = intmask(i) & mask
- index = indexes.getitem(i)
+ index = ll_index_getitem(d.size, indexes, i)
# keep 'i' as a signed number here, to consistently pass signed
# arguments to the small helper methods.
if index == FREE:
@@ -589,7 +599,7 @@
found = d.keyeq(checkingkey, key)
if d.paranoia:
if (entries != d.entries or
- not entries.valid(indexes.getitem(i)) or
+ not entries.valid(ll_index_getitem(d.size, indexes,
i)) or
entries[index].key != checkingkey):
# the compare did major nasty stuff to the dict:
# start over
@@ -608,7 +618,7 @@
mask = d.size - 1
i = hash & mask
perturb = r_uint(hash)
- while indexes.getitem(i) != FREE:
+ while ll_index_getitem(d.size, indexes, i) != FREE:
i = r_uint(i)
i = (i << 2) + i + perturb + 1
i = intmask(i) & mask
@@ -631,7 +641,7 @@
d.size = DICT_INITSIZE
d.num_items = 0
for i in range(DICT_INITSIZE):
- d.indexes.setitem(i, FREE)
+ ll_index_setitem(d.size, d.indexes, i, FREE)
d.entries = DICT.entries.TO.allocate(DICT_ITEMS_INITSIZE)
d.resize_counter = DICT_ITEMS_INITSIZE
return d
@@ -644,7 +654,7 @@
items_size = n // 3 * 2 + 1
d = DICT.allocate()
d.entries = DICT.entries.TO.allocate(items_size)
- d.indexes = DICT.indexes.TO.allocate(n)
+ d.indexes = _ll_malloc_indexes(n)
d.size = n
d.num_items = 0
d.resize_counter = items_size
@@ -657,13 +667,6 @@
return lltype.malloc(DICT)
def _ll_malloc_entries(ENTRIES, n):
return lltype.malloc(ENTRIES, n, zero=True)
-def _ll_malloc_indexes(ITEMS, n):
- res = lltype.malloc(ITEMS, n)
- i = 0
- while i < n:
- res[i] = FREE
- i += 1
- return res
def rtype_r_dict(hop):
r_dict = hop.r_result
@@ -763,7 +766,7 @@
dictsize = len(dict.entries)
d = DICT.allocate()
d.entries = lltype.malloc(DICT.entries.TO, dictsize)
- d.indexes = DICT.indexes.TO.allocate(dict.size)
+ d.indexes = _ll_malloc_indexes(dict.size)
d.size = dict.size
d.num_items = dict.num_items
d.resize_counter = dict.resize_counter
@@ -781,7 +784,7 @@
return
old_entries = d.entries
d.entries = lltype.typeOf(old_entries).TO.allocate(DICT_ITEMS_INITSIZE)
- d.indexes = lltype.typeOf(d).TO.indexes.TO.allocate(DICT_INITSIZE)
+ d.indexes = _ll_malloc_indexes(DICT_INITSIZE)
d.size = DICT_INITSIZE
d.num_items = 0
d.resize_counter = DICT_ITEMS_INITSIZE
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit