UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IoPriorityQueue.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Algo/BinarySearch.h"
6#include "Algo/IsSorted.h"
8
9template<typename T>
11{
12private:
13 struct TInternalQueue
14 {
15 TInternalQueue(int32 InPriority)
17 {
18
19 }
20
21 // Returns true if outer queue should be removed
22 bool Remove(T* Item)
23 {
24 T* Prev = Item->Prev;
25 T* Next = Item->Next;
26 Item->Prev = nullptr;
27 Item->Next = nullptr;
28 if (Prev && Next)
29 {
30 Prev->Next = Next;
31 Next->Prev = Prev;
32 return false;
33 }
34 if (Prev)
35 {
36 Prev->Next = Next;
37 }
38 else
39 {
40 Head = Next;
41 }
42 if (Next)
43 {
44 Next->Prev = Prev;
45 }
46 else
47 {
48 Tail = Prev;
49 }
50 if (!Head)
51 {
52 check(!Tail);
53 return true;
54 }
55 return false;
56 }
57 TInternalQueue* NextFree = nullptr;
58 T* Head = nullptr;
59 T* Tail = nullptr;
61 };
62
63public:
65 {
66 public:
68
70 {
71 Current = Next;
72 Next = Current ? Current->Next : nullptr;
73 return *this;
74 }
75
77 {
78 TIterator Tmp(*this);
79 Current = Next;
80 Next = Current ? Current->Next : nullptr;
81 return Tmp;
82 }
83
84 T& operator*() const
85 {
86 check(Current);
87 check(InternalQueue);
88 check(Current->Priority == InternalQueue->Priority);
89 return *Current;
90 }
91
92 T* operator->() const
93 {
94 check(Current);
95 check(InternalQueue);
96 check(Current->Priority == InternalQueue->Priority);
97 return Current;
98 }
99
100 explicit operator bool() const
101 {
102 return !!Current;
103 }
104
106 {
107 check(Current);
108 check(InternalQueue);
109 check(Current->Priority == InternalQueue->Priority);
110 if (InternalQueue->Remove(Current))
111 {
112 Outer.RemoveQueueByPriority(InternalQueue->Priority);
113 }
114 Current = reinterpret_cast<T*>(-1);
115 }
116
117 private:
119 : Outer(InOuter)
120 {
121 InternalQueue = Outer.FindQueueByPriority(InPriority);
122 if (InternalQueue)
123 {
124 Current = InternalQueue->Head;
125 Next = Current->Next;
126 }
127 else
128 {
129 Current = Next = nullptr;
130 }
131 }
132
133 TIoPriorityQueue<T>& Outer;
134 TInternalQueue* InternalQueue;
135 T* Current;
136 T* Next;
137 };
138
139 bool IsEmpty() const
140 {
141 return InternalQueues.IsEmpty();
142 }
143
145 {
146 if (InternalQueues.IsEmpty())
147 {
148 return MIN_int32;
149 }
150 return InternalQueues.Last()->Priority;
151 }
152
153 void Push(T* Item, int32 Priority)
154 {
155 check(!Item->Prev);
156 check(!Item->Next);
157 Item->Priority = Priority;
158 TInternalQueue& Queue = FindOrAddQueueByPriority(Priority);
159 if (!Queue.Head)
160 {
161 check(!Queue.Tail);
162 Queue.Head = Queue.Tail = Item;
163 }
164 else
165 {
166 Item->Prev = Queue.Tail;
167 Queue.Tail->Next = Item;
168 Queue.Tail = Item;
169 }
170 }
171
172 T* Pop()
173 {
174 if (InternalQueues.IsEmpty())
175 {
176 return nullptr;
177 }
178 int QueueIndex = InternalQueues.Num() - 1;
179 TInternalQueue* QueueWithHighestPriority = InternalQueues[QueueIndex];
183
184 T* Item = QueueWithHighestPriority->Head;
185 check(Item);
186 check(Item->Priority == QueueWithHighestPriority->Priority);
187 T* Next = Item->Next;
188 if (Next)
189 {
190 Next->Prev = nullptr;
192 }
193 else
194 {
195 check(Item == QueueWithHighestPriority->Tail);
197 RemoveQueueAtIndex(QueueIndex);
198 }
199 Item->Prev = Item->Next = nullptr;
200
201 return Item;
202 }
203
205 {
206 return TIterator(*this, Priority);
207 }
208
209 void Remove(T* Item)
210 {
211 T* Prev = Item->Prev;
212 T* Next = Item->Next;
213 if (Prev && Next)
214 {
215 Item->Prev = nullptr;
216 Item->Next = nullptr;
217 Prev->Next = Next;
218 Next->Prev = Prev;
219 return;
220 }
221 int32 QueueIndex;
222 TInternalQueue* InternalQueue = FindQueueByPriority(Item->Priority, QueueIndex);
223 check(InternalQueue);
224 if (InternalQueue->Remove(Item))
225 {
226 RemoveQueueAtIndex(QueueIndex);
227 }
228 }
229
231 {
232 Remove(Item);
233 Push(Item, NewPriority);
234 }
235
237 {
238 int32 QueueIndex;
239 TInternalQueue* Queue = FindQueueByPriority(Priority, QueueIndex);
240 if (!Queue)
241 {
242 return;
243 }
244 TInternalQueue& OtherQueue = Other.FindOrAddQueueByPriority(Priority);
245 if (OtherQueue.Head)
246 {
247 check(OtherQueue.Tail);
248 Queue->Head->Prev = OtherQueue.Tail;
249 OtherQueue.Tail->Next = Queue->Head;
250 OtherQueue.Tail = Queue->Tail;
251 }
252 else
253 {
254 OtherQueue.Head = Queue->Head;
255 OtherQueue.Tail = Queue->Tail;
256 }
257 Queue->Head = Queue->Tail = nullptr;
258 RemoveQueueAtIndex(QueueIndex);
259 }
260
261private:
262 TInternalQueue* FindQueueByPriority(int32 Priority) const
263 {
264 int32 Index = Algo::LowerBoundBy(InternalQueues, Priority, &TInternalQueue::Priority);
265 if (InternalQueues.IsValidIndex(Index) && InternalQueues[Index]->Priority == Priority)
266 {
267 return InternalQueues[Index];
268 }
269 return nullptr;
270 }
271
272 TInternalQueue* FindQueueByPriority(int32 Priority, int32& OutIndex) const
273 {
274 int32 Index = Algo::LowerBoundBy(InternalQueues, Priority, &TInternalQueue::Priority);
275 if (InternalQueues.IsValidIndex(Index) && InternalQueues[Index]->Priority == Priority)
276 {
277 OutIndex = Index;
278 return InternalQueues[Index];
279 }
280 return nullptr;
281 }
282
283 TInternalQueue& FindOrAddQueueByPriority(int32 Priority)
284 {
285 int32 Index = Algo::LowerBoundBy(InternalQueues, Priority, &TInternalQueue::Priority);
286 if (!InternalQueues.IsValidIndex(Index) || InternalQueues[Index]->Priority != Priority)
287 {
288 InternalQueues.Insert(AllocInternalQueue(Priority), Index);
289 }
290 return *InternalQueues[Index];
291 }
292
293 void RemoveQueueByPriority(int32 Priority)
294 {
295 int32 QueueIndex;
296 if (TInternalQueue* InternalQueue = FindQueueByPriority(Priority, QueueIndex))
297 {
298 RemoveQueueAtIndex(QueueIndex);
299 }
300 }
301
302 void RemoveQueueAtIndex(int32 Index)
303 {
304 FreeInternalQueue(InternalQueues[Index]);
305 InternalQueues.RemoveAt(Index, EAllowShrinking::No);
306 }
307
308 TInternalQueue* AllocInternalQueue(int32 Priority)
309 {
310 if (TInternalQueue* FromPool = FirstFreeQueue)
311 {
312 FirstFreeQueue = FromPool->NextFree;
313 FromPool->NextFree = nullptr;
314 FromPool->Priority = Priority;
315 return FromPool;
316 }
317 return new TInternalQueue(Priority);
318 }
319
320 void FreeInternalQueue(TInternalQueue* InternalQueue)
321 {
322 check(!InternalQueue->Head);
323 check(!InternalQueue->Tail);
324 InternalQueue->NextFree = FirstFreeQueue;
325 FirstFreeQueue = InternalQueue;
326 }
327
328 TArray<TInternalQueue*> InternalQueues; // Sorted by priority
329 TInternalQueue* FirstFreeQueue = nullptr;
330};
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
#define MIN_int32
Definition NumericLimits.h:16
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT ElementType & Last(SizeType IndexFromTheEnd=0) UE_LIFETIMEBOUND
Definition Array.h:1263
void RemoveAt(SizeType Index, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2083
UE_REWRITE bool IsEmpty() const
Definition Array.h:1133
UE_NODEBUG UE_FORCEINLINE_HINT bool IsValidIndex(SizeType Index) const
Definition Array.h:1122
SizeType Insert(std::initializer_list< ElementType > InitList, const SizeType InIndex)
Definition Array.h:1875
Definition IoPriorityQueue.h:65
TIterator operator++(int)
Definition IoPriorityQueue.h:76
T & operator*() const
Definition IoPriorityQueue.h:84
TIterator & operator++()
Definition IoPriorityQueue.h:69
T * operator->() const
Definition IoPriorityQueue.h:92
friend TIoPriorityQueue
Definition IoPriorityQueue.h:67
void RemoveCurrent()
Definition IoPriorityQueue.h:105
Definition IoPriorityQueue.h:11
int32 GetMaxPriority() const
Definition IoPriorityQueue.h:144
void MergeInto(TIoPriorityQueue< T > &Other, int32 Priority)
Definition IoPriorityQueue.h:236
void Remove(T *Item)
Definition IoPriorityQueue.h:209
T * Pop()
Definition IoPriorityQueue.h:172
void Reprioritize(T *Item, int32 NewPriority)
Definition IoPriorityQueue.h:230
TIterator CreateIterator(int32 Priority)
Definition IoPriorityQueue.h:204
void Push(T *Item, int32 Priority)
Definition IoPriorityQueue.h:153
bool IsEmpty() const
Definition IoPriorityQueue.h:139
UE_REWRITE auto LowerBoundBy(const RangeType &Range, const ValueType &Value, ProjectionType Projection, SortPredicateType SortPredicate) -> decltype(GetNum(Range))
Definition BinarySearch.h:113
U16 Index
Definition radfft.cpp:71