Allocator Builder
Policy Based C++ Template Allocator Library
 All Classes Functions Variables Enumerations Enumerator Groups Pages
bucketizer.hpp
1 //
3 // Copyright 2014 Felix Petriconi
4 //
5 // License: http://boost.org/LICENSE_1_0.txt, Boost License 1.0
6 //
7 // Authors: http://petriconi.net, Felix Petriconi
8 //
10 #pragma once
11 
12 #include "allocator_base.hpp"
13 #include "internal/reallocator.hpp"
14 #include <cassert>
15 
16 namespace alb {
17  inline namespace v_100 {
35  template <class Allocator, unsigned MinSize, unsigned MaxSize, unsigned StepSize>
36  class bucketizer {
37  public:
38  static constexpr bool supports_truncated_deallocation = false;
39  static constexpr unsigned alignment = Allocator::alignment;
40 
41  static_assert(MinSize < MaxSize, "MinSize must be smaller than MaxSize");
42  static_assert((MaxSize - MinSize + 1) % StepSize == 0, "Incorrect ranges or step size!");
43 
44  static constexpr unsigned number_of_buckets = ((MaxSize - MinSize + 1) / StepSize);
45  static constexpr unsigned max_size = MaxSize;
46  static constexpr unsigned min_size = MinSize;
47  static constexpr unsigned step_size = StepSize;
48 
49  using allocator = Allocator;
50 
51  Allocator _buckets[number_of_buckets];
52 
53  bucketizer() noexcept
54  {
55  for (size_t i = 0; i < number_of_buckets; i++) {
56  _buckets[i].set_min_max(MinSize + i * StepSize, MinSize + (i + 1) * StepSize - 1);
57  }
58  }
59 
60  static constexpr size_t good_size(size_t n) noexcept {
61  return (number_of_buckets - (max_size - n)/step_size + 1) * step_size;
62  }
63 
70  block allocate(size_t n) noexcept
71  {
72  size_t i = 0;
73  while (i < number_of_buckets) {
74  if (_buckets[i].min_size() <= n && n <= _buckets[i].max_size()) {
75  return _buckets[i].allocate(n);
76  }
77  ++i;
78  }
79  return{};
80  }
81 
87  bool owns(const block &b) const noexcept
88  {
89  return b && (MinSize <= b.length && b.length <= MaxSize);
90  }
91 
102  bool reallocate(block &b, size_t n) noexcept
103  {
104  if (n != 0 && (n < MinSize || n > MaxSize)) {
105  return false;
106  }
107 
108  if (internal::is_reallocation_handled_default(*this, b, n)) {
109  return true;
110  }
111 
112  assert(owns(b));
113 
114  const auto alignedLength = internal::round_to_alignment(StepSize, n);
115  auto currentAllocator = find_matching_allocator(b.length);
116  auto newAllocator = find_matching_allocator(alignedLength);
117 
118  if (currentAllocator == newAllocator) {
119  return true;
120  }
121 
122  return internal::reallocate_with_copy(*currentAllocator, *newAllocator, b, alignedLength);
123  }
124 
129  void deallocate(block &b) noexcept
130  {
131  if (!b) {
132  return;
133  }
134  if (!owns(b)) {
135  assert(!"It is not wise to let me deallocate a foreign Block!");
136  return;
137  }
138 
139  auto currentAllocator = find_matching_allocator(b.length);
140  currentAllocator->deallocate(b);
141  }
142 
147  template <typename U = Allocator>
148  typename std::enable_if<traits::has_deallocate_all<U>::value, void>::type
149  deallocate_all() noexcept
150  {
151  for (auto &item : _buckets) {
153  }
154  }
155 
156  private:
157  Allocator *find_matching_allocator(size_t n) noexcept
158  {
159  assert(MinSize <= n && n <= MaxSize);
160  auto v = alb::internal::round_to_alignment(StepSize, n);
161  return &_buckets[(v - MinSize) / StepSize];
162  }
163  };
164 
165  template <class Allocator, unsigned MinSize, unsigned MaxSize, unsigned StepSize>
166  const unsigned bucketizer<Allocator, MinSize, MaxSize, StepSize>::number_of_buckets;
167  }
168  using namespace v_100;
169 }
block allocate(size_t n) noexcept
Definition: bucketizer.hpp:70
bool reallocate_with_copy(OldAllocator &oldAllocator, NewAllocator &newAllocator, block &b, size_t n) noexcept
Definition: reallocator.hpp:35
constexpr size_t round_to_alignment(size_t basis, size_t n) noexcept
std::enable_if< traits::has_deallocate_all< U >::value, void >::type deallocate_all() noexcept
Definition: bucketizer.hpp:149
bool reallocate(block &b, size_t n) noexcept
Definition: bucketizer.hpp:102
bool owns(const block &b) const noexcept
Definition: bucketizer.hpp:87
void deallocate(block &b) noexcept
Definition: bucketizer.hpp:129