Pigweed
 
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
30class SortedItem : public IntrusiveForwardList<SortedItem>::Item {};
31
32namespace internal {
33
44template <typename Derived, typename BlockType>
45class SortedBucketBase : public BucketBase<Derived, BlockType, SortedItem> {
46 private:
48 friend Base;
49
50 public:
51 constexpr SortedBucketBase() = default;
53
54 private:
56 void DoAdd(BlockType& block) {
57 auto* item_to_add = new (block.UsableSpace()) SortedItem();
58 auto prev = Base::FindPrevIf(items_.before_begin(),
59 items_.end(),
60 Derived::MakeAddPredicate(block.InnerSize()));
61 items_.insert_after(prev, *item_to_add);
62 }
63
65 BlockType* DoRemoveAny() {
66 SortedItem& item = items_.front();
67 items_.pop_front();
68 return BlockType::FromUsableSpace(&item);
69 }
70
72 bool DoRemove(BlockType& block) {
73 return items_.remove(Base::GetItemFrom(block));
74 }
75
77 BlockType* DoRemoveCompatible(Layout layout) {
78 auto prev = Base::FindPrevIf(items_.before_begin(),
79 items_.end(),
81 auto* block = Base::GetBlockFromPrev(prev, items_.end());
82 if (block != nullptr) {
83 items_.erase_after(prev);
84 }
85 return block;
86 }
87
89};
90
91} // namespace internal
92
100template <typename BlockType>
102 : public internal::SortedBucketBase<ForwardSortedBucket<BlockType>,
103 BlockType> {
104 public:
109 static constexpr auto MakeAddPredicate(size_t inner_size) {
110 return [inner_size](SortedItem& item) {
111 auto* block = BlockType::FromUsableSpace(&item);
112 return inner_size < block->InnerSize();
113 };
114 }
115};
116
124template <typename BlockType>
126 : public internal::SortedBucketBase<ReverseSortedBucket<BlockType>,
127 BlockType> {
128 public:
133 static constexpr auto MakeAddPredicate(size_t inner_size) {
134 return [inner_size](SortedItem& item) {
135 auto* block = BlockType::FromUsableSpace(&item);
136 return block->InnerSize() < inner_size;
137 };
138 }
139};
140
141} // namespace pw::allocator
Definition: intrusive_forward_list.h:86
Definition: sorted.h:103
static constexpr auto MakeAddPredicate(size_t inner_size)
Definition: sorted.h:109
Definition: layout.h:56
Definition: sorted.h:127
static constexpr auto MakeAddPredicate(size_t inner_size)
Definition: sorted.h:133
Definition: sorted.h:30
static auto MakeCanAllocPredicate(Layout layout)
Definition: base.h:157
constexpr BlockType * GetBlockFromPrev(Iterator prev, Iterator last)
Definition: base.h:174
void Clear()
Removes all blocks from this bucket.
Definition: base.h:124
static ItemType & GetItemFrom(BlockType &block)
Definition: base.h:185
static Iterator FindPrevIf(Iterator before_first, Iterator last, Predicate predicate)
Definition: base.h:138