20#include "pw_allocator/bucket/base.h"
21#include "pw_containers/intrusive_list.h"
23namespace pw::allocator {
43template <
typename BlockType>
46 BucketBase<SequencedBucket<BlockType>, BlockType, SequencedItem> {
48 using Base = internal::
49 BucketBase<SequencedBucket<BlockType>, BlockType,
SequencedItem>;
55 constexpr size_t threshold()
const {
return threshold_; }
67 void DoAdd(BlockType& block);
70 const BlockType* DoFindLargest()
const;
73 BlockType* DoRemoveAny();
76 bool DoRemove(BlockType& block);
79 BlockType* DoRemoveCompatible(
Layout layout);
82 size_t threshold_ = 0;
89template <
typename BlockType>
90SequencedBucket<BlockType>::~SequencedBucket() {
94template <
typename BlockType>
95void SequencedBucket<BlockType>::DoAdd(BlockType& block) {
96 auto* item_to_add =
new (block.UsableSpace()) SequencedItem();
97 containers::future::IntrusiveList<SequencedItem>::iterator iter;
98 if (block.InnerSize() < threshold_) {
100 auto r_iter = std::find_if(
101 items_.rbegin(), items_.rend(), [item_to_add](SequencedItem& item) {
102 return &item < item_to_add;
108 iter = r_iter.base();
113 items_.begin(), items_.end(), [item_to_add](SequencedItem& item) {
114 return item_to_add < &item;
117 items_.insert(iter, *item_to_add);
120template <
typename BlockType>
121const BlockType* SequencedBucket<BlockType>::DoFindLargest()
const {
122 auto iter = std::max_element(items_.begin(), items_.end(), Base::Compare);
123 return BlockType::FromUsableSpace(&(*iter));
126template <
typename BlockType>
127BlockType* SequencedBucket<BlockType>::DoRemoveAny() {
128 SequencedItem& item = items_.front();
130 return BlockType::FromUsableSpace(&item);
133template <
typename BlockType>
134bool SequencedBucket<BlockType>::DoRemove(BlockType& block) {
135 SequencedItem& item_to_remove = Base::GetItemFrom(block);
136 if (block.InnerSize() >= threshold_) {
138 return items_.remove(item_to_remove);
141 auto iter = std::find_if(
142 items_.rbegin(), items_.rend(), [&item_to_remove](SequencedItem& item) {
143 return &item_to_remove == &item;
145 if (iter == items_.rend()) {
152template <
typename BlockType>
153BlockType* SequencedBucket<BlockType>::DoRemoveCompatible(Layout layout) {
154 auto predicate = Base::MakeCanAllocPredicate(layout);
155 SequencedItem* item =
nullptr;
156 if (layout.size() < threshold_) {
158 auto iter = std::find_if(items_.rbegin(), items_.rend(), predicate);
159 item = iter != items_.rend() ? &(*iter) :
nullptr;
162 auto iter = std::find_if(items_.begin(), items_.end(), predicate);
163 item = iter != items_.end() ? &(*iter) :
nullptr;
165 if (item ==
nullptr) {
168 auto* block = BlockType::FromUsableSpace(item);
Definition: sequenced.h:46
void set_threshold(size_t threshold)
Definition: sequenced.h:63
Definition: sequenced.h:35
Definition: intrusive_list.h:88
SmallBlock BlockType
Default block type to use for tests.
Definition: size_report.h:32