|
|
@@ -179,17 +179,9 @@ private:
|
|
|
mSize = inRHS.mSize;
|
|
|
}
|
|
|
|
|
|
- /// Grow the table to the next power of 2
|
|
|
- void GrowTable()
|
|
|
+ /// Grow the table to a new size
|
|
|
+ void GrowTable(size_type inNewMaxSize)
|
|
|
{
|
|
|
- // Calculate new size
|
|
|
- size_type new_max_size = max<size_type>(mMaxSize << 1, 16);
|
|
|
- if (new_max_size < mMaxSize)
|
|
|
- {
|
|
|
- JPH_ASSERT(false, "Overflow in hash table size, can't grow!");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
// Move the old table to a temporary structure
|
|
|
size_type old_max_size = mMaxSize;
|
|
|
KeyValue *old_data = mData;
|
|
|
@@ -201,7 +193,7 @@ private:
|
|
|
mLoadLeft = 0;
|
|
|
|
|
|
// Allocate new table
|
|
|
- AllocateTable(new_max_size);
|
|
|
+ AllocateTable(inNewMaxSize);
|
|
|
|
|
|
// Reset all control bytes
|
|
|
memset(mControl, cBucketEmpty, mMaxSize + 15);
|
|
|
@@ -252,7 +244,16 @@ protected:
|
|
|
if (num_deleted * cMaxDeletedElementsDenominator > mMaxSize * cMaxDeletedElementsNumerator)
|
|
|
rehash(0);
|
|
|
else
|
|
|
- GrowTable();
|
|
|
+ {
|
|
|
+ // Grow by a power of 2
|
|
|
+ size_type new_max_size = max<size_type>(mMaxSize << 1, 16);
|
|
|
+ if (new_max_size < mMaxSize)
|
|
|
+ {
|
|
|
+ JPH_ASSERT(false, "Overflow in hash table size, can't grow!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ GrowTable(new_max_size);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Split hash into index and control value
|
|
|
@@ -489,11 +490,7 @@ public:
|
|
|
if (max_size <= mMaxSize)
|
|
|
return;
|
|
|
|
|
|
- // Allocate buffers
|
|
|
- AllocateTable(max_size);
|
|
|
-
|
|
|
- // Reset all control bytes
|
|
|
- memset(mControl, cBucketEmpty, mMaxSize + 15);
|
|
|
+ GrowTable(max_size);
|
|
|
}
|
|
|
|
|
|
/// Destroy the entire hash table
|
|
|
@@ -523,6 +520,27 @@ public:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// Destroy the entire hash table but keeps the memory allocated
|
|
|
+ void ClearAndKeepMemory()
|
|
|
+ {
|
|
|
+ // Destruct elements
|
|
|
+ if constexpr (!std::is_trivially_destructible<KeyValue>())
|
|
|
+ if (!empty())
|
|
|
+ for (size_type i = 0; i < mMaxSize; ++i)
|
|
|
+ if (mControl[i] & cBucketUsed)
|
|
|
+ mData[i].~KeyValue();
|
|
|
+ mSize = 0;
|
|
|
+
|
|
|
+ // If there are elements that are not marked cBucketEmpty, we reset them
|
|
|
+ size_type max_load = sGetMaxLoad(mMaxSize);
|
|
|
+ if (mLoadLeft != max_load)
|
|
|
+ {
|
|
|
+ // Reset all control bytes
|
|
|
+ memset(mControl, cBucketEmpty, mMaxSize + 15);
|
|
|
+ mLoadLeft = max_load;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// Iterator to first element
|
|
|
iterator begin()
|
|
|
{
|