Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

133 řádky
3.8 KiB

  1. #include "arraylist.hpp"
  2. #include "types.hpp"
  3. template <typename type>
  4. struct Bucket_Allocator {
  5. u32 next_index_in_latest_bucket;
  6. u32 next_bucket_index;
  7. u32 bucket_count;
  8. u32 bucket_size;
  9. Array_List<type*> free_list;
  10. type** buckets;
  11. void clear() {
  12. next_index_in_latest_bucket = 0;
  13. next_bucket_index = 0;
  14. free_list.clear();
  15. }
  16. void expand() {
  17. buckets = (type**)realloc(buckets, bucket_count * 2 * sizeof(type*));
  18. bucket_count *= 2;
  19. }
  20. void jump_to_next_bucket() {
  21. next_index_in_latest_bucket = 0;
  22. ++next_bucket_index;
  23. if (next_bucket_index >= bucket_count) {
  24. expand();
  25. }
  26. buckets[next_bucket_index] = (type*)malloc(bucket_size * sizeof(type));
  27. }
  28. void increment_pointers(s32 amount = 1) {
  29. next_index_in_latest_bucket += amount;
  30. if (next_index_in_latest_bucket >= bucket_size) {
  31. jump_to_next_bucket();
  32. }
  33. }
  34. void alloc(u32 bucket_size = 16, u32 initial_bucket_count = 8) {
  35. this->free_list.alloc();
  36. this->bucket_size = bucket_size;
  37. next_index_in_latest_bucket = 0;
  38. next_bucket_index = 0;
  39. bucket_count = initial_bucket_count;
  40. buckets = (type**)malloc(bucket_count * sizeof(type*));
  41. buckets[0] = (type*)malloc(bucket_size * sizeof(type));
  42. }
  43. void dealloc() {
  44. for (u32 i = 0; i <= next_bucket_index; ++i) {
  45. free(buckets[i]);
  46. }
  47. this->free_list.dealloc();
  48. free(buckets);
  49. }
  50. u32 count_elements() {
  51. free_list.sort();
  52. type* val;
  53. u32 count = 0;
  54. for (u32 i = 0; i < next_bucket_index; ++i) {
  55. for (u32 j = 0; j < bucket_size; ++j) {
  56. val = buckets[i]+j;
  57. if (free_list.sorted_find(val) == -1)
  58. count++;
  59. }
  60. }
  61. for (u32 j = 0; j < next_index_in_latest_bucket; ++j) {
  62. val = buckets[next_bucket_index]+j;
  63. if (free_list.sorted_find(val) == -1)
  64. count++;
  65. }
  66. return count;
  67. }
  68. template <typename lambda>
  69. void for_each(lambda p) {
  70. free_list.sort();
  71. type* val;
  72. for (u32 i = 0; i < next_bucket_index; ++i) {
  73. for (u32 j = 0; j < bucket_size; ++j) {
  74. val = buckets[i]+j;
  75. if (free_list.sorted_find(val) == -1)
  76. p(val);
  77. }
  78. }
  79. for (u32 j = 0; j < next_index_in_latest_bucket; ++j) {
  80. val = buckets[next_bucket_index]+j;
  81. if (free_list.sorted_find(val) == -1)
  82. p(val);
  83. }
  84. }
  85. type* allocate(u32 amount = 1) {
  86. type* ret;
  87. if (amount == 0) return nullptr;
  88. if (amount == 1) {
  89. if (free_list.count != 0) {
  90. return free_list.data[--free_list.count];
  91. }
  92. ret = buckets[next_bucket_index]+next_index_in_latest_bucket;
  93. increment_pointers(1);
  94. return ret;
  95. }
  96. if (amount > bucket_size)
  97. return nullptr;
  98. if ((bucket_size - next_index_in_latest_bucket) >= 4) {
  99. // if the current bucket is ahs enough free space
  100. ret = buckets[next_bucket_index]+(next_index_in_latest_bucket);
  101. increment_pointers(amount);
  102. return ret;
  103. } else {
  104. // the current bucket does not have enough free space
  105. // add all remainding slots to free list
  106. while (next_index_in_latest_bucket < bucket_size) {
  107. free_list.append(buckets[next_bucket_index]+next_index_in_latest_bucket);
  108. ++next_index_in_latest_bucket;
  109. }
  110. jump_to_next_bucket();
  111. return allocate(amount);
  112. }
  113. }
  114. void free_object(type* obj) {
  115. free_list.append(obj);
  116. }
  117. };