#pragma once
#include <string>
#include <vector>
#include <utility>
template<typename Tp>
class FixedAllocator {
public:
explicit FixedAllocator(std::uint64_t page_size) :
page_allocator_(PageAllocator(sizeof(Tp) * page_size)),
page_size_(page_size) {
}
Tp *Allocate() {
Tp *page = nullptr;
if (free_.size() == 0) {
page = static_cast<Tp *>(page_allocator_.Allocate());
free_.push_back(std::make_pair(page_size_, page));
}
auto page_size = free_.front();
if (page_size.first > 1) {
free_[0].first--;
free_[0].second++;
} else {
free_.erase(free_.begin());
}
return page_size.second;
}
void Deallocate(Tp *p) {
for ( size_t i = 0; i < free_.size(); i++ ) {
if ((free_[i].second - p) == 1) {
free_[i].first++;
free_[i].second = p;
return;
}
}
free_.push_back(std::make_pair(1, p));
}
const PageAllocator &InnerAllocator() const noexcept {
return page_allocator_;
}
private:
PageAllocator page_allocator_;
const std::uint64_t page_size_;
std::vector<std::pair<uint64_t, Tp *>> free_;
};