UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
HashMappedArray.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc.All Rights Reserved.
2#pragma once
3
4#include "Containers/HashTable.h"
5
6namespace Chaos::Private
7{
8 // Default traits for THashMappedArray that works for all ID/Element pairs where the
9 // ID has a MurmurFinalize32 implementation and we can compare equality of Elements and IDs.
10 template<typename TIDType, typename TElementType>
12 {
15
16 // Hash the ID to a 32 bit unsigned int for use with FHashTable
17 static uint32 GetIDHash(const FIDType& ID)
18 {
19 return MurmurFinalize32(ID);
20 }
21
22 static FIDType GetElementID(const FElementType& Element)
23 {
24 return FIDType(Element);
25 }
26 };
27
48 template<typename TIDType, typename TElementType, typename TTraits = THashMappedArrayTraits<TIDType, TElementType>>
50 {
51 public:
54 using FTraits = TTraits;
57
58 // Initialize the hash table. InHashSize must be a power of two (asserted)
60 : HashTable(InHashSize)
61 {
62 }
63
64 // Clear the hash map and reserve space for the specified number of elements (will not shrink)
66 {
67 HashTable.Clear();
68 HashTable.Resize(InReserveElements);
69 Elements.Reset(InReserveElements);
70 }
71
72 // Try to add an element with the specified ID to the map. Does nothing if an Element with the same ID is already in the map.
73 // Returns true if the element was added, false if the ID already existed.
74 FORCEINLINE bool TryAdd(const FIDType ID, const FElementType& Element)
75 {
76 if (Find(ID) == nullptr)
77 {
78 Add(ID, Element);
79 return true;
80 }
81 return false;
82 }
83
84 // Try to add an element with the specified ID to the map. Does nothing if an Element with the same ID is already in the map.
85 // Returns true if the element was added, false if the ID already existed.
86 template <typename... ArgsType>
87 FORCEINLINE bool TryEmplace(const FIDType ID, ArgsType&&... Args)
88 {
89 if (Find(ID) == nullptr)
90 {
91 Emplace(ID, Forward<ArgsType>(Args)...);
92 return true;
93 }
94 return false;
95 }
96
97 // Add an element with the specified ID to the map. Asserts if an Element with the same ID is already in the map.
98 FORCEINLINE void Add(const FIDType ID, const FElementType& Element)
99 {
100 checkSlow(Find(ID) == nullptr);
101
102 const int32 Index = Elements.Add(Element);
103 const FHashType Key = FTraits::GetIDHash(ID);
104
105 HashTable.Add(Key, Index);
106 }
107
108 // Add an element with the specified ID to the map.
109 // NOTE: since your element type will also need to contain the ID, you usually have to pass the ID twice
110 // to emplace, which is a little annoying, but shouldn't affect much.
111 template <typename... ArgsType>
112 FORCEINLINE void Emplace(const FIDType ID, ArgsType&&... Args)
113 {
114 checkSlow(Find(ID) == nullptr);
115
116 const int32 Index = Elements.Emplace(Forward<ArgsType>(Args)...);
117 const FHashType Key = FTraits::GetIDHash(ID);
118
119 HashTable.Add(Key, Index);
120 }
121
122 void Remove(const FIDType ID)
123 {
124 const FHashType Key = FTraits::GetIDHash(ID);
125 for (uint32 Index = HashTable.First(Key); HashTable.IsValid(Index); Index = HashTable.Next(Index))
126 {
127 if (FTraits::GetElementID(Elements[Index]) == ID)
128 {
129 const uint32 LastElemIndex = Elements.Num() - 1;
130
131 // Remove the key/index from the hash table
132 HashTable.Remove(Key, Index);
133
134 // If this is the last element in the array (or if there's only one) then
135 // no need for fancy swaps.
136 if (Index == LastElemIndex)
137 {
138 Elements.RemoveAt(Index);
139 }
140
141 // If this is not the last element in the array, swap with the last element
142 // and fix up the hash table
143 else
144 {
145 const FIDType LastElemID = FTraits::GetElementID(Elements[LastElemIndex]);
146 const FHashType LastElemKey = FTraits::GetIDHash(LastElemID);
147
148 // Remove the last element's key/index from the hash table
149 HashTable.Remove(LastElemKey, LastElemIndex);
150
151 // Remove the element we want to remove, swapping it with the last element
152 Elements.RemoveAtSwap(Index);
153
154 // Re-add the last element's key, reusing the index of the element we just removed
155 HashTable.Add(LastElemKey, Index);
156 }
157
158 break;
159 }
160 }
161 }
162
163 // Find the element with the specified ID. Roughly O(Max(1,N/M)) for N elements with a hash table of size M
164 const FElementType* Find(const FIDType ID) const
165 {
166 return const_cast<FType*>(this)->Find(ID);
167 }
168
169 // Find the element with the specified ID. Roughly O(Max(1,N/M)) for N elements with a hash table of size M
171 {
172 const FHashType Key = FTraits::GetIDHash(ID);
173 for (uint32 Index = HashTable.First(Key); HashTable.IsValid(Index); Index = HashTable.Next(Index))
174 {
175 if (FTraits::GetElementID(Elements[Index]) == ID)
176 {
177 return &Elements[Index];
178 }
179 }
180 return nullptr;
181 }
182
183 // The number of elements that have been added to the map
184 int32 Num() const
185 {
186 return Elements.Num();
187 }
188
189 // Get the element at ElementIndex (indexed by order in which they were added)
190 FElementType& At(const int32 ElementIndex)
191 {
192 return Elements[ElementIndex];
193 }
194
195 // Get the element at ElementIndex (indexed by order in which they were added)
196 const FElementType& At(const int32 ElementIndex) const
197 {
198 return Elements[ElementIndex];
199 }
200
201 // Move the array elements into an external array and reset
203 {
204 HashTable.Clear();
205 return MoveTemp(Elements);
206 }
207
208
209 private:
210 FHashTable HashTable;
211 TArray<FElementType> Elements;
212 };
213
214}
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define checkSlow(expr)
Definition AssertionMacros.h:332
uint32 MurmurFinalize32(uint32 Hash)
Definition HashTable.h:23
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
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 HashMappedArray.h:50
const FElementType * Find(const FIDType ID) const
Definition HashMappedArray.h:164
FORCEINLINE void Emplace(const FIDType ID, ArgsType &&... Args)
Definition HashMappedArray.h:112
uint32 FHashType
Definition HashMappedArray.h:55
THashMappedArray(const int32 InHashSize)
Definition HashMappedArray.h:59
TIDType FIDType
Definition HashMappedArray.h:52
TTraits FTraits
Definition HashMappedArray.h:54
int32 Num() const
Definition HashMappedArray.h:184
FORCEINLINE bool TryAdd(const FIDType ID, const FElementType &Element)
Definition HashMappedArray.h:74
const FElementType & At(const int32 ElementIndex) const
Definition HashMappedArray.h:196
void Remove(const FIDType ID)
Definition HashMappedArray.h:122
FElementType & At(const int32 ElementIndex)
Definition HashMappedArray.h:190
FORCEINLINE bool TryEmplace(const FIDType ID, ArgsType &&... Args)
Definition HashMappedArray.h:87
void Reset(const int32 InReserveElements)
Definition HashMappedArray.h:65
FORCEINLINE void Add(const FIDType ID, const FElementType &Element)
Definition HashMappedArray.h:98
TArray< FElementType > ExtractElements()
Definition HashMappedArray.h:202
FElementType * Find(const FIDType ID)
Definition HashMappedArray.h:170
Definition HashTable.h:210
bool IsValid(uint32 Index) const
Definition HashTable.h:409
void Clear()
Definition HashTable.h:350
CORE_API void Resize(uint32 NewIndexSize)
Definition HashTable.cpp:7
void Remove(uint32 Key, uint32 Index)
Definition HashTable.h:437
void Add(uint32 Key, uint32 Index)
Definition HashTable.h:414
uint32 First(uint32 Key) const
Definition HashTable.h:395
uint32 Next(uint32 Index) const
Definition HashTable.h:402
Definition Array.h:670
Definition BodyInstance.h:90
@ Add
Definition PendingSpatialData.h:18
U16 Index
Definition radfft.cpp:71
Definition HashMappedArray.h:12
static uint32 GetIDHash(const FIDType &ID)
Definition HashMappedArray.h:17
static FIDType GetElementID(const FElementType &Element)
Definition HashMappedArray.h:22
TIDType FIDType
Definition HashMappedArray.h:13
Definition ElementType.h:30