Advertisement
radmickey

Untitled

Mar 26th, 2023
1,092
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdlib>
  4. #include <exception>
  5. #include <map>
  6. #include <list>
  7. #include <chrono>
  8.  
  9.  
  10. template <class T>
  11. class myContainer {
  12. private:
  13.     T* container_;
  14.     bool* free_chunks_;
  15.     size_t size_;
  16.     size_t count_free_chunks_;
  17.     size_t index_for_fill_;
  18. public:
  19.     myContainer() {
  20.         size_ = 0;
  21.         count_free_chunks_ = 0;
  22.         index_for_fill_ = 0;
  23.         container_ = nullptr;
  24.         free_chunks_ = nullptr;
  25.     }
  26.  
  27.     void resize(size_t elementCount) {
  28.         delete[] container_;
  29.         delete[] free_chunks_;
  30.         free_chunks_ = new bool[elementCount];
  31.         container_ = new T[elementCount];
  32.  
  33.         size_ = elementCount;
  34.         count_free_chunks_ = elementCount;
  35.  
  36.         for(size_t i = 0; i < elementCount; i++) {
  37.             free_chunks_[i] = true;
  38.         }
  39.     }
  40.  
  41.     void fill(T element_for_fill) {
  42.         container_[index_for_fill_++] = element_for_fill;
  43.     }
  44.  
  45.     void pushFreeChunk(T elementForPush) {
  46.         for (int i = 0; i < size_ ; i++) {
  47.             if (container_[i] == elementForPush) {
  48.                 free_chunks_[i] = true;
  49.                 count_free_chunks_++;
  50.                 return;
  51.             }
  52.         }
  53.     }
  54.  
  55.     T GetFreeChunk() {
  56.         for (size_t i = 0; i < size_; i++) {
  57.             if (free_chunks_[i]) {
  58.                 free_chunks_[i] = false;
  59.                 --count_free_chunks_;
  60.                 return container_[i];
  61.             }
  62.         }
  63.     }
  64.  
  65.     size_t GetCountFreeChunks() const {
  66.         return count_free_chunks_;
  67.     }
  68.  
  69.     size_t size() const {
  70.         return size_;
  71.     }
  72. };
  73.  
  74.  
  75. class Group {
  76. private:
  77.     size_t usedChunksCount_;
  78.     size_t chunksCount_;
  79.     size_t size_;
  80.     myContainer<void*> freeChunksStack_;
  81.  
  82. public:
  83.     Group(): usedChunksCount_(0), chunksCount_(0), size_(0) {}
  84.  
  85.     Group(size_t chunksCount, size_t size): chunksCount_(chunksCount), size_(size), usedChunksCount_(0) {
  86.  
  87.         freeChunksStack_.resize(chunksCount_);
  88.         auto* chunk = (char*)(malloc(chunksCount_ * size_));
  89.  
  90.         for (size_t i = 0; i < chunksCount_; ++i) {
  91.             freeChunksStack_.fill(chunk);
  92.             if (i != chunksCount_ - 1) {
  93.                 chunk += size_;
  94.             }
  95.         }
  96.     }
  97.  
  98.     bool havePlace() const {
  99.         return (usedChunksCount_ < chunksCount_&& freeChunksStack_.GetCountFreeChunks() > 0);
  100.     }
  101.  
  102.     void* getFreeChunk() {
  103.         auto *res = freeChunksStack_.GetFreeChunk();
  104.         return res;
  105.     }
  106.  
  107.     void* allocateInGroup() {
  108.         ++usedChunksCount_;
  109.         return getFreeChunk();
  110.     }
  111.  
  112.     void deallocateInGroup(void* chunk, size_t size) {
  113.         --usedChunksCount_;
  114.         freeChunksStack_.pushFreeChunk(chunk);
  115.     }
  116.  
  117.     size_t getChunkSize() const {
  118.         return size_;
  119.     }
  120.  
  121.     size_t getChunksCount() const {
  122.         return chunksCount_;
  123.     }
  124. };
  125.  
  126.  
  127.  
  128. bool cmp(const std::pair<size_t, Group>& l, const std::pair<size_t, Group>& r) {
  129.     return l.first < r.first;
  130. }
  131.  
  132.  
  133.  
  134. template <class T>
  135. class PoolAllocator {
  136. private:
  137.     size_t groupsNumber_;
  138.  
  139.     size_t binSearch(std::vector<std::pair<size_t, Group>>& arr, size_t x) {
  140.         size_t sz = arr.size();
  141.         size_t l = 0;
  142.         size_t h = sz;
  143.         while (l < h) {
  144.             size_t mid = l + (h - l) / 2;
  145.             if (x <= arr[mid].first) {
  146.                 h = mid;
  147.             } else {
  148.                 l = mid + 1;
  149.             }
  150.         }
  151.         return l;
  152.     }
  153.  
  154. public:
  155.     typedef T value_type;
  156.     typedef value_type* pointer;
  157.     typedef const value_type* const_pointer;
  158.     typedef value_type& reference;
  159.     typedef const value_type& const_reference;
  160.     typedef size_t size_type;
  161.  
  162.     static std::vector<std::pair<size_type, Group>> allGroups_;
  163.     static std::map<pointer, int> positionToAllocatePointer_;
  164.  
  165.  
  166.     template<typename T2>
  167.     explicit PoolAllocator(PoolAllocator<T2> const& other) noexcept {
  168.         for (auto group : other.allGroups_) {
  169.             Group newGr(group.second.getChunksCount(), group.first);
  170.             allGroups_.push_back({group.first, newGr});
  171.         }
  172.         groupsNumber_ = other.getGroupsNumber();
  173.     }
  174.  
  175.     PoolAllocator() = default;
  176.  
  177.     PoolAllocator(std::vector<std::pair<int, size_type>>& memoryToAllocate) {
  178.         groupsNumber_ = memoryToAllocate.size();
  179.         for (size_t i = 0; i < groupsNumber_; ++i)
  180.             allGroups_.push_back({ memoryToAllocate[i].second,Group(memoryToAllocate[i].first, memoryToAllocate[i].second) });
  181.  
  182.         sort(allGroups_.begin(), allGroups_.end(), cmp);
  183.     }
  184.  
  185.     ~PoolAllocator() {
  186.         allGroups_.clear();
  187.     }
  188.  
  189.     pointer allocate(size_type chunksNum) {
  190.         size_t pastePosition = binSearch(allGroups_, chunksNum * sizeof(value_type));
  191.  
  192.         if (pastePosition < allGroups_.size()) {
  193.             auto& GroupToPaste = allGroups_[pastePosition];
  194.             if (GroupToPaste.second.havePlace()) {
  195.                 auto ptr = (pointer)GroupToPaste.second.allocateInGroup();
  196.                 positionToAllocatePointer_[ptr] = pastePosition;
  197.                 return ptr;
  198.             }
  199.  
  200.             else {
  201.                 for (size_t i = pastePosition; i < allGroups_.size(); i++)
  202.                     if (allGroups_[i].second.havePlace()) {
  203.                         auto *ptr = (pointer)allGroups_[i].second.allocateInGroup();
  204.                         positionToAllocatePointer_[ptr] = i;
  205.                         return ptr;
  206.                     }
  207.                 throw std::bad_alloc();
  208.             }
  209.  
  210.         }
  211.         else
  212.             throw std::bad_alloc();
  213.     }
  214.  
  215.     void deallocate(pointer ptr, size_type elementsCount) {
  216.         int deallocPos = positionToAllocatePointer_[ptr];
  217.         positionToAllocatePointer_.erase(ptr);
  218.         auto& GroupToDeallocate = allGroups_[deallocPos];
  219.         GroupToDeallocate.second.deallocateInGroup(ptr, elementsCount);
  220.     }
  221.  
  222.     size_type getGroupsNumber() const {
  223.         return groupsNumber_;
  224.     }
  225. };
  226.  
  227.  
  228. template <class T>
  229. std::vector<std::pair<size_t, Group>> PoolAllocator<T>::allGroups_;
  230.  
  231. template <class T>
  232. std::map<T*, int> PoolAllocator<T>::positionToAllocatePointer_;
  233.  
  234.  
  235.  
  236.  
  237. template <class T, class T2>
  238. bool operator==(const PoolAllocator <T>& first, const PoolAllocator <T2>& second) {
  239.     return (first.allGroups_ == second.allGroups_ && first.getGroupsNumber() == second.getGroupsNumber());
  240. }
  241.  
  242. template <class T, class T2>
  243. bool operator!=(const PoolAllocator <T>& first, const PoolAllocator <T2>& second) {
  244.     return (first.allGroups_ != second.allGroups_ || first.getGroupsNumber() != second.getGroupsNumber());
  245. }
  246.  
  247. int main() {
  248.  
  249.     std::vector<std::pair<int, size_t>> groups;
  250.     groups.resize(4);
  251.     groups[1].second = 2000; groups[1].first = 1000;
  252.     groups[2].second = 1000; groups[2].first = 1000;
  253.     groups[0].second = 2000; groups[0].first = 1000;
  254.     groups[3].second = 330000; groups[3].first = 2;
  255.  
  256.     PoolAllocator<int>testAlloc(groups);
  257.  
  258.     std::vector<int, PoolAllocator<int>> v1(testAlloc);
  259.  
  260.     auto start1 = std::chrono::system_clock::now();
  261.  
  262.     for (int i = 0; i < 10000; i++) {
  263.         v1.push_back(i);
  264.     }
  265.  
  266.     auto end1 = std::chrono::system_clock::now();
  267.  
  268.  
  269.     std::vector<int> v2;
  270.     auto start2 = std::chrono::system_clock::now();
  271.  
  272.     for (int i = 0; i < 10000; i++) {
  273.         v2.push_back(i);
  274.     }
  275.     auto end2 = std::chrono::system_clock::now();
  276.  
  277.     auto res1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - start1).count();
  278.     auto res2 = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - start2).count();
  279.  
  280.  
  281.  
  282.     std::cout << "\nThe time with MyAlloc: " << res1 << " ms\n";
  283.     std::cout << "\nThe time without MyAlloc: " << res2 << " ms\n";
  284.  
  285.  
  286.     return 0;
  287. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement