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.
 
 
 
 

97 líneas
2.8 KiB

  1. #include "arraylist.hpp"
  2. template <typename type, unsigned int bucket_size>
  3. class Bucket_Allocator {
  4. int latest_bucket;
  5. int next_index_in_latest_bucket;
  6. int bucket_count;
  7. int next_bucket_index;
  8. Array_List<type*> free_list;
  9. type** buckets;
  10. void expand() {
  11. // realloc time
  12. buckets = (type**)realloc(buckets, bucket_count * 2 * sizeof(type*));
  13. for (int i = bucket_count; i < bucket_count * 2; ++i) {
  14. buckets[i] = (type*)malloc(bucket_size * sizeof(type));
  15. }
  16. bucket_count *= 2;
  17. }
  18. void jump_to_next_bucket() {
  19. next_index_in_latest_bucket = 0;
  20. ++next_bucket_index;
  21. if (next_bucket_index >= bucket_count) {
  22. expand();
  23. }
  24. }
  25. void increment_pointers(int 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. Bucket_Allocator(unsigned int initial_bucket_count = 1) {
  33. latest_bucket = 0;
  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. for (int i = 0; i < bucket_count; ++i) {
  39. buckets[i] = (type*)malloc(bucket_size * sizeof(type));
  40. }
  41. }
  42. ~Bucket_Allocator() {
  43. for (int i = 0; i < bucket_count; ++i) {
  44. free(buckets[i]);
  45. }
  46. ::free(buckets);
  47. }
  48. type* allocate(unsigned int amount = 1) {
  49. type* ret;
  50. if (amount == 0) return nullptr;
  51. if (amount == 1) {
  52. if (free_list.next_index != 0) {
  53. return free_list.data[--free_list.next_index];
  54. }
  55. ret = buckets[next_bucket_index]+next_index_in_latest_bucket;
  56. increment_pointers(1);
  57. return ret;
  58. }
  59. if (amount > bucket_size)
  60. return nullptr;
  61. if ((bucket_size - next_index_in_latest_bucket) >= 4) {
  62. // if the current bucket is ahs enough free space
  63. ret = buckets[next_bucket_index]+(next_index_in_latest_bucket);
  64. increment_pointers(amount);
  65. return ret;
  66. } else {
  67. // the current bucket does not have enough free space
  68. // add all remainding slots to free list
  69. while (next_index_in_latest_bucket < bucket_size) {
  70. free_list.append(buckets[next_bucket_index]+next_index_in_latest_bucket);
  71. ++next_index_in_latest_bucket;
  72. }
  73. jump_to_next_bucket();
  74. return allocate(amount);
  75. }
  76. }
  77. void free(type* obj) {
  78. free_list.append(obj);
  79. }
  80. void reset() {
  81. latest_bucket = 0;
  82. next_index_in_latest_bucket = 0;
  83. next_bucket_index = 0;
  84. }
  85. };