C/C++ API Reference
Loading...
Searching...
No Matches
best_fit.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <cstddef>
17#include <limits>
18
19#include "pw_allocator/block/detailed_block.h"
20#include "pw_allocator/block_allocator.h"
21#include "pw_allocator/bucket/fast_sorted.h"
22#include "pw_allocator/bucket/sorted.h"
23#include "pw_allocator/config.h"
24
25namespace pw::allocator {
26
28
30template <typename OffsetType>
32
42template <typename BlockType = BestFitBlock<uintptr_t>>
43class BestFitAllocator : public BlockAllocator<BlockType> {
44 private:
47
48 public:
50
52 constexpr BestFitAllocator() = default;
53
60
61 private:
63 size_t DoGetMaxAllocatable() override {
64 const BlockType* largest = large_bucket_.empty()
65 ? small_bucket_.FindLargest()
66 : large_bucket_.FindLargest();
67 return largest == nullptr ? 0 : largest->InnerSize();
68 }
69
72 // The small bucket is slower; skip it if we can.
73 BlockType* block = nullptr;
74 if (layout.size() < sizeof(typename LargeBucket::ItemType)) {
75 block = small_bucket_.RemoveCompatible(layout);
76 if (block != nullptr) {
77 return BlockType::AllocFirst(std::move(block), layout);
78 }
79 }
80 block = large_bucket_.RemoveCompatible(layout);
81 if (block != nullptr) {
82 return BlockType::AllocFirst(std::move(block), layout);
83 }
84 return BlockResult<BlockType>(nullptr, Status::NotFound());
85 }
86
88 void ReserveBlock(BlockType& block) override {
89 // The small bucket is slower; skip it if we can.
90 if (!large_bucket_.Remove(block)) {
91 std::ignore = small_bucket_.Remove(block);
92 }
93 }
94
96 void RecycleBlock(BlockType& block) override {
97 if (block.InnerSize() < sizeof(typename LargeBucket::ItemType)) {
98 std::ignore = small_bucket_.Add(block);
99 } else {
100 std::ignore = large_bucket_.Add(block);
101 }
102 }
103
104 SmallBucket small_bucket_;
105 LargeBucket large_bucket_;
106};
107
109
110} // namespace pw::allocator
Definition: best_fit.h:43
void RecycleBlock(BlockType &block) override
Definition: best_fit.h:96
size_t DoGetMaxAllocatable() override
Definition: best_fit.h:63
BlockResult< BlockType > ChooseBlock(Layout layout) override
Definition: best_fit.h:71
constexpr BestFitAllocator()=default
Constexpr constructor. Callers must explicitly call Init.
BestFitAllocator(ByteSpan region)
Definition: best_fit.h:59
void ReserveBlock(BlockType &block) override
Definition: best_fit.h:88
Definition: block_allocator.h:106
void Init(ByteSpan region)
Definition: block_allocator.h:310
Definition: result.h:116
Definition: detailed_block.h:88
Definition: fast_sorted.h:65
Definition: fast_sorted.h:35
Definition: sorted.h:116
Definition: layout.h:58
bool Remove(BlockType &block)
Definition: base.h:118
const BlockType * FindLargest() const
Definition: base.h:103
bool Add(BlockType &block)
Definition: base.h:89
constexpr bool empty() const
Returns whether this buckets contains any free blocks.
Definition: base.h:70
BlockType * RemoveCompatible(Layout layout)
Definition: base.h:129