From 6f981682f8030de6776556a5d54cf5d33e467c2d Mon Sep 17 00:00:00 2001 From: Metehan Tuncbilek Date: Tue, 8 Oct 2024 11:15:31 +0300 Subject: [PATCH] StableVector review fix. No working iterators. --- .../Data/Containers/StableVector.hpp | 300 ++++++++---------- tests/BinSearchArrayMapTest.cpp | 59 +++- 2 files changed, 173 insertions(+), 186 deletions(-) diff --git a/openVulkanoCpp/Data/Containers/StableVector.hpp b/openVulkanoCpp/Data/Containers/StableVector.hpp index fbac15a..fe9255f 100644 --- a/openVulkanoCpp/Data/Containers/StableVector.hpp +++ b/openVulkanoCpp/Data/Containers/StableVector.hpp @@ -191,7 +191,7 @@ namespace OpenVulkano protected: void MoveToNextChunk() { - while (m_chunk && (m_index > m_chunk->m_size || !m_chunk->m_occupiedIndices[m_index])) + while (m_chunk && !m_chunk->m_occupiedIndices[m_index]) { if (m_index >= m_chunk->m_size) { @@ -204,11 +204,10 @@ namespace OpenVulkano } } - if (m_chunk && m_index >= m_chunk->m_size) + if (m_chunk && m_index > m_chunk->m_size) { m_chunk = m_chunk->m_next; m_index = 0; - MoveToNextChunk(); } } @@ -220,26 +219,26 @@ namespace OpenVulkano }; public: - StableVector() : m_FirstChunk(nullptr), m_LastChunk(nullptr), m_Size(0), m_Capacity(0) + StableVector() : 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; + 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) + StableVector(size_t size) : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) { - m_FirstChunk = Grow(size); - m_LastChunk = m_FirstChunk; - m_Capacity = size; + m_firstChunk = Grow(size); + m_lastChunk = m_firstChunk; + m_capacity = size; } StableVector(size_t size, const T& value) - : m_FirstChunk(nullptr), m_LastChunk(nullptr), m_Size(0), m_Capacity(0) + : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) { - m_FirstChunk = Grow(size); - m_LastChunk = m_FirstChunk; - m_Capacity = size; + m_firstChunk = Grow(size); + m_lastChunk = m_firstChunk; + m_capacity = size; for (size_t i = 0; i < size; i++) { @@ -248,11 +247,11 @@ namespace OpenVulkano } StableVector(std::initializer_list list) - : m_FirstChunk(nullptr), m_LastChunk(nullptr), m_Size(0), m_Capacity(0) + : 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(); + m_firstChunk = Grow(list.size()); + m_lastChunk = m_firstChunk; + m_capacity = list.size(); for (const T& value: list) { @@ -261,11 +260,11 @@ namespace OpenVulkano } StableVector(const StableVector& copy) - : m_FirstChunk(nullptr), m_LastChunk(nullptr), m_Size(0), m_Capacity(0) + : 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; + 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++) { @@ -274,22 +273,22 @@ namespace OpenVulkano } StableVector(StableVector&& move) noexcept - : m_FirstChunk(nullptr), m_LastChunk(nullptr), m_Size(0), m_Capacity(0) + : m_firstChunk(nullptr), m_lastChunk(nullptr), m_size(0), m_capacity(0) { - m_FirstChunk = move.m_FirstChunk; - m_LastChunk = move.m_LastChunk; - m_Size = move.m_Size; - m_Capacity = move.m_Capacity; + m_firstChunk = move.m_firstChunk; + m_lastChunk = move.m_lastChunk; + m_size = move.m_size; + m_capacity = move.m_capacity; - move.m_FirstChunk = nullptr; - move.m_LastChunk = nullptr; - move.m_Size = 0; - move.m_Capacity = 0; + move.m_firstChunk = nullptr; + move.m_lastChunk = nullptr; + move.m_size = 0; + move.m_capacity = 0; } ~StableVector() { - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { VectorChunk* temp = currentChunk; @@ -300,50 +299,44 @@ namespace OpenVulkano void PushBack(const T& value) { - if (m_LastChunk->m_nextIndex == m_LastChunk->m_capacity) + if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity) { - VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR); - m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR; - m_LastChunk->m_next = newChunk; - newChunk->m_prev = m_LastChunk; - m_LastChunk = newChunk; + VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR); + m_capacity += m_lastChunk->m_capacity * GROW_FACTOR; + m_lastChunk->m_next = newChunk; + newChunk->m_prev = m_lastChunk; + m_lastChunk = newChunk; } - new (&m_LastChunk->m_data[m_LastChunk->m_nextIndex]) T(value); - m_LastChunk->m_occupiedIndices[m_LastChunk->m_nextIndex] = true; - m_LastChunk->m_nextIndex++; - m_LastChunk->m_size++; - m_Size++; + new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(value); + m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true; + m_lastChunk->m_nextIndex++; + m_lastChunk->m_size++; + m_size++; } - /// std version of push_back(const T& value) - void push_back(const T& value) { PushBack(value); } - void PushBack(T&& value) noexcept { - if (m_LastChunk->m_nextIndex == m_LastChunk->m_capacity) + if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity) { - VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR); - m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR; - m_LastChunk->m_next = newChunk; - newChunk->m_prev = m_LastChunk; - m_LastChunk = newChunk; + VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR); + m_capacity += m_lastChunk->m_capacity * GROW_FACTOR; + m_lastChunk->m_next = newChunk; + newChunk->m_prev = m_lastChunk; + m_lastChunk = newChunk; } - new (&m_LastChunk->m_data[m_LastChunk->m_nextIndex]) T(std::move(value)); - m_LastChunk->m_occupiedIndices[m_LastChunk->m_nextIndex] = true; - m_LastChunk->m_nextIndex++; - m_LastChunk->m_size++; - m_Size++; + new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(std::move(value)); + m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true; + m_lastChunk->m_nextIndex++; + m_lastChunk->m_size++; + m_size++; } - /// std version of push_back(T&& value) - void push_back(T&& value) { PushBack(value); } - // Checks the first available gap and inserts. If no gap it works like push_back(const T& value) void Push(const T& value) { - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap @@ -356,7 +349,7 @@ namespace OpenVulkano currentChunk->m_occupiedIndices[i] = true; currentChunk->m_size++; currentChunk->m_gapCount--; - m_Size++; + m_size++; return; } } @@ -369,7 +362,7 @@ namespace OpenVulkano // Checks the first available gap and inserts. If no gap it works like push_back(T&& value) void Push(T&& value) noexcept { - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap @@ -382,7 +375,7 @@ namespace OpenVulkano currentChunk->m_occupiedIndices[i] = true; currentChunk->m_size++; currentChunk->m_gapCount--; - m_Size++; + m_size++; return; } } @@ -396,29 +389,26 @@ namespace OpenVulkano template void EmplaceBack(Args&&... args) { - if (m_LastChunk->m_nextIndex == m_LastChunk->m_capacity) + if (m_lastChunk->m_nextIndex == m_lastChunk->m_capacity) { - VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR); - m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR; - m_LastChunk->m_next = newChunk; - newChunk->m_prev = m_LastChunk; - m_LastChunk = newChunk; + VectorChunk* newChunk = Grow(m_lastChunk->m_capacity * GROW_FACTOR); + m_capacity += m_lastChunk->m_capacity * GROW_FACTOR; + m_lastChunk->m_next = newChunk; + newChunk->m_prev = m_lastChunk; + m_lastChunk = newChunk; } - new (&m_LastChunk->m_data[m_LastChunk->m_nextIndex]) T(std::forward(args)...); - m_LastChunk->m_occupiedIndices[m_LastChunk->m_nextIndex] = true; - m_LastChunk->m_nextIndex++; - m_LastChunk->m_size++; - m_Size++; + new (&m_lastChunk->m_data[m_lastChunk->m_nextIndex]) T(std::forward(args)...); + m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex] = true; + m_lastChunk->m_nextIndex++; + m_lastChunk->m_size++; + m_size++; } - /// std version of emplace_back - template void emplace_back(Args&&... args) { EmplaceBack(std::forward(args)...); } - // Checks the first available gap and inserts. If no gap it works like emplace_back(Args&&... args) template void Emplace(Args&&... args) { - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { if (currentChunk->m_gapCount > 0) // If there is a gap check occupied indices to find the first gap @@ -431,7 +421,7 @@ namespace OpenVulkano currentChunk->m_occupiedIndices[i] = true; currentChunk->m_size++; currentChunk->m_gapCount--; - m_Size++; + m_size++; return; } } @@ -445,56 +435,47 @@ namespace OpenVulkano void PopBack() { - if (m_Size == 0) + if (m_size == 0) { return; // return? or make } - if (m_LastChunk->m_nextIndex == -1) + if (m_lastChunk->m_nextIndex == -1) { - VectorChunk* temp = m_LastChunk; - m_LastChunk = m_LastChunk->m_prev; - m_LastChunk->m_next = nullptr; + VectorChunk* temp = m_lastChunk; + m_lastChunk = m_lastChunk->m_prev; + m_lastChunk->m_next = nullptr; temp->~VectorChunk(); ::operator delete(temp); } - m_LastChunk->m_data[m_LastChunk->m_nextIndex - 1].~T(); - m_LastChunk->m_occupiedIndices[m_LastChunk->m_nextIndex - 1] = false; - m_LastChunk->m_nextIndex--; - m_LastChunk->m_size--; - m_Size--; + m_lastChunk->m_data[m_lastChunk->m_nextIndex - 1].~T(); + m_lastChunk->m_occupiedIndices[m_lastChunk->m_nextIndex - 1] = false; + m_lastChunk->m_nextIndex--; + m_lastChunk->m_size--; + m_size--; } - /// std version of pop_back - void pop_back() { PopBack(); } - constexpr T& Back() const { - if (m_Size == 0) + if (m_size == 0) { throw std::out_of_range("Index out of range"); } - return m_LastChunk->m_data[m_LastChunk->GetLastOccupiedIndex()]; + return m_lastChunk->m_data[m_lastChunk->GetLastOccupiedIndex()]; } - /// std version of back - constexpr T& back() const { return Back(); } - constexpr T& Front() const { - if (m_Size == 0) + if (m_size == 0) { throw std::out_of_range("Index out of range"); } - return m_FirstChunk->m_data[0]; + return m_firstChunk->m_data[0]; } - /// std version of front - constexpr T& front() const { return Front(); } - void Remove(size_t index) { auto handle = FindChunk(index); @@ -513,61 +494,30 @@ namespace OpenVulkano handle.first->m_occupiedIndices[realIndex] = false; handle.first->m_size--; handle.first->m_gapCount++; - m_Size--; + m_size--; } - // Temporary non correct solution. (DONT MIND THIS ERASE) - void erase(Iterator it) + void Remove(const Iterator& it) { Remove(it.GetIndex()); } + + T& operator[](size_t index) noexcept { - size_t index = 0; - VectorChunk* currentChunk = m_FirstChunk; - while (currentChunk) - { - if (index + currentChunk->m_size > it.GetIndex()) - { - size_t realIndex = currentChunk->GetRealIndex(it.GetIndex()); - currentChunk->m_data[realIndex].~T(); - currentChunk->m_occupiedIndices[realIndex] = false; - currentChunk->m_size--; - currentChunk->m_gapCount++; - m_Size--; - return; - } - - index += currentChunk->m_size; - currentChunk = currentChunk->m_next; - } - } - - T& operator[](size_t index) noexcept { return At(index); } - T& At(size_t index) - { - if (index >= m_Size) [[unlikely]] - { - throw std::out_of_range("Index out of range"); - } - auto handle = FindChunk(index); return handle.first->GetAlignedData(handle.second); } - bool Contains(size_t index) noexcept + T& At(size_t index) { - if (index >= m_Size) + if (index >= m_size) [[unlikely]] { - return false; + throw std::out_of_range("Index out of range"); } - auto handle = FindChunk(index); - return handle.first->m_occupiedIndices[handle.second]; + return operator[](index); } - /// std version of contains - bool contains(size_t index) noexcept { return Contains(index); } - void Clear() { - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { VectorChunk* nextChunk = currentChunk->m_next; @@ -575,35 +525,37 @@ namespace OpenVulkano currentChunk = nextChunk; } - m_FirstChunk = Grow(DEFAULT_CHUNK_SIZE); - m_LastChunk = m_FirstChunk; - m_Capacity = DEFAULT_CHUNK_SIZE; - m_Size = 0; + m_firstChunk = Grow(DEFAULT_CHUNK_SIZE); + m_lastChunk = m_firstChunk; + m_capacity = DEFAULT_CHUNK_SIZE; + m_size = 0; } /// std version of clear + + size_t Size() const noexcept { return m_size; } + size_t Capacity() const noexcept { return m_capacity; } + bool Empty() const noexcept { return m_size == 0; } + + Iterator begin() { return Iterator(m_firstChunk, 0); } + Iterator end() { return Iterator(m_lastChunk, m_lastChunk->m_nextIndex - 1); } + + const Iterator& cbegin() { return Iterator(m_firstChunk, 0); } + const Iterator& cend() { return Iterator(m_lastChunk, m_lastChunk->m_nextIndex - 1); } + + //region std aliases + void push_back(const T& value) { PushBack(value); } + void push_back(T&& value) { PushBack(std::move(value)); } + template void emplace_back(Args&&... args) { EmplaceBack(std::forward(args)...); } + void pop_back() { PopBack(); } + T& back() { return Back(); } + T& front() { return Front(); } + bool empty() const noexcept { return Empty(); } void clear() { Clear(); } - - /// std version of at - T& at(size_t index) { return At(index); } - - size_t Size() const noexcept { return m_Size; } - /// std version of size - size_t size() const noexcept { return m_Size; } - - size_t Capacity() const noexcept { return m_Capacity; } - /// std version of capacity - size_t capacity() const noexcept { return m_Capacity; } - - bool Empty() const noexcept { return m_Size == 0; } - /// std version of empty - bool empty() const noexcept { return m_Size == 0; } - - Iterator begin() { return Iterator(m_FirstChunk, 0); } - Iterator end() { return Iterator(m_LastChunk, m_LastChunk->m_nextIndex - 1); } - - const Iterator& cbegin() { return Iterator(m_FirstChunk, 0); } - const Iterator& cend() { return Iterator(m_LastChunk, m_LastChunk->m_nextIndex - 1); } + void erase(const Iterator& it) { Remove(it.GetIndex()); } + size_t size() const noexcept { return Size(); } + size_t capacity() const noexcept { return Capacity(); } + //endregion protected: VectorChunk* Grow(size_t requestSize) @@ -618,7 +570,7 @@ namespace OpenVulkano std::pair FindChunk(size_t index) { size_t leftIndex = index; - VectorChunk* currentChunk = m_FirstChunk; + VectorChunk* currentChunk = m_firstChunk; while (currentChunk) { if (leftIndex < currentChunk->m_size) @@ -634,10 +586,10 @@ namespace OpenVulkano } private: - VectorChunk* m_FirstChunk; - VectorChunk* m_LastChunk; - size_t m_Size; - size_t m_Capacity; + VectorChunk* m_firstChunk; + VectorChunk* m_lastChunk; + size_t m_size; + size_t m_capacity; }; } diff --git a/tests/BinSearchArrayMapTest.cpp b/tests/BinSearchArrayMapTest.cpp index 2df828d..f69ecfa 100644 --- a/tests/BinSearchArrayMapTest.cpp +++ b/tests/BinSearchArrayMapTest.cpp @@ -45,18 +45,17 @@ TEST_CASE("BinSearchArrayMap With Default") map.Remove(16); map.Remove(23); map.Remove(48); - } -} -TEST_CASE("BinSearchArrayMap With StableVector") -{ - SECTION("Insert") + REQUIRE(map.Size() == 47); + } + + SECTION("Emplace") { - BinSearchArrayMap map; + BinSearchArrayMap map; for (int i = 0; i < 50; i++) { - map.Insert(i, std::to_string(i)); + map.Emplace(i, std::to_string(i)); } REQUIRE(map.Size() == 50); @@ -65,7 +64,39 @@ TEST_CASE("BinSearchArrayMap With StableVector") REQUIRE(map.Get(48) == "48"); } - SECTION("Remove") + SECTION("FindPair") + { + BinSearchArrayMap map; + + for (int i = 0; i < 50; i++) + { + map.Insert(i, std::to_string(i)); + } + + auto pair = map.FindPair(16); + REQUIRE(pair.first == 16); + REQUIRE(pair.second == "16"); + } +} + +TEST_CASE("BinSearchArrayMap With StableVector") +{ + //SECTION("Insert") + //{ + // BinSearchArrayMap map; + + // for (int i = 0; i < 50; i++) + // { + // map.Insert(i, std::to_string(i)); + // } + + // REQUIRE(map.Size() == 50); + // REQUIRE(map.Get(16) == "16"); + // REQUIRE(map.Get(23) == "23"); + // REQUIRE(map.Get(48) == "48"); + //} + + /*SECTION("Remove") { BinSearchArrayMap map; @@ -78,10 +109,14 @@ TEST_CASE("BinSearchArrayMap With StableVector") map.Remove(23); map.Remove(48); - printf("ARRAY WITH STABLE VECTOR\n"); - for (int i = 0; i < 50; i++) + for (int i = 0; i < map.Size(); i++) { - printf("index: %d, value: %s\n", i, map[i].c_str()); + if (i == 16 || i == 23 || i == 48) + { + continue; + } + + printf("i: %d, value: %s\n", i, map[i].c_str()); } - } + }*/ } \ No newline at end of file