UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PsoLruCache.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "Containers/Set.h"
8
9/* Implements a Least Recently Used (LRU) cache.
10 *
11 * @param KeyType The type of cache entry keys.
12 * @param ValueType The type of cache entry values.
13 */
14template<typename KeyType, typename ValueType>
16{
18 struct FCacheEntry
19 {
21 KeyType Key;
22
24 FCacheEntry* LessRecent;
25
27 FCacheEntry* MoreRecent;
28
30 ValueType Value;
31
38 FCacheEntry(const KeyType& InKey, const ValueType& InValue)
39 : Key(InKey)
40 , LessRecent(nullptr)
41 , MoreRecent(nullptr)
42 , Value(InValue)
43 { }
44
46 inline void LinkBefore(FCacheEntry* Other)
47 {
48 LessRecent = Other;
49
50 if (Other != nullptr)
51 {
52 Other->MoreRecent = this;
53 }
54 }
55
57 inline void Unlink()
58 {
59 if (LessRecent != nullptr)
60 {
61 LessRecent->MoreRecent = MoreRecent;
62 }
63
64 if (MoreRecent != nullptr)
65 {
66 MoreRecent->LessRecent = LessRecent;
67 }
68
69 LessRecent = nullptr;
70 MoreRecent = nullptr;
71 }
72 };
73
75 struct FKeyFuncs : public BaseKeyFuncs<FCacheEntry*, KeyType>
76 {
77 inline static const KeyType& GetSetKey(const FCacheEntry* Entry)
78 {
79 return Entry->Key;
80 }
81
82 inline static bool Matches(KeyType A, KeyType B)
83 {
84 return A == B;
85 }
86
87 inline static uint32 GetKeyHash(KeyType Key)
88 {
89 return GetTypeHash(Key);
90 }
91 };
92
93public:
94
97 : LeastRecent(nullptr)
98 , MostRecent(nullptr)
99 , MaxNumElements(0)
100 { }
101
108 : LeastRecent(nullptr)
109 , MostRecent(nullptr)
110 , MaxNumElements(InMaxNumElements)
111 {
113 }
114
117 {
118 Empty();
119 }
120
121public:
122
136 FSetElementId Add(const KeyType& Key, const ValueType& Value)
137 {
138 check(MaxNumElements > 0 && "Cannot add values to zero size FOpenGLLruCache");
139 check(!LookupSet.Contains(Key));
140
141 check(LookupSet.Num() < MaxNumElements);
142 // add new entry
143 FCacheEntry* NewEntry = new FCacheEntry(Key, Value);
144 NewEntry->LinkBefore(MostRecent);
145 MostRecent = NewEntry;
146
147 if (LeastRecent == nullptr)
148 {
149 LeastRecent = NewEntry;
150 }
151 return LookupSet.Add(NewEntry);
152 }
153
161 inline bool Contains(const KeyType& Key) const
162 {
163 return LookupSet.Contains(Key);
164 }
165
173 template<typename Predicate>
174 inline bool ContainsByPredicate(Predicate Pred) const
175 {
176 for (const FCacheEntry* Entry : LookupSet)
177 {
178 if (Pred(Entry->Key, Entry->Value))
179 {
180 return true;
181 }
182 }
183
184 return false;
185 }
186
194 {
196
197 for (FCacheEntry* Entry : LookupSet)
198 {
199 delete Entry;
200 }
201
202 MaxNumElements = InMaxNumElements;
203 LookupSet.Empty(MaxNumElements);
204
205 MostRecent = nullptr;
206 LeastRecent = nullptr;
207 }
208
216 template<typename Predicate>
218 {
219 TArray<ValueType> Result;
220
221 for (const FCacheEntry* Entry : LookupSet)
222 {
223 if (Pred(Entry->Key, Entry->Value))
224 {
225 Result.Add(Entry->Value);
226 }
227 }
228
229 return Result;
230 }
231
239 inline const ValueType* Find(const KeyType& Key) const
240 {
241 FCacheEntry** EntryPtr = LookupSet.Find(Key);
242
243 if (EntryPtr != nullptr)
244 {
245 return &(*EntryPtr)->Value;
246 }
247
248 return nullptr;
249 }
250
258 const ValueType* FindAndTouch(const KeyType& Key)
259 {
260 FCacheEntry** EntryPtr = LookupSet.Find(Key);
261
262 if (EntryPtr == nullptr)
263 {
264 return nullptr;
265 }
266
268
269 return &(*EntryPtr)->Value;
270 }
271
279 template<typename Predicate>
280 const ValueType* FindByPredicate(Predicate Pred) const
281 {
282 for (const FCacheEntry* Entry : LookupSet)
283 {
284 if (Pred(Entry->Key, Entry->Value))
285 {
286 return &Entry->Value;
287 }
288 }
289
290 return nullptr;
291 }
292
300 {
301 for (const FCacheEntry* Entry : LookupSet)
302 {
303 OutKeys.Add(Entry->Key);
304 }
305 }
306
313 inline int32 Max() const
314 {
315 return MaxNumElements;
316 }
317
324 inline int32 Num() const
325 {
326 return LookupSet.Num();
327 }
328
335 void Remove(const KeyType& Key)
336 {
337 FCacheEntry** EntryPtr = LookupSet.Find(Key);
338
339 if (EntryPtr != nullptr)
340 {
342 }
343 }
344
345 bool Remove(const KeyType& Key, ValueType& RemovedValue)
346 {
347 FCacheEntry** EntryPtr = LookupSet.Find(Key);
348
349 if (EntryPtr != nullptr)
350 {
351 RemovedValue = MoveTemp((*EntryPtr)->Value);
353 return true;
354 }
355 return false;
356 }
357
365 template<typename Predicate>
367 {
368 int32 NumRemoved = 0;
369
370 for (const FCacheEntry* Entry : LookupSet)
371 {
372 if (Pred(Entry->Key, Entry->Value))
373 {
374 Remove(Entry);
375 ++NumRemoved;
376 }
377 }
378
379 return NumRemoved;
380 }
381
387 inline ValueType RemoveLeastRecent()
388 {
389 check(LeastRecent);
390 ValueType LeastRecentElement = MoveTemp(LeastRecent->Value);
391 Remove(LeastRecent);
392 return LeastRecentElement;
393 }
394
400 inline const ValueType GetLeastRecent() const
401 {
402 check(LeastRecent);
403 return LeastRecent->Value;
404 }
405
411 inline ValueType RemoveMostRecent()
412 {
413 check(MostRecent);
414 ValueType MostRecentElement = MoveTemp(MostRecent->Value);
415 Remove(MostRecent);
416 return MostRecentElement;
417 }
418
419 inline void MarkAsRecent(const FSetElementId& LRUNode)
420 {
421 MarkAsRecent(*LookupSet[LRUNode]);
422 }
423
424public:
425
431 template<bool Const>
433 {
434 public:
435
437 : CurrentEntry(nullptr)
438 { }
439
440 inline TBaseIterator(const TPsoLruCache& Cache)
441 : CurrentEntry(Cache.MostRecent)
442 { }
443
444 public:
445
447 {
448 Increment();
449 return *this;
450 }
451
452 inline friend bool operator==(const TBaseIterator& Lhs, const TBaseIterator& Rhs)
453 {
454 return Lhs.CurrentEntry == Rhs.CurrentEntry;
455 }
456
457 inline friend bool operator!=(const TBaseIterator& Lhs, const TBaseIterator& Rhs)
458 {
459 return Lhs.CurrentEntry != Rhs.CurrentEntry;
460 }
461
462 ValueType& operator->() const
463 {
464 check(CurrentEntry != nullptr);
465 return CurrentEntry->Value;
466 }
467
468 ValueType& operator*() const
469 {
470 check(CurrentEntry != nullptr);
471 return CurrentEntry->Value;
472 }
473
474 inline explicit operator bool() const
475 {
476 return (CurrentEntry != nullptr);
477 }
478
479 inline bool operator!() const
480 {
481 return !(bool)*this;
482 }
483
484 public:
485
486 inline KeyType& Key() const
487 {
488 check(CurrentEntry != nullptr);
489 return CurrentEntry->Key;
490 }
491
492 inline ValueType& Value() const
493 {
494 check(CurrentEntry != nullptr);
495 return CurrentEntry->Value;
496 }
497
498 protected:
499
500 FCacheEntry* GetCurrentEntry()
501 {
502 return CurrentEntry;
503 }
504
506 {
507 check(CurrentEntry != nullptr);
508 CurrentEntry = CurrentEntry->LessRecent;
509 }
510
511 private:
512
513 FCacheEntry* CurrentEntry;
514 };
515
516
521 : public TBaseIterator<true>
522 {
523 public:
524
527 { }
528
529 inline TConstIterator(const TPsoLruCache& Cache)
530 : TBaseIterator<true>(Cache)
531 { }
532 };
533
534
539 : public TBaseIterator<false>
540 {
541 public:
542
543 inline TIterator()
545 , Cache(nullptr)
546 { }
547
550 , Cache(&InCache)
551 { }
552
555 {
556 check(Cache != nullptr);
557
558 FCacheEntry* MoreRecentEntry = this->GetCurrentEntry();
559 this->Increment();
560 Cache->Remove(MoreRecentEntry);
561 }
562
563 private:
564
565 TPsoLruCache* Cache;
566 };
567
568protected:
569
575 inline void MarkAsRecent(FCacheEntry& Entry)
576 {
577 check(LeastRecent != nullptr);
578 check(MostRecent != nullptr);
579
580 // if entry is least recent and not the only item in the list, make it not least recent
581 if ((&Entry == LeastRecent) && (LeastRecent->MoreRecent != nullptr))
582 {
583 LeastRecent = LeastRecent->MoreRecent;
584 }
585
586 // relink if not already the most recent item
587 if (&Entry != MostRecent)
588 {
589 Entry.Unlink();
590 Entry.LinkBefore(MostRecent);
591 MostRecent = &Entry;
592 }
593 }
594
600 inline void Remove(FCacheEntry* Entry)
601 {
602 if (Entry == nullptr)
603 {
604 return;
605 }
606
607 LookupSet.Remove(Entry->Key);
608
609 if (Entry == LeastRecent)
610 {
611 LeastRecent = Entry->MoreRecent;
612 }
613
614 if (Entry == MostRecent)
615 {
616 MostRecent = Entry->LessRecent;
617 }
618
619 Entry->Unlink();
620 delete Entry;
621 }
622
623private:
624
625 friend TIterator begin(TPsoLruCache& Cache) { return TIterator(Cache); }
626 friend TConstIterator begin(const TPsoLruCache& Cache) { return TConstIterator(Cache); }
627 friend TIterator end(TPsoLruCache& Cache) { return TIterator(); }
628 friend TConstIterator end(const TPsoLruCache& Cache) { return TConstIterator(); }
629
630private:
631
634
636 FCacheEntry* LeastRecent;
637
639 FCacheEntry* MostRecent;
640
642 int32 MaxNumElements;
643};
#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
return true
Definition ExternalRpcRegistry.cpp:601
const bool
Definition NetworkReplayStreaming.h:178
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition SetUtilities.h:95
Definition Array.h:670
Definition PsoLruCache.h:433
FCacheEntry * GetCurrentEntry()
Definition PsoLruCache.h:500
friend bool operator==(const TBaseIterator &Lhs, const TBaseIterator &Rhs)
Definition PsoLruCache.h:452
TBaseIterator()
Definition PsoLruCache.h:436
KeyType & Key() const
Definition PsoLruCache.h:486
TBaseIterator(const TPsoLruCache &Cache)
Definition PsoLruCache.h:440
ValueType & Value() const
Definition PsoLruCache.h:492
void Increment()
Definition PsoLruCache.h:505
ValueType & operator*() const
Definition PsoLruCache.h:468
bool operator!() const
Definition PsoLruCache.h:479
TBaseIterator & operator++()
Definition PsoLruCache.h:446
ValueType & operator->() const
Definition PsoLruCache.h:462
friend bool operator!=(const TBaseIterator &Lhs, const TBaseIterator &Rhs)
Definition PsoLruCache.h:457
Definition PsoLruCache.h:522
TConstIterator(const TPsoLruCache &Cache)
Definition PsoLruCache.h:529
TConstIterator()
Definition PsoLruCache.h:525
Definition PsoLruCache.h:540
void RemoveCurrentAndIncrement()
Definition PsoLruCache.h:554
TIterator(TPsoLruCache &InCache)
Definition PsoLruCache.h:548
TIterator()
Definition PsoLruCache.h:543
Definition PsoLruCache.h:16
ValueType RemoveMostRecent()
Definition PsoLruCache.h:411
ValueType RemoveLeastRecent()
Definition PsoLruCache.h:387
const ValueType * FindAndTouch(const KeyType &Key)
Definition PsoLruCache.h:258
void MarkAsRecent(FCacheEntry &Entry)
Definition PsoLruCache.h:575
void Remove(const KeyType &Key)
Definition PsoLruCache.h:335
friend TConstIterator begin(const TPsoLruCache &Cache)
Definition PsoLruCache.h:626
bool Contains(const KeyType &Key) const
Definition PsoLruCache.h:161
TPsoLruCache(int32 InMaxNumElements)
Definition PsoLruCache.h:107
int32 Max() const
Definition PsoLruCache.h:313
friend TIterator begin(TPsoLruCache &Cache)
Definition PsoLruCache.h:625
TPsoLruCache()
Definition PsoLruCache.h:96
int32 RemoveByPredicate(Predicate Pred)
Definition PsoLruCache.h:366
void Remove(FCacheEntry *Entry)
Definition PsoLruCache.h:600
void GetKeys(TArray< KeyType > &OutKeys) const
Definition PsoLruCache.h:299
const ValueType GetLeastRecent() const
Definition PsoLruCache.h:400
int32 Num() const
Definition PsoLruCache.h:324
bool Remove(const KeyType &Key, ValueType &RemovedValue)
Definition PsoLruCache.h:345
friend TConstIterator end(const TPsoLruCache &Cache)
Definition PsoLruCache.h:628
void Empty(int32 InMaxNumElements=0)
Definition PsoLruCache.h:193
TArray< ValueType > FilterByPredicate(Predicate Pred) const
Definition PsoLruCache.h:217
bool ContainsByPredicate(Predicate Pred) const
Definition PsoLruCache.h:174
FSetElementId Add(const KeyType &Key, const ValueType &Value)
Definition PsoLruCache.h:136
~TPsoLruCache()
Definition PsoLruCache.h:116
const ValueType * FindByPredicate(Predicate Pred) const
Definition PsoLruCache.h:280
void MarkAsRecent(const FSetElementId &LRUNode)
Definition PsoLruCache.h:419
friend TIterator end(TPsoLruCache &Cache)
Definition PsoLruCache.h:627
const ValueType * Find(const KeyType &Key) const
Definition PsoLruCache.h:239
@ false
Definition radaudio_common.h:23
Definition SetUtilities.h:23
KeyType KeyType
Definition SetUtilities.h:24