No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

108 líneas
3.2 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. Bucket_Allocator(unsigned int bucket_size, unsigned int initial_bucket_count) {
  32. this->bucket_size = bucket_size;
  33. next_index_in_latest_bucket = 0;
  34. next_bucket_index = 0;
  35. bucket_count = initial_bucket_count;
  36. buckets = (type**)malloc(bucket_count * sizeof(type*));
  37. buckets[0] = (type*)malloc(bucket_size * sizeof(type));
  38. }
  39. ~Bucket_Allocator() {
  40. for (unsigned int i = 0; i <= next_bucket_index; ++i) {
  41. free(buckets[i]);
  42. }
  43. free(buckets);
  44. }
  45. template <typename proc>
  46. void for_each(proc p) {
  47. free_list.sort();
  48. type* val;
  49. for (unsigned int i = 0; i < next_bucket_index; ++i) {
  50. for (unsigned int j = 0; j < bucket_size; ++j) {
  51. val = buckets[i]+j;
  52. if (free_list.sorted_find(val) == -1)
  53. p(val);
  54. }
  55. }
  56. for (unsigned int j = 0; j < next_index_in_latest_bucket; ++j) {
  57. val = buckets[next_bucket_index]+j;
  58. if (free_list.sorted_find(val) == -1)
  59. p(val);
  60. }
  61. }
  62. type* allocate(unsigned int amount = 1) {
  63. type* ret;
  64. if (amount == 0) return nullptr;
  65. if (amount == 1) {
  66. if (free_list.next_index != 0) {
  67. return free_list.data[--free_list.next_index];
  68. }
  69. ret = buckets[next_bucket_index]+next_index_in_latest_bucket;
  70. increment_pointers(1);
  71. return ret;
  72. }
  73. if (amount > bucket_size)
  74. return nullptr;
  75. if ((bucket_size - next_index_in_latest_bucket) >= 4) {
  76. // if the current bucket is ahs enough free space
  77. ret = buckets[next_bucket_index]+(next_index_in_latest_bucket);
  78. increment_pointers(amount);
  79. return ret;
  80. } else {
  81. // the current bucket does not have enough free space
  82. // add all remainding slots to free list
  83. while (next_index_in_latest_bucket < bucket_size) {
  84. free_list.append(buckets[next_bucket_index]+next_index_in_latest_bucket);
  85. ++next_index_in_latest_bucket;
  86. }
  87. jump_to_next_bucket();
  88. return allocate(amount);
  89. }
  90. }
  91. void free_object(type* obj) {
  92. free_list.append(obj);
  93. }
  94. };