From dca48b335a87da5afb2e03ed0297013610329428 Mon Sep 17 00:00:00 2001
From: Mateusz Karbowiak <69864511+mtszkarbowiak@users.noreply.github.com>
Date: Thu, 31 Oct 2024 02:41:51 +0100
Subject: [PATCH] Hash collections bucket state enum extracted
This is a small compilation time optimization by reducing total number of generated types. Should not change runtime behavior.
---
Source/Engine/Core/Collections/BucketState.h | 15 +++++++
Source/Engine/Core/Collections/Dictionary.h | 44 +++++++++-----------
Source/Engine/Core/Collections/HashSet.h | 42 ++++++++-----------
3 files changed, 52 insertions(+), 49 deletions(-)
create mode 100644 Source/Engine/Core/Collections/BucketState.h
diff --git a/Source/Engine/Core/Collections/BucketState.h b/Source/Engine/Core/Collections/BucketState.h
new file mode 100644
index 000000000..16cbdb845
--- /dev/null
+++ b/Source/Engine/Core/Collections/BucketState.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
+
+#pragma once
+
+#include "Engine/Core/Types/BaseTypes.h"
+
+///
+/// Tells if the object is occupied, and if not, if the bucket is a subject of compaction.
+///
+enum class BucketState : byte
+{
+ Empty = 0,
+ Deleted = 1,
+ Occupied = 2,
+};
diff --git a/Source/Engine/Core/Collections/Dictionary.h b/Source/Engine/Core/Collections/Dictionary.h
index 794cfc455..efb7bafcf 100644
--- a/Source/Engine/Core/Collections/Dictionary.h
+++ b/Source/Engine/Core/Collections/Dictionary.h
@@ -4,6 +4,7 @@
#include "Engine/Core/Memory/Memory.h"
#include "Engine/Core/Memory/Allocation.h"
+#include "Engine/Core/Collections/BucketState.h"
#include "Engine/Core/Collections/HashFunctions.h"
#include "Engine/Core/Collections/Config.h"
@@ -25,34 +26,27 @@ public:
{
friend Dictionary;
- enum State : byte
- {
- Empty = 0,
- Deleted = 1,
- Occupied = 2,
- };
-
/// The key.
KeyType Key;
/// The value.
ValueType Value;
private:
- State _state;
+ BucketState _state;
FORCE_INLINE void Free()
{
- if (_state == Occupied)
+ if (_state == BucketState::Occupied)
{
Memory::DestructItem(&Key);
Memory::DestructItem(&Value);
}
- _state = Empty;
+ _state = BucketState::Empty;
}
FORCE_INLINE void Delete()
{
- _state = Deleted;
+ _state = BucketState::Deleted;
Memory::DestructItem(&Key);
Memory::DestructItem(&Value);
}
@@ -62,7 +56,7 @@ public:
{
Memory::ConstructItems(&Key, &key, 1);
Memory::ConstructItem(&Value);
- _state = Occupied;
+ _state = BucketState::Occupied;
}
template
@@ -70,7 +64,7 @@ public:
{
Memory::ConstructItems(&Key, &key, 1);
Memory::ConstructItems(&Value, &value, 1);
- _state = Occupied;
+ _state = BucketState::Occupied;
}
template
@@ -78,27 +72,27 @@ public:
{
Memory::ConstructItems(&Key, &key, 1);
Memory::MoveItems(&Value, &value, 1);
- _state = Occupied;
+ _state = BucketState::Occupied;
}
FORCE_INLINE bool IsEmpty() const
{
- return _state == Empty;
+ return _state == BucketState::Empty;
}
FORCE_INLINE bool IsDeleted() const
{
- return _state == Deleted;
+ return _state == BucketState::Deleted;
}
FORCE_INLINE bool IsOccupied() const
{
- return _state == Occupied;
+ return _state == BucketState::Occupied;
}
FORCE_INLINE bool IsNotOccupied() const
{
- return _state != Occupied;
+ return _state != BucketState::Occupied;
}
};
@@ -127,10 +121,10 @@ private:
Bucket& toBucket = toData[i];
Memory::MoveItems(&toBucket.Key, &fromBucket.Key, 1);
Memory::MoveItems(&toBucket.Value, &fromBucket.Value, 1);
- toBucket._state = Bucket::Occupied;
+ toBucket._state = BucketState::Occupied;
Memory::DestructItem(&fromBucket.Key);
Memory::DestructItem(&fromBucket.Value);
- fromBucket._state = Bucket::Empty;
+ fromBucket._state = BucketState::Empty;
}
}
from.Free();
@@ -566,7 +560,7 @@ public:
_allocation.Allocate(capacity);
Bucket* data = _allocation.Get();
for (int32 i = 0; i < capacity; i++)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
}
_size = capacity;
Bucket* oldData = oldAllocation.Get();
@@ -583,7 +577,7 @@ public:
Bucket* bucket = &_allocation.Get()[pos.FreeSlotIndex];
Memory::MoveItems(&bucket->Key, &oldBucket.Key, 1);
Memory::MoveItems(&bucket->Value, &oldBucket.Value, 1);
- bucket->_state = Bucket::Occupied;
+ bucket->_state = BucketState::Occupied;
++_elementsCount;
}
}
@@ -967,7 +961,7 @@ private:
// Fast path if it's empty
Bucket* data = _allocation.Get();
for (int32 i = 0; i < _size; i++)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
}
else
{
@@ -977,7 +971,7 @@ private:
_allocation.Allocate(_size);
Bucket* data = _allocation.Get();
for (int32 i = 0; i < _size; i++)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
Bucket* oldData = oldAllocation.Get();
FindPositionResult pos;
for (int32 i = 0; i < _size; i++)
@@ -990,7 +984,7 @@ private:
Bucket* bucket = &_allocation.Get()[pos.FreeSlotIndex];
Memory::MoveItems(&bucket->Key, &oldBucket.Key, 1);
Memory::MoveItems(&bucket->Value, &oldBucket.Value, 1);
- bucket->_state = Bucket::Occupied;
+ bucket->_state = BucketState::Occupied;
}
}
for (int32 i = 0; i < _size; i++)
diff --git a/Source/Engine/Core/Collections/HashSet.h b/Source/Engine/Core/Collections/HashSet.h
index 2e90dae4b..aa61354fd 100644
--- a/Source/Engine/Core/Collections/HashSet.h
+++ b/Source/Engine/Core/Collections/HashSet.h
@@ -4,6 +4,7 @@
#include "Engine/Core/Memory/Memory.h"
#include "Engine/Core/Memory/Allocation.h"
+#include "Engine/Core/Collections/BucketState.h"
#include "Engine/Core/Collections/HashFunctions.h"
#include "Engine/Core/Collections/Config.h"
@@ -24,29 +25,22 @@ public:
{
friend HashSet;
- enum State : byte
- {
- Empty,
- Deleted,
- Occupied,
- };
-
/// The item.
T Item;
private:
- State _state;
+ BucketState _state;
FORCE_INLINE void Free()
{
- if (_state == Occupied)
+ if (_state == BucketState::Occupied)
Memory::DestructItem(&Item);
- _state = Empty;
+ _state = BucketState::Empty;
}
FORCE_INLINE void Delete()
{
- _state = Deleted;
+ _state = BucketState::Deleted;
Memory::DestructItem(&Item);
}
@@ -54,34 +48,34 @@ public:
FORCE_INLINE void Occupy(const ItemType& item)
{
Memory::ConstructItems(&Item, &item, 1);
- _state = Occupied;
+ _state = BucketState::Occupied;
}
template
FORCE_INLINE void Occupy(ItemType&& item)
{
Memory::MoveItems(&Item, &item, 1);
- _state = Occupied;
+ _state = BucketState::Occupied;
}
FORCE_INLINE bool IsEmpty() const
{
- return _state == Empty;
+ return _state == BucketState::Empty;
}
FORCE_INLINE bool IsDeleted() const
{
- return _state == Deleted;
+ return _state == BucketState::Deleted;
}
FORCE_INLINE bool IsOccupied() const
{
- return _state == Occupied;
+ return _state == BucketState::Occupied;
}
FORCE_INLINE bool IsNotOccupied() const
{
- return _state != Occupied;
+ return _state != BucketState::Occupied;
}
};
@@ -109,9 +103,9 @@ private:
{
Bucket& toBucket = toData[i];
Memory::MoveItems(&toBucket.Item, &fromBucket.Item, 1);
- toBucket._state = Bucket::Occupied;
+ toBucket._state = BucketState::Occupied;
Memory::DestructItem(&fromBucket.Item);
- fromBucket._state = Bucket::Empty;
+ fromBucket._state = BucketState::Empty;
}
}
from.Free();
@@ -443,7 +437,7 @@ public:
_allocation.Allocate(capacity);
Bucket* data = _allocation.Get();
for (int32 i = 0; i < capacity; i++)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
}
_size = capacity;
Bucket* oldData = oldAllocation.Get();
@@ -459,7 +453,7 @@ public:
ASSERT(pos.FreeSlotIndex != -1);
Bucket* bucket = &_allocation.Get()[pos.FreeSlotIndex];
Memory::MoveItems(&bucket->Item, &oldBucket.Item, 1);
- bucket->_state = Bucket::Occupied;
+ bucket->_state = BucketState::Occupied;
_elementsCount++;
}
}
@@ -763,7 +757,7 @@ private:
// Fast path if it's empty
Bucket* data = _allocation.Get();
for (int32 i = 0; i < _size; ++i)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
}
else
{
@@ -773,7 +767,7 @@ private:
_allocation.Allocate(_size);
Bucket* data = _allocation.Get();
for (int32 i = 0; i < _size; ++i)
- data[i]._state = Bucket::Empty;
+ data[i]._state = BucketState::Empty;
Bucket* oldData = oldAllocation.Get();
FindPositionResult pos;
for (int32 i = 0; i < _size; ++i)
@@ -785,7 +779,7 @@ private:
ASSERT(pos.FreeSlotIndex != -1);
Bucket* bucket = &_allocation.Get()[pos.FreeSlotIndex];
Memory::MoveItems(&bucket->Item, &oldBucket.Item, 1);
- bucket->_state = Bucket::Occupied;
+ bucket->_state = BucketState::Occupied;
}
}
for (int32 i = 0; i < _size; ++i)