Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

109 рядки
3.3 KiB

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