UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CompactSetBase.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
8
15
17template<typename Allocator>
19{
20public:
22 using SizeType = typename AllocatorType::SizeType;
23
28
36 {
37 return NumElements == 0;
38 }
39
42 {
43 return NumElements;
44 }
45
48 {
49 return MaxElements;
50 }
51
54 {
55 return NumElements;
56 }
57
72
73protected:
75 static constexpr size_t HashCountSize = sizeof(HashCountType);
76 using ElementAllocatorType = typename AllocatorType::template ForElementType<uint8>;
77
78 static_assert(std::is_same_v<SizeType, int32>, "TCompactSet currently only supports 32-bit allocators");
79 static_assert(sizeof(HashCountType) == UE::Core::CompactHashTable::GetMemoryAlignment(), "Hashtable alignment changed, need to make sure HashCountType is stored correctly");
80
82
83 [[nodiscard]] explicit consteval TCompactSetBase(EConstEval)
85 , NumElements(0)
86 , MaxElements(0)
87 {
88 }
89
95
96 /* Calculate the size of the hash table from the number of elements in the set */
101
108
115
116 /* Calculate the size of the hash table from the number of elements in the set */
121
122 /* Calculate bytes required to store the elements, includes any padding required for the hash table */
127
128 /* Get the total memory required for the compact set for the given number of elements and size of the number of hash elements */
133
134 /* Calculate the size of the hash table from the number of elements in the set assuming the default number of hash elements */
139
140 /* The total amount of memory required by the has set to store N elements with a hash table size of Y */
142 {
143 // Given some space in memory and a requested size for hash table, figure out how many elements we can fit in the remaining space
146 const size_t AvailableBytes = TotalBytes - sizeof(HashCountType) - ((size_t)HashCount << TypeShift); // Remove hashtable and HashCount data
147 const size_t MaxElements = AvailableBytes / (Layout.Size + TypeSize); // Calculate the max available ignoring the fact that the hash data has to be aligned
148 const size_t RealAvailableBytes = AlignDown(AvailableBytes - (MaxElements << TypeShift), UE::Core::CompactHashTable::GetMemoryAlignment()); // Remove the max required indexes and align down
149 return FMath::Min<SizeType>(MaxElements, RealAvailableBytes / Layout.Size); // Now we can get the true number of elements we could potentially use within the aligned space
150 }
151
153 {
154 const size_t OldHashCount = MaxElements > 0 ? *(uint32*)(Elements.GetAllocation() + GetElementsSizeInBytes(MaxElements, Layout)) : 0;
155 const size_t OldSize = MaxElements > 0 ? GetTotalMemoryRequiredInBytes(MaxElements, OldHashCount, Layout) : 0;
156
157 const size_t NewHashCount = NewMaxElements > 0 ? GetHashCount(NewMaxElements) : 0;
159 size_t NewSlackSize = 0;
160
162 {
163 NewSlackSize = Elements.CalculateSlackGrow(NewSize, OldSize, 1, Layout.Alignment);
164 }
165 else
166 {
167 NewSlackSize = Elements.CalculateSlackGrow(NewSize, OldSize, 1);
168 }
169
170 if (NewSlackSize == NewSize)
171 {
172 // No need for expensive slack calculations if there is none
173 return NewMaxElements;
174 }
175
176 // Calculate the number of items we can fit in the allotted space
179 {
180 // This can happen if we're basically at the slack limit, when we got to calculate the results, even adding one element tracking index can
181 // cause us to lose space due to alignment changes, in this case we just take the user input as the source of truth
182 return NewMaxElements;
183 }
184
187 {
188 // New Size required to much space. Cut the new hash count in half and restrict the elements to the max for that hash count
190 SlackHashCount /= 2;
191 }
192
195
196 return SlackNumElements;
197 }
198
203
204 // Use this is you'll be keeping the element data
206 {
207 bool bRequiresRehash = false;
208
210 {
211 const size_t OldHashCount = MaxElements > 0 ? *(uint32*)(Elements.GetAllocation() + GetElementsSizeInBytes(MaxElements, Layout)) : 0;
212 const size_t OldSize = MaxElements > 0 ? GetTotalMemoryRequiredInBytes(MaxElements, OldHashCount, Layout) : 0;
213
216
218 {
219 checkf(NewSize >= 0 && NewSize <= MAX_int32, TEXT("Invalid size for TSet[%d]: NewMaxElements[%d] ElementSize[%d] HashCount[%d]"), NewSize, NewMaxElements, Layout.Size, NewHashCount);
220
221 // If preserving then we copy over all the data
223 {
224 Elements.ResizeAllocation(OldSize, NewSize, 1, Layout.Alignment);
225 }
226 else
227 {
228 Elements.ResizeAllocation(OldSize, NewSize, 1);
229 }
230
232
233 // This should always be true since our type size will change on Powerof2 barriers (256, 65536, etc)
235
238
241
242 // Copy hash lookup table (first so to free up the space for the other data to move)
244
245 // Copy hash size + next index table
247 }
248 else
249 {
250 // If not preserving (or shrinking) then we only need to copy the array data
252 {
253 Elements.ResizeAllocation(NumElements * Layout.Size, NewSize, 1, Layout.Alignment);
254 }
255 else
256 {
257 Elements.ResizeAllocation(NumElements * Layout.Size, NewSize, 1);
258 }
259
260 // Update hash size
261 if (NewMaxElements > 0)
262 {
264
266 bRequiresRehash = true;
267 }
268 }
269
271 }
272
273 return bRequiresRehash;
274 }
275
277
280};
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
constexpr T Align(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:18
constexpr T AlignDown(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:34
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
EConstEval
Definition CoreMiscDefines.h:161
@ ConstEval
Definition CoreMiscDefines.h:161
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define MAX_int32
Definition NumericLimits.h:25
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition CompactHashTable.h:350
Definition CompactHashTable.h:283
Definition CompactSetBase.h:19
typename AllocatorType::SizeType SizeType
Definition CompactSetBase.h:22
void ResizeAllocation(const int32 NewMaxElements, const FCompactSetLayout &Layout)
Definition CompactSetBase.h:199
Allocator AllocatorType
Definition CompactSetBase.h:21
UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize(const FCompactSetLayout Layout) const
Definition CompactSetBase.h:63
UE_FORCEINLINE_HINT int32 Max() const
Definition CompactSetBase.h:47
FConstCompactHashTableView GetConstHashTableView(const FCompactSetLayout Layout) const
Definition CompactSetBase.h:109
SizeType MaxElements
Definition CompactSetBase.h:279
static UE_FORCEINLINE_HINT constexpr SizeType GetHashCount(uint32 NumElements)
Definition CompactSetBase.h:117
FCompactHashTableView GetHashTableView(const FCompactSetLayout Layout)
Definition CompactSetBase.h:102
consteval TCompactSetBase(EConstEval)
Definition CompactSetBase.h:83
ElementAllocatorType Elements
Definition CompactSetBase.h:276
UE_FORCEINLINE_HINT const HashCountType * GetHashTableMemory(const FCompactSetLayout Layout) const
Definition CompactSetBase.h:97
static constexpr SizeType GetMaxElementsForAvailableSpace(size_t TotalBytes, uint32 HashCount, uint32 MinElementCount, const FCompactSetLayout Layout)
Definition CompactSetBase.h:141
static UE_FORCEINLINE_HINT constexpr size_t GetElementsSizeInBytes(uint32 NumElements, const FCompactSetLayout Layout)
Definition CompactSetBase.h:123
bool operator==(FIntrusiveUnsetOptionalState Tag) const
Definition CompactSetBase.h:24
typename AllocatorType::template ForElementType< uint8 > ElementAllocatorType
Definition CompactSetBase.h:76
TCompactSetBase(FIntrusiveUnsetOptionalState Tag)
Definition CompactSetBase.h:90
int32 AllocatorCalculateSlackGrow(int32 NewMaxElements, const FCompactSetLayout &Layout) const
Definition CompactSetBase.h:152
static UE_FORCEINLINE_HINT constexpr size_t GetTotalMemoryRequiredInBytes(uint32 NumElements, const FCompactSetLayout Layout)
Definition CompactSetBase.h:135
UE_FORCEINLINE_HINT int32 GetMaxIndex() const
Definition CompactSetBase.h:53
uint32 HashCountType
Definition CompactSetBase.h:74
bool ResizeAllocationPreserveData(const int32 NewMaxElements, const FCompactSetLayout &Layout, bool bPreserve=true)
Definition CompactSetBase.h:205
UE_FORCEINLINE_HINT bool IsEmpty() const
Definition CompactSetBase.h:35
UE_FORCEINLINE_HINT TCompactSetBase()=default
static constexpr size_t HashCountSize
Definition CompactSetBase.h:75
SizeType NumElements
Definition CompactSetBase.h:278
static UE_FORCEINLINE_HINT constexpr size_t GetTotalMemoryRequiredInBytes(uint32 NumElements, uint32 HashCount, const FCompactSetLayout Layout)
Definition CompactSetBase.h:129
UE_FORCEINLINE_HINT int32 Num() const
Definition CompactSetBase.h:41
constexpr size_t GetHashCount(uint32 NumElements)
Definition CompactHashTable.h:75
UE_FORCEINLINE_HINT constexpr uint32 GetTypeShift(uint32 IndexCount)
Definition CompactHashTable.h:59
UE_FORCEINLINE_HINT constexpr size_t GetMemoryRequiredInBytes(uint32 IndexCount, uint32 HashCount)
Definition CompactHashTable.h:64
UE_FORCEINLINE_HINT constexpr size_t GetMemoryAlignment()
Definition CompactHashTable.h:69
UE_FORCEINLINE_HINT constexpr uint32 GetTypeSize(uint32 IndexCount)
Definition CompactHashTable.h:54
Definition CompactSetBase.h:11
int32 Alignment
Definition CompactSetBase.h:13
int32 Size
Definition CompactSetBase.h:12
Definition IntrusiveUnsetOptionalState.h:71
static UE_FORCEINLINE_HINT void * Memmove(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:109
Definition ContainerAllocationPolicies.h:256