fixed review on stableVector.

This commit is contained in:
Metehan Tuncbilek
2024-10-09 23:50:37 +03:00
parent 89ce60f869
commit 8e527074e3

View File

@@ -56,6 +56,7 @@ namespace OpenVulkano
{ {
if (m_occupiedIndices[i]) if (m_occupiedIndices[i])
{ {
m_occupiedIndices[i] = false;
m_data[i].~T(); m_data[i].~T();
} }
} }
@@ -65,7 +66,7 @@ namespace OpenVulkano
size_t GetRealIndex(size_t reqIndex) size_t GetRealIndex(size_t reqIndex)
{ {
if (m_gapCount == 0 || reqIndex == 0) if (m_gapCount == 0)
{ {
return reqIndex; return reqIndex;
} }
@@ -79,27 +80,7 @@ namespace OpenVulkano
} }
} }
return reqIndex + gapCount; for (size_t i = reqIndex + gapCount; i < m_capacity; i++)
}
T& GetAlignedData(size_t index)
{
size_t realIndex = GetRealIndex(index);
for (size_t i = realIndex; i < m_capacity; i++)
{
if (m_occupiedIndices[i])
{
return m_data[i];
}
}
throw std::out_of_range("Index out of range");
}
size_t GetLastOccupiedIndex()
{
for (size_t i = m_capacity - 1; i >= 0; i--)
{ {
if (m_occupiedIndices[i]) if (m_occupiedIndices[i])
{ {
@@ -107,20 +88,22 @@ namespace OpenVulkano
} }
} }
return 0; return reqIndex + gapCount;
} }
}; };
public: public:
class Iterator class Iterator
{ {
friend class StableVector<T>;
public: public:
Iterator(VectorChunk* chunk, size_t index) : m_chunk(chunk), m_index(index) {} Iterator(VectorChunk* chunk, size_t index) : m_chunk(chunk), m_index(index) {}
T& operator*() T& operator*()
{ {
auto realIndex = m_chunk->GetRealIndex(m_index); auto realIndex = m_chunk->GetRealIndex(m_index);
return m_chunk->GetAlignedData(realIndex); return m_chunk->m_data[realIndex];
} }
T* operator->() { return &operator*(); } T* operator->() { return &operator*(); }
@@ -176,10 +159,7 @@ namespace OpenVulkano
bool operator!=(const Iterator& other) const { return !(*this == other); } bool operator!=(const Iterator& other) const { return !(*this == other); }
std::streamsize GetIndex() const { return m_chunk->GetRealIndex(m_index); } private:
VectorChunk* GetChunk() const { return m_chunk; }
protected:
void MoveToNextChunk() void MoveToNextChunk()
{ {
while (m_chunk && m_index >= m_chunk->m_size) while (m_chunk && m_index >= m_chunk->m_size)
@@ -198,20 +178,16 @@ namespace OpenVulkano
} }
} }
std::streamsize GetIteratorIndex() const { return m_chunk->GetRealIndex(m_index); }
private: private:
VectorChunk* m_chunk; VectorChunk* m_chunk;
std::streamsize m_index; std::streamsize m_index;
}; };
public: public:
StableVector() : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) StableVector(size_t size = DEFAULT_CHUNK_SIZE)
{ : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
m_firstChunk = Grow(DEFAULT_CHUNK_SIZE);
m_lastChunk = m_firstChunk;
m_capacity = DEFAULT_CHUNK_SIZE;
}
StableVector(size_t size) : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
{ {
m_firstChunk = Grow(size); m_firstChunk = Grow(size);
m_lastChunk = m_firstChunk; m_lastChunk = m_firstChunk;
@@ -219,12 +195,8 @@ namespace OpenVulkano
} }
StableVector(size_t size, const T& value) StableVector(size_t size, const T& value)
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) : StableVector(size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
{ {
m_firstChunk = Grow(size);
m_lastChunk = m_firstChunk;
m_capacity = size;
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
{ {
PushBack(value); PushBack(value);
@@ -232,12 +204,8 @@ namespace OpenVulkano
} }
StableVector(std::initializer_list<T> list) StableVector(std::initializer_list<T> list)
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) : StableVector(list.size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
{ {
m_firstChunk = Grow(list.size());
m_lastChunk = m_firstChunk;
m_capacity = list.size();
for (const T& value: list) for (const T& value: list)
{ {
PushBack(value); PushBack(value);
@@ -245,12 +213,8 @@ namespace OpenVulkano
} }
StableVector(const StableVector<T>& copy) StableVector(const StableVector<T>& copy)
: m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) : StableVector(copy.m_size), m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0)
{ {
m_firstChunk = Grow(copy.m_capacity); // One big chunk to make Stable contiguous.
m_lastChunk = m_firstChunk;
m_capacity = copy.m_capacity;
for (size_t i = 0; i < copy.Size(); i++) for (size_t i = 0; i < copy.Size(); i++)
{ {
PushBack(copy.At(i)); PushBack(copy.At(i));
@@ -273,12 +237,14 @@ namespace OpenVulkano
~StableVector() ~StableVector()
{ {
// Destroy everything left
VectorChunk* currentChunk = m_firstChunk; VectorChunk* currentChunk = m_firstChunk;
while (currentChunk) while (currentChunk)
{ {
VectorChunk* temp = currentChunk; VectorChunk* temp = currentChunk;
currentChunk = currentChunk->m_next; currentChunk = currentChunk->m_next;
delete temp; temp->~VectorChunk();
::operator delete(temp);
} }
} }
@@ -312,8 +278,8 @@ namespace OpenVulkano
m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1].~T(); m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1].~T();
m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex - 1] = false; m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex - 1] = false;
m_lastChunk->m_nextIndex--;
m_lastChunk->m_size--; m_lastChunk->m_size--;
m_lastChunk->m_gapCount++;
m_size--; m_size--;
} }
@@ -324,7 +290,7 @@ namespace OpenVulkano
throw std::out_of_range("Index out of range"); throw std::out_of_range("Index out of range");
} }
return m_lastChunk->m_data[m_lastChunk->GetLastOccupiedIndex()]; return m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1];
} }
constexpr T& Front() const constexpr T& Front() const
@@ -351,26 +317,24 @@ namespace OpenVulkano
throw std::out_of_range("Index out of range"); throw std::out_of_range("Index out of range");
} }
handle.first->m_data[realIndex].~T(); Delete(realIndex, handle.first);
handle.first->m_occupiedIndices[realIndex] = false;
handle.first->m_size--;
handle.first->m_gapCount++;
m_size--;
} }
void Remove(const Iterator& it) void Remove(const Iterator& it)
{ {
it.GetChunk()->m_data[it.GetIndex()].~T(); if (it.m_chunk == nullptr)
it.GetChunk()->m_occupiedIndices[it.GetIndex()] = false; {
it.GetChunk()->m_size--; throw std::out_of_range("Index out of range");
it.GetChunk()->m_gapCount++; }
m_size--;
Delete(it.GetIteratorIndex(), it.m_chunk);
} }
T& operator[](size_t index) noexcept T& operator[](size_t index) noexcept
{ {
auto handle = FindChunk(index); auto handle = FindChunk(index);
return handle.first->GetAlignedData(handle.second); size_t realIndex = handle.first->GetRealIndex(handle.second);
return handle.first->m_data[realIndex];
} }
T& At(size_t index) T& At(size_t index)
@@ -383,20 +347,30 @@ namespace OpenVulkano
return operator[](index); return operator[](index);
} }
void Clear() void Clear()
{ {
VectorChunk* currentChunk = m_firstChunk; // Get the first chunk's cap
size_t cap = m_firstChunk->m_capacity;
// Annihilate everything
VectorChunk* currentChunk = m_firstChunk->m_next;
while (currentChunk) while (currentChunk)
{ {
VectorChunk* nextChunk = currentChunk->m_next; VectorChunk* temp = currentChunk;
delete currentChunk; currentChunk = currentChunk->m_next;
currentChunk = nextChunk; temp->~VectorChunk();
::operator delete(temp);
} }
m_firstChunk = Grow(DEFAULT_CHUNK_SIZE); // Reset the first chunk
m_firstChunk->m_next = nullptr;
m_lastChunk = m_firstChunk; m_lastChunk = m_firstChunk;
m_capacity = DEFAULT_CHUNK_SIZE; m_firstChunk->m_size = 0;
m_firstChunk->m_nextIndex = 0;
m_firstChunk->m_gapCount = 0;
m_firstChunk->~VectorChunk();
m_size = 0; m_size = 0;
m_capacity = cap;
} }
size_t Size() const noexcept { return m_size; } size_t Size() const noexcept { return m_size; }
@@ -423,7 +397,7 @@ namespace OpenVulkano
size_t capacity() const noexcept { return Capacity(); } size_t capacity() const noexcept { return Capacity(); }
//endregion //endregion
protected: private:
VectorChunk* Grow(size_t requestSize) VectorChunk* Grow(size_t requestSize)
{ {
VectorChunk* newChunk = static_cast<VectorChunk*>( VectorChunk* newChunk = static_cast<VectorChunk*>(
@@ -497,6 +471,15 @@ namespace OpenVulkano
return InsertBack(); return InsertBack();
} }
void Delete(size_t index, VectorChunk* chunk)
{
chunk->m_data[index].~T();
chunk->m_occupiedIndices[index] = false;
chunk->m_size--;
chunk->m_gapCount++;
m_size--;
}
private: private:
VectorChunk* m_firstChunk; VectorChunk* m_firstChunk;
VectorChunk* m_lastChunk; VectorChunk* m_lastChunk;