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ů.
 
 
 
 

129 řádky
3.8 KiB

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