C/C++ API Reference
Loading...
Searching...
No Matches
fast_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_multimap.h"
20#include "pw_function/function.h"
21
22namespace pw::allocator {
23
25
33template <typename BlockType>
35 : public IntrusiveMultiMap<size_t, FastSortedItem<BlockType>>::Item {
36 public:
37 size_t key() const {
38 const auto* block = BlockType::FromUsableSpace(this);
39 return block->InnerSize();
40 }
41};
42
53 : public IntrusiveMultiMap<size_t, GenericFastSortedItem>::Item {};
54
61template <typename BlockType>
63 : public internal::BucketBase<FastSortedBucket<BlockType>,
64 BlockType,
65 FastSortedItem<BlockType>> {
66 private:
68 BlockType,
70 friend Base;
71
72 template <typename>
73 friend class ReverseFastSortedBucket;
74
75 using Compare = Function<bool(size_t, size_t)>;
76
77 public:
78 constexpr FastSortedBucket() = default;
80
81 private:
82 // Constructor used by `ReverseFastSortedBucket`.
83 constexpr explicit FastSortedBucket(Compare&& compare)
84 : items_(std::move(compare)) {}
85
87 void DoAdd(BlockType& block);
88
90 const BlockType* DoFindLargest() const;
91
93 BlockType* DoRemoveAny();
94
96 bool DoRemove(BlockType& block);
97
99 BlockType* DoRemoveCompatible(Layout layout);
100
101 template <typename Iterator>
102 BlockType* RemoveImpl(Iterator iter, Layout layout);
103
105};
106
110template <typename BlockType>
112 : public internal::BucketBase<ReverseFastSortedBucket<BlockType>,
113 BlockType,
114 FastSortedItem<BlockType>> {
115 private:
117 BlockType,
119 friend Base;
120
121 public:
122 constexpr ReverseFastSortedBucket()
123 : impl_(std::greater<>()), items_(impl_.items_) {}
124
125 private:
127 void DoAdd(BlockType& block);
128
130 const BlockType* DoFindLargest() const;
131
133 BlockType* DoRemoveAny();
134
136 bool DoRemove(BlockType& block) { return impl_.DoRemove(block); }
137
139 BlockType* DoRemoveCompatible(Layout layout) {
140 return impl_.RemoveImpl(impl_.items_.begin(), layout);
141 }
142
145};
146
148
149// Template method implementations.
150
151template <typename BlockType>
153 Base::Clear();
154}
155
156template <typename BlockType>
157void FastSortedBucket<BlockType>::DoAdd(BlockType& block) {
158 auto* item = new (block.UsableSpace()) FastSortedItem<BlockType>();
159 items_.insert(*item);
160}
161
162template <typename BlockType>
163const BlockType* FastSortedBucket<BlockType>::DoFindLargest() const {
164 auto iter = items_.end();
165 --iter;
166 return BlockType::FromUsableSpace(&(*iter));
167}
168
169template <typename BlockType>
170BlockType* FastSortedBucket<BlockType>::DoRemoveAny() {
171 auto iter = items_.begin();
172 FastSortedItem<BlockType>& item = *iter;
173 items_.erase(iter);
174 return BlockType::FromUsableSpace(&item);
175}
176
177template <typename BlockType>
178bool FastSortedBucket<BlockType>::DoRemove(BlockType& block) {
179 FastSortedItem<BlockType>& item_to_remove = Base::GetItemFrom(block);
180 auto iters = items_.equal_range(block.InnerSize());
181 auto iter = std::find_if(iters.first,
182 iters.second,
183 [&item_to_remove](FastSortedItem<BlockType>& item) {
184 return &item_to_remove == &item;
185 });
186 if (iter == items_.end()) {
187 return false;
188 }
189 items_.erase(iter);
190 return true;
191}
192
193template <typename BlockType>
194BlockType* FastSortedBucket<BlockType>::DoRemoveCompatible(Layout layout) {
195 auto iter = items_.lower_bound(layout.size());
196 return RemoveImpl(iter, layout);
197}
198
199template <typename BlockType>
200template <typename Iterator>
201BlockType* FastSortedBucket<BlockType>::RemoveImpl(Iterator iter,
202 Layout layout) {
203 iter = std::find_if(iter, items_.end(), Base::MakeCanAllocPredicate(layout));
204 auto* block = Base::GetBlockFromIterator(iter, items_.end());
205 if (block != nullptr) {
206 items_.erase(iter);
207 }
208 return block;
209}
210
211template <typename BlockType>
212void ReverseFastSortedBucket<BlockType>::DoAdd(BlockType& block) {
213 impl_.DoAdd(block);
214}
215
216template <typename BlockType>
217const BlockType* ReverseFastSortedBucket<BlockType>::DoFindLargest() const {
218 auto iter = impl_.items_.begin();
219 return BlockType::FromUsableSpace(&(*iter));
220}
221
222template <typename BlockType>
223BlockType* ReverseFastSortedBucket<BlockType>::DoRemoveAny() {
224 auto iter = items_.begin();
225 FastSortedItem<BlockType>& item = *iter;
226 items_.erase(iter);
227 return BlockType::FromUsableSpace(&item);
228}
229
230} // namespace pw::allocator
Definition: intrusive_multimap.h:65
Definition: fast_sorted.h:65
Definition: fast_sorted.h:35
Definition: layout.h:64
Definition: fast_sorted.h:114
SmallBlock BlockType
Default block type to use for tests.
Definition: size_report.h:32
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
Definition: fast_sorted.h:53