PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/memory/lldict.py

https://bitbucket.org/pypy/pypy/
Python | 100 lines | 78 code | 18 blank | 4 comment | 7 complexity | b9824f3ac740d94e1b3a120b660dc8f2 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rtyper.lltypesystem import lltype, llmemory
  2. from rpython.rtyper.lltypesystem import rdict
  3. from rpython.rlib.objectmodel import we_are_translated
  4. from rpython.memory.support import mangle_hash
  5. # This is a low-level AddressDict, reusing a lot of the logic from rdict.py.
  6. # xxx this is very dependent on the details of rdict.py
  7. alloc_count = 0 # for debugging
  8. def count_alloc(delta):
  9. "NOT_RPYTHON"
  10. global alloc_count
  11. alloc_count += delta
  12. def newdict(length_estimate=0):
  13. return rdict.ll_newdict_size(DICT, length_estimate)
  14. def dict_allocate():
  15. if not we_are_translated(): count_alloc(+1)
  16. return lltype.malloc(DICT, flavor="raw")
  17. def dict_delete(d):
  18. dict_delete_entries(d.entries)
  19. lltype.free(d, flavor="raw")
  20. if not we_are_translated(): count_alloc(-1)
  21. def dict_allocate_entries(n):
  22. if not we_are_translated(): count_alloc(+1)
  23. # 'raw zero varsize malloc with length field' is not really implemented.
  24. # we can initialize the memory to zero manually
  25. entries = lltype.malloc(ENTRIES, n, flavor="raw")
  26. i = 0
  27. while i < n:
  28. entries[i].key = llmemory.NULL
  29. i += 1
  30. return entries
  31. def dict_delete_entries(entries):
  32. lltype.free(entries, flavor="raw")
  33. if not we_are_translated(): count_alloc(-1)
  34. def _hash(adr):
  35. return mangle_hash(llmemory.cast_adr_to_int(adr))
  36. def dict_keyhash(d, key):
  37. return _hash(key)
  38. def dict_entry_valid(entries, i):
  39. return entries[i].key != llmemory.NULL
  40. def dict_entry_hash(entries, i):
  41. return _hash(entries[i].key)
  42. def dict_get(d, key, default=llmemory.NULL):
  43. return rdict.ll_get(d, key, default)
  44. def dict_add(d, key):
  45. rdict.ll_dict_setitem(d, key, llmemory.NULL)
  46. def dict_insertclean(d, key, value):
  47. rdict.ll_dict_insertclean(d, key, value, _hash(key))
  48. def dict_foreach(d, callback, arg):
  49. entries = d.entries
  50. i = len(entries) - 1
  51. while i >= 0:
  52. if dict_entry_valid(entries, i):
  53. callback(entries[i].key, entries[i].value, arg)
  54. i -= 1
  55. dict_foreach._annspecialcase_ = 'specialize:arg(1)'
  56. ENTRY = lltype.Struct('ENTRY', ('key', llmemory.Address),
  57. ('value', llmemory.Address))
  58. ENTRIES = lltype.Array(ENTRY,
  59. adtmeths = {
  60. 'allocate': dict_allocate_entries,
  61. 'delete': dict_delete_entries,
  62. 'valid': dict_entry_valid,
  63. 'everused': dict_entry_valid,
  64. 'hash': dict_entry_hash,
  65. })
  66. DICT = lltype.Struct('DICT', ('entries', lltype.Ptr(ENTRIES)),
  67. ('num_items', lltype.Signed),
  68. ('resize_counter', lltype.Signed),
  69. adtmeths = {
  70. 'allocate': dict_allocate,
  71. 'delete': dict_delete,
  72. 'length': rdict.ll_dict_len,
  73. 'contains': rdict.ll_contains,
  74. 'setitem': rdict.ll_dict_setitem,
  75. 'get': dict_get,
  76. 'add': dict_add,
  77. 'insertclean': dict_insertclean,
  78. 'clear': rdict.ll_clear,
  79. 'foreach': dict_foreach,
  80. 'keyhash': dict_keyhash,
  81. 'keyeq': None,
  82. })