stable vector fix for algorithm. Still no correct Iterator.

This commit is contained in:
Metehan Tuncbilek
2024-10-08 07:20:41 +03:00
parent eb2ca2ff5a
commit 7b40d001ec
4 changed files with 316 additions and 266 deletions

View File

@@ -106,7 +106,7 @@ namespace OpenVulkano
return -1; return -1;
} }
bool Contains(const K key) const noexcept bool Contains(const K key) noexcept
{ {
size_t low = 0; size_t low = 0;
size_t high = m_data.size(); size_t high = m_data.size();

View File

@@ -52,7 +52,7 @@ namespace OpenVulkano
~VectorChunk() ~VectorChunk()
{ {
for (size_t i = 0; i < m_size; i++) for (size_t i = 0; i < m_capacity; i++)
{ {
if (m_occupiedIndices[i]) if (m_occupiedIndices[i])
{ {
@@ -65,13 +65,13 @@ namespace OpenVulkano
size_t GetRealIndex(size_t reqIndex) size_t GetRealIndex(size_t reqIndex)
{ {
if (m_gapCount == 0) if (m_gapCount == 0 || reqIndex == 0)
{ {
return reqIndex; return reqIndex;
} }
size_t gapCount = 0; size_t gapCount = 0;
for (size_t i = 0; i < reqIndex; i++) for (size_t i = 0; i <= reqIndex; i++)
{ {
if (!m_occupiedIndices[i]) if (!m_occupiedIndices[i])
{ {
@@ -93,6 +93,8 @@ namespace OpenVulkano
return m_data[i]; return m_data[i];
} }
} }
throw std::out_of_range("Index out of range");
} }
size_t GetLastOccupiedIndex() size_t GetLastOccupiedIndex()
@@ -115,8 +117,17 @@ namespace OpenVulkano
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*() { return m_chunk->GetAlignedData(m_index); } T& operator*()
T* operator->() { return &m_chunk->GetAlignedData(m_index); } {
auto realIndex = m_chunk->GetRealIndex(m_index);
return m_chunk->GetAlignedData(m_index);
}
T* operator->()
{
auto realIndex = m_chunk->GetRealIndex(m_index);
return &m_chunk->GetAlignedData(m_index);
}
Iterator& operator++() Iterator& operator++()
{ {
@@ -174,13 +185,30 @@ namespace OpenVulkano
return m_chunk != other.m_chunk || m_index != other.m_index; return m_chunk != other.m_chunk || m_index != other.m_index;
} }
size_t GetIndex() const { return m_index; }
size_t GetChunk() const { return m_chunk; }
protected: protected:
void MoveToNextChunk() void MoveToNextChunk()
{ {
while (m_chunk && m_index > m_chunk->m_size) while (m_chunk && (m_index > m_chunk->m_size || !m_chunk->m_occupiedIndices[m_index]))
{
if (m_index >= m_chunk->m_size)
{
m_chunk = m_chunk->m_next;
m_index = 0;
}
else
{
++m_index;
}
}
if (m_chunk && m_index >= m_chunk->m_size)
{ {
m_index -= m_chunk->m_size;
m_chunk = m_chunk->m_next; m_chunk = m_chunk->m_next;
m_index = 0;
MoveToNextChunk();
} }
} }
@@ -264,10 +292,9 @@ namespace OpenVulkano
VectorChunk* currentChunk = m_FirstChunk; VectorChunk* currentChunk = m_FirstChunk;
while (currentChunk) while (currentChunk)
{ {
VectorChunk* nextChunk = currentChunk->m_next; VectorChunk* temp = currentChunk;
currentChunk->~VectorChunk(); currentChunk = currentChunk->m_next;
::operator delete(currentChunk); delete temp;
currentChunk = nextChunk;
} }
} }
@@ -276,6 +303,7 @@ namespace OpenVulkano
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); VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR);
m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR;
m_LastChunk->m_next = newChunk; m_LastChunk->m_next = newChunk;
newChunk->m_prev = m_LastChunk; newChunk->m_prev = m_LastChunk;
m_LastChunk = newChunk; m_LastChunk = newChunk;
@@ -296,6 +324,7 @@ namespace OpenVulkano
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); VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR);
m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR;
m_LastChunk->m_next = newChunk; m_LastChunk->m_next = newChunk;
newChunk->m_prev = m_LastChunk; newChunk->m_prev = m_LastChunk;
m_LastChunk = newChunk; m_LastChunk = newChunk;
@@ -358,6 +387,8 @@ namespace OpenVulkano
} }
} }
} }
currentChunk = currentChunk->m_next;
} }
PushBack(std::move(value)); PushBack(std::move(value));
@@ -368,6 +399,7 @@ namespace OpenVulkano
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); VectorChunk* newChunk = Grow(m_LastChunk->m_capacity * GROW_FACTOR);
m_Capacity += m_LastChunk->m_capacity * GROW_FACTOR;
m_LastChunk->m_next = newChunk; m_LastChunk->m_next = newChunk;
newChunk->m_prev = m_LastChunk; newChunk->m_prev = m_LastChunk;
m_LastChunk = newChunk; m_LastChunk = newChunk;
@@ -404,6 +436,8 @@ namespace OpenVulkano
} }
} }
} }
currentChunk = currentChunk->m_next;
} }
EmplaceBack(std::forward<Args>(args)...); EmplaceBack(std::forward<Args>(args)...);
@@ -416,6 +450,15 @@ namespace OpenVulkano
return; // return? or make return; // return? or make
} }
if (m_LastChunk->m_nextIndex == -1)
{
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_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_nextIndex--;
@@ -480,9 +523,9 @@ namespace OpenVulkano
VectorChunk* currentChunk = m_FirstChunk; VectorChunk* currentChunk = m_FirstChunk;
while (currentChunk) while (currentChunk)
{ {
if (index + currentChunk->m_size > it.m_index) if (index + currentChunk->m_size > it.GetIndex())
{ {
size_t realIndex = currentChunk->GetRealIndex(it.m_index); size_t realIndex = currentChunk->GetRealIndex(it.GetIndex());
currentChunk->m_data[realIndex].~T(); currentChunk->m_data[realIndex].~T();
currentChunk->m_occupiedIndices[realIndex] = false; currentChunk->m_occupiedIndices[realIndex] = false;
currentChunk->m_size--; currentChunk->m_size--;
@@ -496,7 +539,7 @@ namespace OpenVulkano
} }
} }
T& operator[](size_t index) { return At(index); } T& operator[](size_t index) noexcept { return At(index); }
T& At(size_t index) T& At(size_t index)
{ {
if (index >= m_Size) [[unlikely]] if (index >= m_Size) [[unlikely]]
@@ -508,6 +551,39 @@ namespace OpenVulkano
return handle.first->GetAlignedData(handle.second); return handle.first->GetAlignedData(handle.second);
} }
bool Contains(size_t index) noexcept
{
if (index >= m_Size)
{
return false;
}
auto handle = FindChunk(index);
return handle.first->m_occupiedIndices[handle.second];
}
/// std version of contains
bool contains(size_t index) noexcept { return Contains(index); }
void Clear()
{
VectorChunk* currentChunk = m_FirstChunk;
while (currentChunk)
{
VectorChunk* nextChunk = currentChunk->m_next;
delete currentChunk;
currentChunk = nextChunk;
}
m_FirstChunk = Grow(DEFAULT_CHUNK_SIZE);
m_LastChunk = m_FirstChunk;
m_Capacity = DEFAULT_CHUNK_SIZE;
m_Size = 0;
}
/// std version of clear
void clear() { Clear(); }
/// std version of at /// std version of at
T& at(size_t index) { return At(index); } T& at(size_t index) { return At(index); }

View File

@@ -45,69 +45,43 @@ TEST_CASE("BinSearchArrayMap With Default")
map.Remove(16); map.Remove(16);
map.Remove(23); map.Remove(23);
map.Remove(48); map.Remove(48);
REQUIRE(map[49] == "49");
printf("ARRAY WITH DEFAULT\n");
for (int i = 0; i < 50; i++)
{
if (map.Contains(i))
{
printf("index: %d, value: %s\n", i, map[i].c_str());
}
else
{
printf("index: %d, value: %s\n", i, "EMPTY");
}
}
} }
} }
//TEST_CASE("BinSearchArrayMap With StableVector") TEST_CASE("BinSearchArrayMap With StableVector")
//{ {
// SECTION("Insert") SECTION("Insert")
// { {
// BinSearchArrayMap<int, std::string, std::pair, StableVector> map; BinSearchArrayMap<int, std::string, std::pair, StableVector> map;
//
// for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
// { {
// map.Insert(i, std::to_string(i)); map.Insert(i, std::to_string(i));
// } }
//
// REQUIRE(map.Size() == 50); REQUIRE(map.Size() == 50);
// REQUIRE(map.Get(16) == "16"); REQUIRE(map.Get(16) == "16");
// REQUIRE(map.Get(23) == "23"); REQUIRE(map.Get(23) == "23");
// REQUIRE(map.Get(48) == "48"); REQUIRE(map.Get(48) == "48");
// } }
//
// SECTION("Remove") SECTION("Remove")
// { {
// BinSearchArrayMap<int, std::string, std::pair, StableVector> map; BinSearchArrayMap<int, std::string, std::pair, StableVector> map;
//
// for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
// { {
// map.Insert(i, std::to_string(i)); map.Insert(i, std::to_string(i));
// } }
//
// map.Remove(16); map.Remove(16);
// map.Remove(23); map.Remove(23);
// map.Remove(48);
// if (map.Contains(49))
// { printf("ARRAY WITH STABLE VECTOR\n");
// printf("index: %d, value: %s\n", 49, map[49].c_str()); for (int i = 0; i < 50; i++)
// } {
// printf("index: %d, value: %s\n", i, map[i].c_str());
// printf("ARRAY WITH STABLE VECTOR\n"); }
// for (int i = 0; i < 50; i++) }
// { }
// if (map.Contains(i))
// {
// printf("index: %d, value: %s\n", i, map[i].c_str());
// }
// else
// {
// printf("index: %d, value: %s\n", i, "EMPTY");
// }
// }
// }
//}

