You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

namespace.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "vm/vm.h"
  2. #include <stdio.h>
  3. static const l2_word tombstone = ~(l2_word)0;
  4. static struct l2_vm_namespace *set(struct l2_vm_namespace *ns, l2_word key, l2_word val);
  5. static struct l2_vm_namespace *alloc(size_t size, l2_word mask) {
  6. printf("alloc, size %zu, mask allows up to [%u]\n", size, mask);
  7. struct l2_vm_namespace *ns = calloc(
  8. 1, sizeof(struct l2_vm_namespace) + sizeof(l2_word) * size * 2);
  9. ns->size = size;
  10. ns->mask = mask;
  11. return ns;
  12. }
  13. static struct l2_vm_namespace *grow(struct l2_vm_namespace *ns) {
  14. struct l2_vm_namespace *newns = alloc(ns->size * 2, (ns->mask << 1) | ns->mask);
  15. for (size_t i = 0; i < ns->size; ++i) {
  16. l2_word key = ns->data[i];
  17. if (key == 0 || key == tombstone) {
  18. continue;
  19. }
  20. l2_word val = ns->data[ns->size + i];
  21. for (l2_word i = 0; ; ++i) {
  22. l2_word hash = (key + i) & newns->mask;
  23. if (newns->data[hash] == 0) {
  24. newns->data[hash] = key;
  25. newns->data[newns->size + hash] = val;
  26. newns->len += 1;
  27. break;
  28. }
  29. }
  30. }
  31. free(ns);
  32. return newns;
  33. }
  34. static void del(struct l2_vm_namespace *ns, l2_word key) {
  35. if (ns == NULL) {
  36. return;
  37. }
  38. for (l2_word i = 0; ; ++i) {
  39. l2_word hash = (key + i) & ns->mask;
  40. l2_word k = ns->data[hash];
  41. if (k == 0) {
  42. return;
  43. } else if (k == key) {
  44. ns->data[hash] = tombstone;
  45. return;
  46. }
  47. }
  48. }
  49. static struct l2_vm_namespace *set(struct l2_vm_namespace *ns, l2_word key, l2_word val) {
  50. if (ns == NULL) {
  51. ns = alloc(16, 0x0f);
  52. printf("alloc to %zu\n", ns->size);
  53. } else if (ns->len >= ns->size / 2) {
  54. ns = grow(ns);
  55. printf("grew to %zu\n", ns->size);
  56. }
  57. for (l2_word i = 0; ; ++i) {
  58. l2_word hash = (key + i) & ns->mask;
  59. l2_word k = ns->data[hash];
  60. if (k == tombstone) {
  61. ns->data[hash] = key;
  62. ns->data[ns->size + hash] = val;
  63. break;
  64. } else if (k == key) {
  65. ns->data[ns->size + hash] = val;
  66. break;
  67. } else if (k == 0) {
  68. ns->len += 1;
  69. ns->data[hash] = key;
  70. ns->data[ns->size + hash] = val;
  71. break;
  72. }
  73. }
  74. return ns;
  75. }
  76. static l2_word get(struct l2_vm_namespace *ns, l2_word key) {
  77. if (ns == NULL) {
  78. return 0;
  79. }
  80. for (l2_word i = 0; ; ++i) {
  81. l2_word hash = (key + i) & ns->mask;
  82. l2_word k = ns->data[hash];
  83. if (k == 0) {
  84. return 0;
  85. } else if (k == key) {
  86. printf("found, %i collisions\n", i);
  87. return ns->data[ns->size + hash];
  88. }
  89. }
  90. }
  91. void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val) {
  92. if (val == 0) {
  93. del(ns->data, key);
  94. } else {
  95. ns->data = set(ns->data, key, val);
  96. }
  97. }
  98. l2_word l2_vm_namespace_get(struct l2_vm_value *ns, l2_word key) {
  99. return get(ns->data, key);
  100. }