UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
StripedMap.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
7#include "Containers/Map.h"
8#include "Async/SharedLock.h"
9#include "Async/SharedMutex.h"
10#include "Async/UniqueLock.h"
11#include "HAL/PlatformTLS.h"
13#include "Misc/ScopeRWLock.h"
14
24
34
35// Use FTransactionallySafeRWLock by default for now because there is no transactionally-safe
36// FSharedMutex and a bug in FSharedMutex is currently causing deadlocks.
38
54template <int32 BucketCount, typename BaseMapType, typename KeyType, typename ValueType, typename SetAllocator, typename KeyFuncs, typename LockingPolicy>
56{
57 static_assert(BucketCount > 0, "The BucketCount needs to be at least 1");
58public:
60 typedef typename BaseMapType::KeyConstPointerType KeyConstPointerType;
61 typedef KeyFuncs KeyFuncsType;
62
63protected:
65 {
66 typename LockingPolicy::MutexType Mutex;
68 std::atomic<uint32> SharedLockCount = 0;
69 };
70
88
106
107#define WITH_STRIPEDMAP_DEBUGGABLE_MUTEX 0
108#if WITH_STRIPEDMAP_DEBUGGABLE_MUTEX
109 typedef FDebuggableMutex MutexType;
110 typedef FDebuggableExclusiveLock ExclusiveLockType;
111 typedef FDebuggableSharedLock SharedLockType;
112#else
113 typedef typename LockingPolicy::MutexType MutexType;
114 typedef typename LockingPolicy::ExclusiveLockType ExclusiveLockType;
115 typedef typename LockingPolicy::SharedLockType SharedLockType;
116#endif
117#undef WITH_STRIPEDMAP_DEBUGGABLE_MUTEX
118
119 struct FBucket
120 {
123 } Buckets[BucketCount];
124
126 {
127 if constexpr (BucketCount == 1)
128 {
129 return 0;
130 }
131 else
132 {
133 return Hash % BucketCount;
134 }
135 }
136
137 template <typename FunctionType>
138 decltype(auto) ApplyUnlockedByHash(uint32 InHash, FunctionType&& InFunction)
139 {
141 }
142
143 template <typename FunctionType>
144 decltype(auto) ApplyUnlocked(KeyConstPointerType InKey, FunctionType&& InFunction)
145 {
146 return ApplyUnlockedByHash(KeyFuncsType::GetKeyHash(InKey), Forward<FunctionType>(InFunction));
147 }
148
149 template <typename LockType, typename FunctionType>
150 decltype(auto) ApplyByHash(uint32 InHash, FunctionType&& InFunction) const
151 {
152 const FBucket& Bucket = Buckets[GetBucketIndex(InHash)];
153
154 LockType ScopeLock(Bucket.Lock);
155 return InFunction(InHash, Bucket.Map);
156 }
157
158 template <typename LockType, typename FunctionType>
159 decltype(auto) Apply(KeyConstPointerType InKey, FunctionType&& InFunction) const
160 {
161 return ApplyByHash<LockType>(KeyFuncsType::GetKeyHash(InKey), Forward<FunctionType>(InFunction));
162 }
163
164 template <typename LockType, typename FunctionType>
165 decltype(auto) ApplyByHash(uint32 InHash, FunctionType&& InFunction)
166 {
168
169 LockType ScopeLock(Bucket.Lock);
170 return InFunction(InHash, Bucket.Map);
171 }
172
173 template <typename LockType, typename FunctionType>
174 decltype(auto) Apply(KeyConstPointerType InKey, FunctionType&& InFunction)
175 {
176 return ApplyByHash<LockType>(KeyFuncsType::GetKeyHash(InKey), Forward<FunctionType>(InFunction));
177 }
178
179 template <typename FunctionType>
184
185 template <typename FunctionType>
190
191 template <typename FunctionType>
192 decltype(auto) Read(KeyConstPointerType InKey, FunctionType&& InFunction)
193 {
195 }
196
197 template <typename FunctionType>
202
203 template <typename FunctionType>
204 decltype(auto) Read(KeyConstPointerType InKey, FunctionType&& InFunction) const
205 {
207 }
208
209 template <typename FunctionType>
214
215 template <typename FunctionType>
216 void ForEachMap(FunctionType&& InFunction)
217 {
218 for (FBucket& Bucket : Buckets)
219 {
220 ExclusiveLockType ScopeLock(Bucket.Lock);
221 InFunction(Bucket.Map);
222 }
223 }
224
225 template <typename FunctionType>
226 void ForEachMap(FunctionType&& InFunction) const
227 {
228 for (const FBucket& Bucket : Buckets)
229 {
230 SharedLockType ScopeLock(Bucket.Lock);
231 InFunction(Bucket.Map);
232 }
233 }
234
235public:
245 {
246 return Read(InKey, [&InKey](uint32 Hash, const MapType& Map)
247 {
248 const ValueType* Result = Map.FindByHash(Hash, InKey);
249 if (Result)
250 {
251 return *Result;
252 }
253
254 return ValueType();
255 }
256 );
257 }
258
269 template <typename FunctionType>
271 {
272 return Read(InKey, [&InKey, &InFunction](uint32 Hash, const MapType& Map)
273 {
274 const ValueType* Result = Map.FindByHash(Hash, InKey);
275 if (Result)
276 {
277 InFunction(*Result);
278 return true;
279 }
280
281 return false;
282 }
283 );
284 }
285
293 template <typename UpdateFunctionType>
295 {
297 {
298 ValueType* Result = Map.FindByHash(Hash, InKey);
299 if (Result)
300 {
301 InUpdateFunction(*Result);
302 return true;
303 }
304
305 return false;
306 }
307 );
308 }
309
317 {
318 return Read(InKey, [&InKey](uint32 Hash, const MapType& Map) { return Map.ContainsByHash(Hash, InKey); });
319 }
320
327 template <typename InitKeyType = KeyType, typename InitValueType = ValueType>
329 {
330 return Write(InKey, [&InKey, &InValue](uint32 Hash, MapType& Map)
331 {
333 }
334 );
335 }
336
343 void Add(const KeyType& InKey, const ValueType& InValue)
344 {
345 return Emplace(InKey, InValue);
346 }
347
354 void Add(const KeyType& InKey, ValueType&& InValue)
355 {
357 }
358
365 void Add(KeyType&& InKey, const ValueType& InValue)
366 {
368 }
369
376 void Add(KeyType&& InKey, ValueType&& InValue)
377 {
379 }
380
388 template <typename ProduceFunctionType>
390 {
391 return ApplyUnlocked(InKey,
392 [this, &InKey, &InProduceFunction](uint32 Hash, FBucket& Bucket)
393 {
394 {
396 const ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
397 if (Result)
398 {
399 return *Result;
400 }
401 }
402
404 ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
405 if (Result)
406 {
407 return *Result;
408 }
409
410 return Bucket.Map.AddByHash(Hash, InKey, InProduceFunction());
411 });
412 }
413
421 template <typename ProduceFunctionType, typename ApplyFunctionType>
423 {
426 {
427 {
429 const ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
430 if (Result)
431 {
432 InApplyFunction(*Result);
433 return;
434 }
435 }
436
438 ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
439 if (Result)
440 {
441 InApplyFunction(*Result);
442 return;
443 }
444
445 InApplyFunction(Bucket.Map.AddByHash(Hash, InKey, InProduceFunction()));
446 });
447 }
448
457 template <typename TryProduceFunctionType, typename ApplyFunctionType>
459 {
460 return ApplyUnlocked(InKey,
462 {
463 {
465 const ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
466 if (Result)
467 {
468 InApplyFunction(*Result);
469 return true;
470 }
471 }
472
474 const ValueType* Result = Bucket.Map.FindByHash(Hash, InKey);
475 if (Result)
476 {
477 InApplyFunction(*Result);
478 return true;
479 }
480
481 ValueType Value;
483 {
484 InApplyFunction(Bucket.Map.AddByHash(Hash, InKey, MoveTemp(Value)));
485 return true;
486 }
487
488 return false;
489 });
490 }
491
499 template <typename ProduceFunctionType, typename ApplyFunctionType>
501 {
503 {
504 ValueType* Result = Map.FindByHash(Hash, InKey);
505 if (Result)
506 {
507 InApplyFunction(*Result);
508 }
509 else
510 {
512 }
513 });
514 }
515
524 template <typename TryProduceFunctionType, typename ApplyFunctionType>
526 {
528 {
529 ValueType* Result = Map.FindByHash(Hash, InKey);
530 if (Result)
531 {
532 InApplyFunction(*Result);
533 return true;
534 }
535
536 ValueType Value;
538 {
540 return true;
541 }
542
543 return false;
544 });
545 }
546
554 {
555 return Write(InKey, [&InKey](uint32 Hash, MapType& Map) { return Map.RemoveByHash(Hash, InKey); });
556 }
557
563
571 template <typename PredicateType>
573 {
574 return Write(InKey,
576 {
577 FSetElementId ElementId = Map.FindIdByHash(Hash, InKey);
578 if (ElementId.IsValidId() && InPredicate(Map.Get(ElementId).Value))
579 {
580 Map.Remove(ElementId);
581 return 1;
582 }
583
584 return 0;
585 });
586 }
587
594 template <typename PredicateType>
596 {
600 {
601 for (auto It = Map.CreateIterator(); It; ++It)
602 {
603 if (InPredicate(*It))
604 {
605 It.RemoveCurrent();
606 RemovedCount++;
607 }
608 }
609 }
610 );
611 return RemovedCount;
612 }
613
623 {
625 {
626 return Map.RemoveAndCopyValueByHash(Hash, InKey, OutRemovedValue);
627 });
628 }
629
639 {
640 return Write(InKey, [&InKey](uint32 Hash, MapType& Map)
641 {
642 return Map.FindAndRemoveChecked(InKey);
643 }
644 );
645 }
646
648 void Empty()
649 {
651 [](MapType& Map)
652 {
653 Map.Empty();
654 }
655 );
656 }
657
659 void Reset()
660 {
662 [](MapType& Map)
663 {
664 Map.Reset();
665 }
666 );
667 }
668
670 void Shrink()
671 {
673 [](MapType& Map)
674 {
675 Map.Shrink();
676 }
677 );
678 }
679
681 void Compact()
682 {
684 [](MapType& Map)
685 {
686 Map.Compact();
687 }
688 );
689 }
690
692 [[nodiscard]] int32 Num() const
693 {
694 int32 Count = 0;
696 [&Count](const MapType& Map)
697 {
698 Count += Map.Num();
699 }
700 );
701
702 return Count;
703 }
704
710 template <typename FunctionType>
711 void ForEach(FunctionType&& InFunction)
712 {
715 {
716 for (auto& Item : Map)
717 {
718 InFunction(Item);
719 }
720 }
721 );
722 }
723
729 template <typename FunctionType>
730 void ForEach(FunctionType&& InFunction) const
731 {
733 [&InFunction](const MapType& Map)
734 {
735 for (const auto& Item : Map)
736 {
737 InFunction(Item);
738 }
739 }
740 );
741 }
742
749 template<typename Allocator>
751 {
752 OutKeys.Reset();
754 ForEach(
755 [&OutKeys, &VisitedKeys](const auto& Pair)
756 {
757 if (!VisitedKeys.Contains(Pair.Key))
758 {
759 OutKeys.Add(Pair.Key);
760 VisitedKeys.Add(Pair.Key);
761 }
762 }
763 );
764 return OutKeys.Num();
765 }
766};
767
771template <
772 int32 BucketCount,
773 typename KeyType,
774 typename ValueType,
775 typename SetAllocator = FDefaultSetAllocator,
778>
779class TStripedMap : public TStripedMapBase<BucketCount, TMap<KeyType, ValueType, SetAllocator, KeyFuncs>, KeyType, ValueType, SetAllocator, KeyFuncs, LockingPolicy>
780{
781public:
783};
784
788template <
789 int32 BucketCount,
790 typename KeyType,
791 typename ValueType,
792 typename SetAllocator = FDefaultSetAllocator,
795>
796class TStripedMultiMap : public TStripedMapBase<BucketCount, TMultiMap<KeyType, ValueType, SetAllocator, KeyFuncs>, KeyType, ValueType, SetAllocator, KeyFuncs, LockingPolicy>
797{
798public:
800
808 template<typename Allocator>
813};
#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
FTransactionallySafeStripedMapLockingPolicy FDefaultStripedMapLockingPolicy
Definition StripedMap.h:37
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTempIfPossible(T &&Obj) noexcept
Definition UnrealTemplate.h:538
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 ContainerAllocationPolicies.h:1660
Definition SetUtilities.h:95
UE_FORCEINLINE_HINT bool IsValidId() const
Definition SetUtilities.h:101
Definition Array.h:670
Definition StripedMap.h:56
LockingPolicy::SharedLockType SharedLockType
Definition StripedMap.h:115
bool RemoveAndCopyValue(KeyConstPointerType InKey, ValueType &OutRemovedValue)
Definition StripedMap.h:622
void Add(KeyType &&InKey, const ValueType &InValue)
Definition StripedMap.h:365
void Shrink()
Definition StripedMap.h:670
int32 Remove(KeyConstPointerType InKey)
Definition StripedMap.h:553
decltype(auto) Read(KeyConstPointerType InKey, FunctionType &&InFunction) const
Definition StripedMap.h:204
decltype(auto) ApplyUnlockedByHash(uint32 InHash, FunctionType &&InFunction)
Definition StripedMap.h:138
int32 RemoveByHash(uint32 InKeyHash, KeyConstPointerType InKey)
Definition StripedMap.h:559
decltype(auto) ReadByHash(uint32 InHash, KeyConstPointerType InKey, FunctionType &&InFunction) const
Definition StripedMap.h:210
void Add(KeyType &&InKey, ValueType &&InValue)
Definition StripedMap.h:376
ValueType FindAndRemoveChecked(KeyConstPointerType InKey)
Definition StripedMap.h:638
BaseMapType::KeyConstPointerType KeyConstPointerType
Definition StripedMap.h:60
ValueType FindRef(KeyConstPointerType InKey) const
Definition StripedMap.h:244
struct TStripedMapBase::FBucket Buckets[BucketCount]
void ForEach(FunctionType &&InFunction)
Definition StripedMap.h:711
ValueType FindOrProduce(const KeyType &InKey, ProduceFunctionType &&InProduceFunction)
Definition StripedMap.h:389
void Emplace(InitKeyType &&InKey, InitValueType &&InValue)
Definition StripedMap.h:328
KeyFuncs KeyFuncsType
Definition StripedMap.h:61
decltype(auto) ReadByHash(uint32 InHash, KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:198
void ForEach(FunctionType &&InFunction) const
Definition StripedMap.h:730
void FindOrProduceAndApplyForWrite(const KeyType &InKey, ProduceFunctionType &&InProduceFunction, ApplyFunctionType &&InApplyFunction)
Definition StripedMap.h:500
decltype(auto) Apply(KeyConstPointerType InKey, FunctionType &&InFunction) const
Definition StripedMap.h:159
bool FindOrTryProduceAndApplyForWrite(const KeyType &InKey, TryProduceFunctionType &&InTryProduceFunction, ApplyFunctionType &&InApplyFunction)
Definition StripedMap.h:525
decltype(auto) Write(KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:180
void ForEachMap(FunctionType &&InFunction)
Definition StripedMap.h:216
void ForEachMap(FunctionType &&InFunction) const
Definition StripedMap.h:226
decltype(auto) ApplyUnlocked(KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:144
decltype(auto) Apply(KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:174
void Empty()
Definition StripedMap.h:648
int32 GetKeys(TArray< KeyType, Allocator > &OutKeys) const
Definition StripedMap.h:750
void Compact()
Definition StripedMap.h:681
decltype(auto) ApplyByHash(uint32 InHash, FunctionType &&InFunction) const
Definition StripedMap.h:150
LockingPolicy::MutexType MutexType
Definition StripedMap.h:113
BaseMapType MapType
Definition StripedMap.h:59
int32 RemoveIf(PredicateType &&InPredicate)
Definition StripedMap.h:595
bool FindAndApply(KeyConstPointerType InKey, UpdateFunctionType &&InUpdateFunction)
Definition StripedMap.h:294
int32 Num() const
Definition StripedMap.h:692
bool FindAndApply(KeyConstPointerType InKey, FunctionType &&InFunction) const
Definition StripedMap.h:270
void Reset()
Definition StripedMap.h:659
decltype(auto) WriteByHash(uint32 InHash, KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:186
void Add(const KeyType &InKey, ValueType &&InValue)
Definition StripedMap.h:354
void FindOrProduceAndApply(const KeyType &InKey, ProduceFunctionType &&InProduceFunction, ApplyFunctionType &&InApplyFunction)
Definition StripedMap.h:422
LockingPolicy::ExclusiveLockType ExclusiveLockType
Definition StripedMap.h:114
bool Contains(KeyConstPointerType InKey) const
Definition StripedMap.h:316
decltype(auto) ApplyByHash(uint32 InHash, FunctionType &&InFunction)
Definition StripedMap.h:165
void Add(const KeyType &InKey, const ValueType &InValue)
Definition StripedMap.h:343
uint32 GetBucketIndex(uint32 Hash) const
Definition StripedMap.h:125
decltype(auto) Read(KeyConstPointerType InKey, FunctionType &&InFunction)
Definition StripedMap.h:192
int32 RemoveIf(KeyConstPointerType InKey, PredicateType &&InPredicate)
Definition StripedMap.h:572
bool FindOrTryProduceAndApply(const KeyType &InKey, TryProduceFunctionType &&InTryProduceFunction, ApplyFunctionType &&InApplyFunction)
Definition StripedMap.h:458
Definition StripedMap.h:780
Definition StripedMap.h:797
void MultiFind(typename Super::KeyConstPointerType InKey, TArray< ValueType, Allocator > &OutValues, bool bMaintainOrder=false) const
Definition StripedMap.h:809
Definition CriticalSection.h:14
Definition SharedMutex.h:22
Definition ScopeRWLock.h:21
Definition SharedLock.h:22
Definition UniqueLock.h:20
Definition ScopeRWLock.h:60
FNameFuncs< typename TGetKeyType< MapType >::Type > KeyFuncs
Definition PerPlatformProperties.h:107
static uint32 GetCurrentThreadId(void)
Definition AndroidPlatformTLS.h:20
Definition StripedMap.h:19
UE::FSharedMutex MutexType
Definition StripedMap.h:20
UE::TUniqueLock< UE::FSharedMutex > ExclusiveLockType
Definition StripedMap.h:21
UE::TSharedLock< UE::FSharedMutex > SharedLockType
Definition StripedMap.h:22
UE::TReadScopeLock< MutexType > SharedLockType
Definition StripedMap.h:32
FTransactionallySafeRWLock MutexType
Definition StripedMap.h:30
UE::TWriteScopeLock< MutexType > ExclusiveLockType
Definition StripedMap.h:31
Definition Map.h:111
Definition StripedMap.h:120
MutexType Lock
Definition StripedMap.h:121
MapType Map
Definition StripedMap.h:122
FDebuggableMutex & DebuggableMutex
Definition StripedMap.h:91
LockingPolicy::ExclusiveLockType InnerLock
Definition StripedMap.h:92
FDebuggableExclusiveLock(FDebuggableMutex &InDebuggableMutex)
Definition StripedMap.h:93
~FDebuggableExclusiveLock()
Definition StripedMap.h:101
Definition StripedMap.h:65
uint32 ExclusiveLockOwnerThreadId
Definition StripedMap.h:67
std::atomic< uint32 > SharedLockCount
Definition StripedMap.h:68
LockingPolicy::MutexType Mutex
Definition StripedMap.h:66
Definition StripedMap.h:72
FDebuggableMutex & DebuggableMutex
Definition StripedMap.h:73
~FDebuggableSharedLock()
Definition StripedMap.h:83
LockingPolicy::SharedLockType InnerLock
Definition StripedMap.h:74
FDebuggableSharedLock(FDebuggableMutex &InDebuggableMutex)
Definition StripedMap.h:75