15#if JPH_DEFAULT_ALLOCATE_ALIGNMENT < 16
26 mObjectStoreSizeBytes = inObjectStoreSizeBytes;
27#if JPH_DEFAULT_ALLOCATE_ALIGNMENT < 16
28 mObjectStore =
reinterpret_cast<uint8 *
>(JPH::AlignedAllocate(inObjectStoreSizeBytes, 16));
30 mObjectStore =
reinterpret_cast<uint8 *
>(JPH::Allocate(inObjectStoreSizeBytes));
46 if (mWriteOffset.load(memory_order_relaxed) >= mObjectStoreSizeBytes)
50 uint32 begin = mWriteOffset.fetch_add(inBlockSize, memory_order_relaxed);
51 uint32 end = min(begin + inBlockSize, mObjectStoreSizeBytes);
61 begin = min(begin, mObjectStoreSizeBytes);
72 const uint8 *data =
reinterpret_cast<const uint8 *
>(inData);
73 JPH_ASSERT(data >= mObjectStore && data < mObjectStore + mObjectStoreSizeBytes);
74 return uint32(data - mObjectStore);
81 return reinterpret_cast<T *
>(mObjectStore + inOffset);
89 mAllocator(inAllocator),
90 mBlockSize(inBlockSize)
98 uint32 alignment_mask = inAlignment - 1;
99 uint32 alignment = (inAlignment - (mBegin & alignment_mask)) & alignment_mask;
102 if (mEnd - mBegin < inSize + alignment)
105 mAllocator.
Allocate(mBlockSize, mBegin, mEnd);
108 alignment = (inAlignment - (mBegin & alignment_mask)) & alignment_mask;
111 if (mEnd - mBegin < inSize + alignment)
117 outWriteOffset = mBegin;
126template <
class Key,
class Value>
132 mNumBuckets = inMaxBuckets;
133 mMaxBuckets = inMaxBuckets;
135#if JPH_DEFAULT_ALLOCATE_ALIGNMENT < 16
136 mBuckets =
reinterpret_cast<atomic<uint32> *
>(
AlignedAllocate(inMaxBuckets *
sizeof(atomic<uint32>), 16));
138 mBuckets =
reinterpret_cast<atomic<uint32> *
>(
Allocate(inMaxBuckets *
sizeof(atomic<uint32>)));
144template <
class Key,
class Value>
147#if JPH_DEFAULT_ALLOCATE_ALIGNMENT < 16
154template <
class Key,
class Value>
157#ifdef JPH_ENABLE_ASSERTS
163 static_assert(
sizeof(atomic<uint32>) ==
sizeof(
uint32));
166 const uint32 *end = start + mNumBuckets;
175template <
class Key,
class Value>
182 mNumBuckets = inNumBuckets;
185template <
class Key,
class Value>
186template <
class... Params>
190 JPH_ASSERT(Find(inKey, inKeyHash) ==
nullptr);
200#ifdef JPH_ENABLE_ASSERTS
202 mNumKeyValues.fetch_add(1, memory_order_relaxed);
206 KeyValue *kv = mAllocator.template FromOffset<KeyValue>(write_offset);
209 memset(kv, 0xcd, size);
212 new (&kv->mValue) Value(std::forward<Params>(inConstructorParams)...);
215 atomic<uint32> &offset = mBuckets[inKeyHash & (mNumBuckets - 1)];
218 uint32 old_offset = offset.load(memory_order_relaxed);
221 kv->mNextOffset = old_offset;
222 if (offset.compare_exchange_weak(old_offset, write_offset, memory_order_release))
229template <
class Key,
class Value>
233 uint32 offset = mBuckets[inKeyHash & (mNumBuckets - 1)].load(memory_order_acquire);
234 while (offset != cInvalidHandle)
237 const KeyValue *kv = mAllocator.template FromOffset<const KeyValue>(offset);
238 if (kv->mKey == inKey)
240 offset = kv->mNextOffset;
247template <
class Key,
class Value>
250 return mAllocator.ToOffset(inKeyValue);
253template <
class Key,
class Value>
256 return mAllocator.template FromOffset<const KeyValue>(inHandle);
259template <
class Key,
class Value>
262 for (
const atomic<uint32> *bucket = mBuckets; bucket < mBuckets + mNumBuckets; ++bucket)
265 while (offset != cInvalidHandle)
267 const KeyValue *kv = mAllocator.template FromOffset<const KeyValue>(offset);
269 offset = kv->mNextOffset;
274template <
class Key,
class Value>
278 Iterator it {
this, 0, mBuckets[0] };
281 if (it.mOffset == cInvalidHandle)
287template <
class Key,
class Value>
290 return {
this, mNumBuckets, cInvalidHandle };
293template <
class Key,
class Value>
298 return *
mMap->mAllocator.template FromOffset<KeyValue>(
mOffset);
301template <
class Key,
class Value>
309 const KeyValue *kv = mMap->mAllocator.template FromOffset<const KeyValue>(mOffset);
310 mOffset = kv->mNextOffset;
320 if (mBucket >= mMap->mNumBuckets)
324 mOffset = mMap->mBuckets[mBucket];
332template <
class Key,
class Value>
335 const int cMaxPerBucket = 256;
337 int max_objects_per_bucket = 0;
339 int histogram[cMaxPerBucket];
340 for (
int i = 0; i < cMaxPerBucket; ++i)
343 for (atomic<uint32> *bucket = mBuckets, *bucket_end = mBuckets + mNumBuckets; bucket < bucket_end; ++bucket)
345 int objects_in_bucket = 0;
349 const KeyValue *kv = mAllocator.template FromOffset<const KeyValue>(offset);
350 offset = kv->mNextOffset;
354 max_objects_per_bucket = max(objects_in_bucket, max_objects_per_bucket);
355 histogram[min(objects_in_bucket, cMaxPerBucket - 1)]++;
358 Trace(
"max_objects_per_bucket = %d, num_buckets = %u, num_objects = %d", max_objects_per_bucket, mNumBuckets, num_objects);
360 for (
int i = 0; i < cMaxPerBucket; ++i)
361 if (histogram[i] != 0)
362 Trace(
"%d: %d", i, histogram[i]);
std::uint8_t uint8
Definition Core.h:506
std::uint64_t uint64
Definition Core.h:510
unsigned int uint
Definition Core.h:505
#define JPH_NAMESPACE_END
Definition Core.h:428
std::uint32_t uint32
Definition Core.h:508
#define JPH_NAMESPACE_BEGIN
Definition Core.h:422
TraceFunction Trace
Definition IssueReporting.cpp:14
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
constexpr bool IsPowerOf2(T inV)
Check if inV is a power of 2.
Definition Math.h:76
bool IsAligned(T inV, uint64 inAlignment)
Check if inV is inAlignment aligned.
Definition Math.h:91
AllocateFunction Allocate
Definition Memory.cpp:68
FreeFunction Free
Definition Memory.cpp:70
AlignedFreeFunction AlignedFree
Definition Memory.cpp:72
AlignedAllocateFunction AlignedAllocate
Definition Memory.cpp:71
void push_back(const T &inValue)
Add element to the back of the array.
Definition Array.h:354
Definition LockFreeHashMap.h:49
LFHMAllocatorContext(LFHMAllocator &inAllocator, uint32 inBlockSize)
Construct a new allocator context.
Definition LockFreeHashMap.inl:88
bool Allocate(uint32 inSize, uint32 inAlignment, uint32 &outWriteOffset)
Allocate data block.
Definition LockFreeHashMap.inl:94
Allocator for a lock free hash map.
Definition LockFreeHashMap.h:14
uint32 ToOffset(const T *inData) const
Convert a pointer to an offset.
Definition LockFreeHashMap.inl:70
~LFHMAllocator()
Destructor.
Definition LockFreeHashMap.inl:13
void Init(uint inObjectStoreSizeBytes)
Definition LockFreeHashMap.inl:22
T * FromOffset(uint32 inOffset) const
Convert an offset to a pointer.
Definition LockFreeHashMap.inl:78
void Allocate(uint32 inBlockSize, uint32 &ioBegin, uint32 &ioEnd)
Definition LockFreeHashMap.inl:39
void Clear()
Clear all allocations.
Definition LockFreeHashMap.inl:34
A key / value pair that is inserted in the map.
Definition LockFreeHashMap.h:100
Definition LockFreeHashMap.h:72
const KeyValue * FromHandle(uint32 inHandle) const
Convert uint32 handle back to key and value.
Definition LockFreeHashMap.inl:254
Iterator begin()
Definition LockFreeHashMap.inl:275
void GetAllKeyValues(Array< const KeyValue * > &outAll) const
Get all key/value pairs.
Definition LockFreeHashMap.inl:260
void Init(uint32 inMaxBuckets)
Definition LockFreeHashMap.inl:127
void SetNumBuckets(uint32 inNumBuckets)
Definition LockFreeHashMap.inl:176
KeyValue * Create(LFHMAllocatorContext &ioContext, const Key &inKey, uint64 inKeyHash, int inExtraBytes, Params &&... inConstructorParams)
Definition LockFreeHashMap.inl:187
~LockFreeHashMap()
Definition LockFreeHashMap.inl:145
const KeyValue * Find(const Key &inKey, uint64 inKeyHash) const
Find an element, returns null if not found.
Definition LockFreeHashMap.inl:230
uint32 ToHandle(const KeyValue *inKeyValue) const
Get convert key value pair to uint32 handle.
Definition LockFreeHashMap.inl:248
Iterator end()
Definition LockFreeHashMap.inl:288
static const uint32 cInvalidHandle
Value of an invalid handle.
Definition LockFreeHashMap.h:123
void Clear()
Definition LockFreeHashMap.inl:155
static JPH_INLINE UVec4 sReplicate(uint32 inV)
Replicate int inV across all components.
Definition UVec4.inl:75
JPH_INLINE void StoreInt4Aligned(uint32 *outV) const
Store 4 ints to memory, aligned to 16 bytes.
Definition UVec4.inl:599
Non-const iterator.
Definition LockFreeHashMap.h:142
uint32 mOffset
Definition LockFreeHashMap.h:155
Iterator & operator++()
Next item.
Definition LockFreeHashMap.inl:302
MapType * mMap
Definition LockFreeHashMap.h:153
KeyValue & operator*()
Convert to key value pair.
Definition LockFreeHashMap.inl:294