/rpython/rtyper/memory/lldict.py
Python | 100 lines | 78 code | 18 blank | 4 comment | 7 complexity | dc6c8d13afd6996f4d0e678effdc15bc MD5 | raw file
Possible License(s): Apache-2.0
- from rpython.rtyper.lltypesystem import lltype, llmemory
- from rpython.rtyper.lltypesystem import rdict
- from rpython.rlib.objectmodel import we_are_translated
- from rpython.rtyper.memory.support import mangle_hash
- # This is a low-level AddressDict, reusing a lot of the logic from rdict.py.
- # xxx this is very dependent on the details of rdict.py
- alloc_count = 0 # for debugging
- def count_alloc(delta):
- "NOT_RPYTHON"
- global alloc_count
- alloc_count += delta
- def newdict(length_estimate=0):
- return rdict.ll_newdict_size(DICT, length_estimate)
- def dict_allocate():
- if not we_are_translated(): count_alloc(+1)
- return lltype.malloc(DICT, flavor="raw")
- def dict_delete(d):
- dict_delete_entries(d.entries)
- lltype.free(d, flavor="raw")
- if not we_are_translated(): count_alloc(-1)
- def dict_allocate_entries(n):
- if not we_are_translated(): count_alloc(+1)
- # 'raw zero varsize malloc with length field' is not really implemented.
- # we can initialize the memory to zero manually
- entries = lltype.malloc(ENTRIES, n, flavor="raw")
- i = 0
- while i < n:
- entries[i].key = llmemory.NULL
- i += 1
- return entries
- def dict_delete_entries(entries):
- lltype.free(entries, flavor="raw")
- if not we_are_translated(): count_alloc(-1)
- def _hash(adr):
- return mangle_hash(llmemory.cast_adr_to_int(adr))
- def dict_keyhash(d, key):
- return _hash(key)
- def dict_entry_valid(entries, i):
- return entries[i].key != llmemory.NULL
- def dict_entry_hash(entries, i):
- return _hash(entries[i].key)
- def dict_get(d, key, default=llmemory.NULL):
- return rdict.ll_get(d, key, default)
- def dict_add(d, key):
- rdict.ll_dict_setitem(d, key, llmemory.NULL)
- def dict_insertclean(d, key, value):
- rdict.ll_dict_insertclean(d, key, value, _hash(key))
- def dict_foreach(d, callback, arg):
- entries = d.entries
- i = len(entries) - 1
- while i >= 0:
- if dict_entry_valid(entries, i):
- callback(entries[i].key, entries[i].value, arg)
- i -= 1
- dict_foreach._annspecialcase_ = 'specialize:arg(1)'
- ENTRY = lltype.Struct('ENTRY', ('key', llmemory.Address),
- ('value', llmemory.Address))
- ENTRIES = lltype.Array(ENTRY,
- adtmeths = {
- 'allocate': dict_allocate_entries,
- 'delete': dict_delete_entries,
- 'valid': dict_entry_valid,
- 'everused': dict_entry_valid,
- 'hash': dict_entry_hash,
- })
- DICT = lltype.Struct('DICT', ('entries', lltype.Ptr(ENTRIES)),
- ('num_items', lltype.Signed),
- ('resize_counter', lltype.Signed),
- adtmeths = {
- 'allocate': dict_allocate,
- 'delete': dict_delete,
- 'length': rdict.ll_dict_len,
- 'contains': rdict.ll_contains,
- 'setitem': rdict.ll_dict_setitem,
- 'get': dict_get,
- 'add': dict_add,
- 'insertclean': dict_insertclean,
- 'clear': rdict.ll_clear,
- 'foreach': dict_foreach,
- 'keyhash': dict_keyhash,
- 'keyeq': None,
- })