C/C++ API Reference
Loading...
Searching...
No Matches
sorted.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
18#include "pw_allocator/bucket/base.h"
19#include "pw_containers/intrusive_forward_list.h"
20
21namespace pw::allocator {
22
24
32class SortedItem : public IntrusiveForwardList<SortedItem>::Item {};
33
34// Forward declarations.
35
36template <typename BlockType>
38
39template <typename BlockType>
41
42namespace internal {
43
54template <typename Derived, typename BlockType>
55class SortedBucketBase : public BucketBase<Derived, BlockType, SortedItem> {
56 public:
58
59 protected:
61 friend Base;
62
63 constexpr SortedBucketBase() = default;
64
65 const IntrusiveForwardList<SortedItem>& items() const { return items_; }
66
68 void DoAdd(BlockType& block);
69
71 BlockType* DoRemoveAny();
72
74 bool DoRemove(BlockType& block) {
75 return items_.remove(Base::GetItemFrom(block));
76 }
77
79 BlockType* DoRemoveCompatible(Layout layout);
80
81 private:
83};
84
85} // namespace internal
86
94template <typename BlockType>
96 : public internal::SortedBucketBase<ForwardSortedBucket<BlockType>,
97 BlockType> {
98 private:
99 using Base =
101
102 friend Base;
103 friend typename Base::Base;
104
109 static constexpr auto MakeAddPredicate(size_t inner_size);
110
112 const BlockType* DoFindLargest() const;
113};
114
122template <typename BlockType>
124 : public internal::SortedBucketBase<ReverseSortedBucket<BlockType>,
125 BlockType> {
126 private:
127 using Base =
129
130 friend Base;
131 friend typename Base::Base;
132
137 static constexpr auto MakeAddPredicate(size_t inner_size);
138
140 const BlockType* DoFindLargest() const;
141};
142
144
145// Template method implementations.
146
147namespace internal {
148
149template <typename Derived, typename BlockType>
151 auto* item_to_add = new (block.UsableSpace()) SortedItem();
152 auto prev = Base::FindPrevIf(items_.before_begin(),
153 items_.end(),
154 Derived::MakeAddPredicate(block.InnerSize()));
155 items_.insert_after(prev, *item_to_add);
156}
157
158template <typename Derived, typename BlockType>
160 SortedItem& item = items_.front();
161 items_.pop_front();
162 return BlockType::FromUsableSpace(&item);
163}
164
165template <typename Derived, typename BlockType>
167 Layout layout) {
168 auto prev = Base::FindPrevIf(
169 items_.before_begin(), items_.end(), Base::MakeCanAllocPredicate(layout));
170 auto* block = Base::GetBlockFromPrev(prev, items_.end());
171 if (block != nullptr) {
172 items_.erase_after(prev);
173 }
174 return block;
175}
176
177} // namespace internal
178
179template <typename BlockType>
181 size_t inner_size) {
182 return [inner_size](SortedItem& item) {
183 auto* block = BlockType::FromUsableSpace(&item);
184 return inner_size < block->InnerSize();
185 };
186}
187
188template <typename BlockType>
189const BlockType* ForwardSortedBucket<BlockType>::DoFindLargest() const {
190 const auto& items = Base::items();
191 if (items.empty()) {
192 return nullptr;
193 }
194 auto iter = items.before_begin();
195 auto prev = iter;
196 do {
197 prev = iter++;
198 } while (iter != items.end());
199 return BlockType::FromUsableSpace(&(*prev));
200}
201
202template <typename BlockType>
203constexpr auto ReverseSortedBucket<BlockType>::MakeAddPredicate(
204 size_t inner_size) {
205 return [inner_size](SortedItem& item) {
206 auto* block = BlockType::FromUsableSpace(&item);
207 return block->InnerSize() < inner_size;
208 };
209}
210
211template <typename BlockType>
212const BlockType* ReverseSortedBucket<BlockType>::DoFindLargest() const {
213 const auto& items = Base::items();
214 auto iter = items.begin();
215 return BlockType::FromUsableSpace(&(*iter));
216}
217
218} // namespace pw::allocator
Definition: intrusive_forward_list.h:99
Definition: sorted.h:97
Definition: layout.h:64
Definition: sorted.h:125
Definition: sorted.h:32
void Clear()
Removes all blocks from this bucket.
Definition: base.h:118
static ItemType & GetItemFrom(BlockType &block)
Definition: base.h:169
BlockType * DoRemoveCompatible(Layout layout)
Definition: sorted.h:166
bool DoRemove(BlockType &block)
Definition: sorted.h:74
BlockType * DoRemoveAny()
Definition: sorted.h:159
void DoAdd(BlockType &block)
Definition: sorted.h:150
SmallBlock BlockType
Default block type to use for tests.
Definition: size_report.h:32