View File

@@ -4,189 +4,189 @@
using namespace OpenVulkano; using namespace OpenVulkano;
//struct Test struct Test
//{ {
// uint32_t mValue; uint32_t mValue;
// Test(uint32_t value) : mValue(value) {} Test(uint32_t value) : mValue(value) {}
// Test() : mValue(0) {} Test() : mValue(0) {}
//}; };
//
//static int incrementCounter = 0; static int incrementCounter = 0;
//static int decrementCounter = 0; static int decrementCounter = 0;
//
//struct TestCount struct TestCount
//{ {
// TestCount() : m_value("") { ++incrementCounter; } TestCount() : m_value("") { ++incrementCounter; }
// TestCount(const std::string& val) : m_value(val) { ++incrementCounter; } TestCount(const std::string& val) : m_value(val) { ++incrementCounter; }
// TestCount(TestCount&& other) noexcept : m_value(std::move(other.m_value)) { ++incrementCounter; } TestCount(TestCount&& other) noexcept : m_value(std::move(other.m_value)) { ++incrementCounter; }
// TestCount(const TestCount& other) : m_value(other.m_value) { ++incrementCounter; } TestCount(const TestCount& other) : m_value(other.m_value) { ++incrementCounter; }
//
// TestCount& operator=(const TestCount& other) TestCount& operator=(const TestCount& other)
// { {
// m_value = other.m_value; m_value = other.m_value;
// return *this; return *this;
// } }
//
// TestCount& operator=(TestCount&& other) noexcept TestCount& operator=(TestCount&& other) noexcept
// { {
// m_value = std::move(other.m_value); m_value = std::move(other.m_value);
// return *this; return *this;
// } }
//
// ~TestCount() { ++decrementCounter; } ~TestCount() { ++decrementCounter; }
//
// std::string m_value; std::string m_value;
//}; };
//
//TEST_CASE("ChunkVector") TEST_CASE("ChunkVector")
//{ {
// SECTION("PushBack") SECTION("PushBack")
// { {
// StableVector<uint32_t> vec; StableVector<uint32_t> vec;
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// vec.PushBack(i); vec.PushBack(i);
// } }
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
// REQUIRE(vec.Capacity() == 224); // 32 + 64 + 128 = 3 | previous chunk size multiplied by 2 REQUIRE(vec.Capacity() == 224); // 32 + 64 + 128 = 3 | previous chunk size multiplied by 2
// } }
//
// SECTION("EmplaceBack") SECTION("EmplaceBack")
// { {
// StableVector<Test> vec; StableVector<Test> vec;
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// vec.EmplaceBack(i); vec.EmplaceBack(i);
// } }
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// REQUIRE(vec[i].mValue == i); REQUIRE(vec[i].mValue == i);
// } }
// } }
//
// SECTION("PopBack") SECTION("PopBack")
// { {
// StableVector<uint32_t> vec; StableVector<uint32_t> vec;
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// vec.PushBack(i); vec.PushBack(i);
// } }
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
//
// uint64_t tempVal = vec.Capacity(); uint64_t tempVal = vec.Capacity();
//
// for (uint32_t i = 0; i < 50; ++i) for (uint32_t i = 0; i < 50; ++i)
// { {
// vec.PopBack(); vec.PopBack();
// } }
//
// REQUIRE(vec.Size() == 50); REQUIRE(vec.Size() == 50);
// REQUIRE(vec.Capacity() == tempVal); REQUIRE(vec.Capacity() == tempVal);
// } }
//
// SECTION("Clear") SECTION("Clear")
// { {
// StableVector<uint32_t> vec; StableVector<uint32_t> vec;
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// vec.PushBack(i); vec.PushBack(i);
// } }
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
//
// vec.Clear(); vec.Clear();
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
// } }
//
// SECTION("Add/Fill") SECTION("Add/Fill")
// { {
// StableVector<std::string> vec; StableVector<std::string> vec;
//
// REQUIRE(vec.Size() == 0); REQUIRE(vec.Size() == 0);
// REQUIRE(vec.Capacity() == 32); REQUIRE(vec.Capacity() == 32);
//
// for (uint32_t i = 0; i < 100; ++i) for (uint32_t i = 0; i < 100; ++i)
// { {
// vec.PushBack("a"); vec.PushBack("a");
// } }
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
//
// vec.Remove(56); vec.Remove(56);
// REQUIRE(vec[56] == "a"); REQUIRE(vec[56] == "a");
//
// vec.Add("z"); vec.Push("z");
//
// REQUIRE(vec.Size() == 100); REQUIRE(vec.Size() == 100);
// REQUIRE(vec[56] == "z"); REQUIRE(vec[56] == "z");
// } }
//
// SECTION("Correct Initialization") SECTION("Correct Initialization")
// { {
// StableVector<TestCount> vec; StableVector<TestCount> vec;
//
// REQUIRE(incrementCounter == 0); REQUIRE(incrementCounter == 0);
// REQUIRE(decrementCounter == 0); REQUIRE(decrementCounter == 0);
//
// vec.EmplaceBack("a"); vec.EmplaceBack("a");
//
// REQUIRE(incrementCounter == 1); REQUIRE(incrementCounter == 1);
// REQUIRE(decrementCounter == 0); REQUIRE(decrementCounter == 0);
//
// vec.PushBack(TestCount("b")); vec.PushBack(TestCount("b"));
//
// REQUIRE(incrementCounter == 3); REQUIRE(incrementCounter == 3);
// REQUIRE(decrementCounter == 1); REQUIRE(decrementCounter == 1);
//
// TestCount testClass = TestCount("c"); TestCount testClass = TestCount("c");
// vec.PushBack(std::move(testClass)); vec.PushBack(std::move(testClass));
//
// REQUIRE(incrementCounter == 5); REQUIRE(incrementCounter == 5);
// REQUIRE(decrementCounter == 1); REQUIRE(decrementCounter == 1);
//
// vec.Clear(); vec.Clear();
//
// REQUIRE(incrementCounter == 5); REQUIRE(incrementCounter == 5);
// REQUIRE(decrementCounter == 4); REQUIRE(decrementCounter == 4);
//
// vec.PushBack(TestCount("d")); vec.PushBack(TestCount("d"));
//
// REQUIRE(incrementCounter == 7); REQUIRE(incrementCounter == 7);
// REQUIRE(decrementCounter == 5); REQUIRE(decrementCounter == 5);
//
// TestCount testClass2 = TestCount("e"); TestCount testClass2 = TestCount("e");
// vec.PushBack(testClass2); vec.PushBack(testClass2);
//
// REQUIRE(incrementCounter == 9); REQUIRE(incrementCounter == 9);
// REQUIRE(decrementCounter == 5); REQUIRE(decrementCounter == 5);
// } }
//
// SECTION("Out of scope check") SECTION("Out of scope check")
// { {
// REQUIRE(incrementCounter == 9); REQUIRE(incrementCounter == 9);
// REQUIRE(decrementCounter == 9); REQUIRE(decrementCounter == 9);
// } }
//} }