From ca8070ef71b8f047b91174d318f626887a342569 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 2 Nov 2021 19:42:00 +0100 Subject: [PATCH 1/5] Map changes --- .vscode/c_cpp_properties.json | 20 ++++ .vscode/launch.json | 11 ++ .vscode/settings.json | 9 +- CMakeLists.txt | 2 + compile_commands.json | 1 + src/Engine/Containers/Array.h | 2 +- src/Engine/Containers/Map.h | 46 +++++--- src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 3 +- src/Engine/MinimalEngine.h | 47 +++++---- test/Engine/Containers/Array.cpp | 1 - test/Engine/Containers/Map.cpp | 110 +++++++++++--------- test/Engine/EngineTest.cpp | 13 +++ 12 files changed, 168 insertions(+), 97 deletions(-) create mode 120000 compile_commands.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 5cffc62..dbec570 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -19,6 +19,26 @@ ] }, "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe" + }, + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/src/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools", + "cppStandard": "c++20", + "browse": { + "path": [ + "external/**" + ] + }, + "compilerPath": "/usr/bin/g++" } ], "version": 4 diff --git a/.vscode/launch.json b/.vscode/launch.json index fd0efbb..cba0aba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -62,6 +62,17 @@ "traceResponse": true } }, + { + "name": "Test (Linux)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceRoot}/bin/Debug/Seele_unit_tests", + "args": [], + "stopAtEntry": false, + "console": "internalConsole", + "cwd": "${workspaceRoot}/bin/Debug", + "environment": [], + }, { "name": "Test", "type": "cppvsdbg", diff --git a/.vscode/settings.json b/.vscode/settings.json index 63892bb..86c9ad4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -124,15 +124,10 @@ "-Wno-dev" ], "C_Cpp.default.cppStandard": "c++20", - "C_Cpp.default.intelliSenseMode": "msvc-x64", - "C_Cpp.files.exclude": { - "**/.vscode": true, - "external/**": true - }, "files.watcherExclude": { "**/target": true }, - "C_Cpp.errorSquiggles": "Disabled", "git.ignoreSubmodules": true, - "cmake.configureOnOpen": true + "cmake.configureOnOpen": true, + "C_Cpp.intelliSenseEngineFallback": "Enabled" } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0618813..e6c62ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ set(CMAKE_CXX_STANDARD 20) # Handle superbuild first option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine) set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external) set(ASSIMP_ROOT ${EXTERNAL_ROOT}/assimp) diff --git a/compile_commands.json b/compile_commands.json new file mode 120000 index 0000000..f2b5938 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1 @@ +bin/Debug/compile_commands.json \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index d23c113..2c844dc 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -401,7 +401,7 @@ namespace Seele } void pop() { - arraySize--; + _data[arraySize--].~T(); markIteratorDirty(); } constexpr inline reference operator[](size_type index) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index c7808f1..14c24b8 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -189,7 +189,7 @@ public: : root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(Compare()) { @@ -200,7 +200,7 @@ public: , root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(comp) { @@ -210,7 +210,7 @@ public: , root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(Compare()) { @@ -221,7 +221,7 @@ public: , comp(other.comp) { root = &nodeContainer[nodeContainer.indexOf(other.root)]; - refreshIterators(); + markIteratorDirty(); } Map(Map&& other) : nodeContainer(other.nodeContainer) @@ -229,7 +229,7 @@ public: , comp(std::move(other.comp)) { root = &nodeContainer[nodeContainer.indexOf(other.root)]; - refreshIterators(); + markIteratorDirty(); } ~Map() { @@ -242,7 +242,7 @@ public: root = &nodeContainer[nodeContainer.indexOf(other.root)]; _size = other._size; comp = other.comp; - refreshIterators(); + markIteratorDirty(); } return *this; } @@ -254,14 +254,14 @@ public: root = &nodeContainer[nodeContainer.indexOf(other.root)]; _size = std::move(other._size); comp = std::move(other.comp); - refreshIterators(); + markIteratorDirty(); } return *this; } inline mapped_type& operator[](const key_type& key) { root = splay(root, key); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { root = insert(root, key); @@ -272,7 +272,7 @@ public: inline mapped_type& operator[](key_type&& key) { root = splay(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { root = insert(root, std::move(key)); @@ -283,7 +283,7 @@ public: iterator find(const key_type& key) { root = splay(root, key); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -293,7 +293,7 @@ public: iterator find(key_type&& key) { root = splay(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -303,13 +303,13 @@ public: iterator erase(const key_type& key) { root = remove(root, key); - refreshIterators(); + markIteratorDirty(); return iterator(root); } iterator erase(K&& key) { root = remove(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); return iterator(root); } void clear() @@ -317,7 +317,7 @@ public: nodeContainer.clear(); root = nullptr; _size = 0; - refreshIterators(); + markIteratorDirty(); } bool exists(key_type&& key) { @@ -486,10 +486,22 @@ private: r = splay(r->leftChild, key); r->rightChild = temp->rightChild; } - temp->leftChild = nullptr; - temp->rightChild = nullptr; + Node& lastNode = nodeContainer.back(); + size_t removedIndex = nodeContainer.indexOf(temp); + nodeContainer[removedIndex] = std::move(lastNode); + for(auto it : nodeContainer) + { + if(it.leftChild == &lastNode) + { + it.leftChild = &nodeContainer[removedIndex]; + } + if(it.rightChild == &lastNode) + { + it.rightChild = &nodeContainer[removedIndex]; + } + } + nodeContainer.pop(); _size--; - delete temp; return r; } template diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 614666f..f80bf5d 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -54,7 +54,8 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer); bufferReqInfo.buffer = buffers[i].buffer; vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements); - buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); + auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); + buffers[i].allocation = temp; vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset()); } } diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index dbc81a4..e1fd69c 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -29,14 +29,16 @@ extern Seele::Map registeredObjects; extern std::mutex registeredObjectsLock; namespace Seele { -template +template class RefPtr; -template +template class RefObject { public: - RefObject(T *ptr) - : handle(ptr), refCount(1) + RefObject(T *ptr, Deleter&& deleter) + : handle(ptr) + , deleter(std::move(deleter)) + , refCount(1) { registeredObjects[ptr] = this; } @@ -55,7 +57,7 @@ public: registeredObjects.erase(handle); } // #pragma warning( disable: 4150) - delete handle; + //deleter(handle); // #pragma warning( default: 4150) } RefObject &operator=(const RefObject &rhs) @@ -108,11 +110,12 @@ public: } private: T *handle; + Deleter deleter; std::atomic_uint64_t refCount; - friend class RefPtr; + friend class RefPtr; }; -template +template > class RefPtr { public: @@ -124,7 +127,7 @@ public: { object = nullptr; } - RefPtr(T *ptr) + RefPtr(T *ptr, Deleter deleter = Deleter()) { std::unique_lock l(registeredObjectsLock); auto registeredObj = registeredObjects.find(ptr); @@ -132,17 +135,17 @@ public: auto registeredEnd = registeredObjects.end(); if (registeredObj == registeredEnd) { - object = new RefObject(ptr); + object = new RefObject(ptr, std::move(deleter)); l.unlock(); } else { l.unlock(); - object = (RefObject *)registeredObj->value; + object = (RefObject *)registeredObj->value; object->addRef(); } } - explicit RefPtr(RefObject *other) + explicit RefPtr(RefObject *other) : object(other) { object->addRef(); @@ -166,12 +169,12 @@ public: { F *f = other.getObject()->getHandle(); assert(static_cast(f)); - object = (RefObject *)other.getObject(); + object = (RefObject *)other.getObject(); object->addRef(); } - template - RefPtr cast() + template > + RefPtr cast() { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -179,12 +182,12 @@ public: { return nullptr; } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); } - template - const RefPtr cast() const + template > + const RefPtr cast() const { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -192,8 +195,8 @@ public: { return nullptr; } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); } RefPtr &operator=(const RefPtr &other) @@ -254,7 +257,7 @@ public: assert(object != nullptr); return object->handle; } - RefObject *getObject() const + RefObject *getObject() const { return object; } @@ -268,7 +271,7 @@ public: } private: - RefObject *object; + RefObject *object; friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int) diff --git a/test/Engine/Containers/Array.cpp b/test/Engine/Containers/Array.cpp index 8def8d1..00c13ec 100644 --- a/test/Engine/Containers/Array.cpp +++ b/test/Engine/Containers/Array.cpp @@ -3,7 +3,6 @@ #include "MinimalEngine.h" #include #include -#define BOOST_TEST_MODULE SeeleEngine #include using namespace Seele; diff --git a/test/Engine/Containers/Map.cpp b/test/Engine/Containers/Map.cpp index 2ea2c79..894f26e 100644 --- a/test/Engine/Containers/Map.cpp +++ b/test/Engine/Containers/Map.cpp @@ -8,71 +8,85 @@ BOOST_AUTO_TEST_SUITE(CachedMap) BOOST_AUTO_TEST_CASE(insert_find_basic) { - Map map; - map[2] = 3; - map[1] = 5; - map[6] = 4; - map[4] = 7; - BOOST_REQUIRE_EQUAL(map[2], 3); - BOOST_REQUIRE_EQUAL(map[1], 5); - BOOST_REQUIRE_EQUAL(map[6], 4); - BOOST_REQUIRE_EQUAL(map[4], 7); - map[2] = 5; - map[4] = 4; - BOOST_REQUIRE_EQUAL(map[2], 5); - BOOST_REQUIRE_EQUAL(map[4], 4); + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + BOOST_REQUIRE_EQUAL(map[2], 3); + BOOST_REQUIRE_EQUAL(map[1], 5); + BOOST_REQUIRE_EQUAL(map[6], 4); + BOOST_REQUIRE_EQUAL(map[4], 7); + map[2] = 5; + map[4] = 4; + BOOST_REQUIRE_EQUAL(map[2], 5); + BOOST_REQUIRE_EQUAL(map[4], 4); } BOOST_AUTO_TEST_CASE(for_each) { - Map map; - map[2] = 3; - map[1] = 5; - map[6] = 4; - map[4] = 7; - int count = 0; - for(auto it : map) - { - count++; - } - BOOST_REQUIRE_EQUAL(count, 4); + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + int count = 0; + for(auto it : map) + { + count++; + } + BOOST_REQUIRE_EQUAL(count, 4); +} + +BOOST_AUTO_TEST_CASE(remove_entry) +{ + Map map; + map[1] = 5; + map[4] = 1; + map[2] = 6; + map[3] = 4; + map.erase(2); + BOOST_REQUIRE_EQUAL(map.size(), 3); + BOOST_REQUIRE_EQUAL(map[1], 5); + BOOST_REQUIRE_EQUAL(map[4], 1); + BOOST_REQUIRE_EQUAL(map[3], 4); } BOOST_AUTO_TEST_CASE(key_exists) { - Map map; - map[2] = 3; - BOOST_REQUIRE_EQUAL(map.exists(2), true); - BOOST_REQUIRE_EQUAL(map.exists(4), false); - map.erase(2); - BOOST_REQUIRE_EQUAL(map.exists(2), false); + Map map; + map[2] = 3; + BOOST_REQUIRE_EQUAL(map.exists(2), true); + BOOST_REQUIRE_EQUAL(map.exists(4), false); + map.erase(2); + BOOST_REQUIRE_EQUAL(map.exists(2), false); } BOOST_AUTO_TEST_CASE(custom_key) { - struct Key - { - int id; - bool operator<(const Key& other) const - { - return id < other.id; - } - }; - Map map; - map[Key{ 2 }] = 3; - map[Key{ 3 }] = 4; - BOOST_REQUIRE_EQUAL(map[Key{ 2 }], 3); - BOOST_REQUIRE_EQUAL(map[Key{ 3 }], 4); + struct Key + { + int id; + bool operator<(const Key& other) const + { + return id < other.id; + } + }; + Map map; + map[Key{ 2 }] = 3; + map[Key{ 3 }] = 4; + BOOST_REQUIRE_EQUAL(map[Key{ 2 }], 3); + BOOST_REQUIRE_EQUAL(map[Key{ 3 }], 4); } BOOST_AUTO_TEST_CASE(string_key) { - std::map map; - map["Test"] = 2; - map["Test2"] = 3; - BOOST_REQUIRE_EQUAL(map["Test"], 2); - BOOST_REQUIRE_EQUAL(map["Test2"], 3); + std::map map; + map["Test"] = 2; + map["Test2"] = 3; + BOOST_REQUIRE_EQUAL(map["Test"], 2); + BOOST_REQUIRE_EQUAL(map["Test2"], 3); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/Engine/EngineTest.cpp b/test/Engine/EngineTest.cpp index fefd4c6..ffc0742 100644 --- a/test/Engine/EngineTest.cpp +++ b/test/Engine/EngineTest.cpp @@ -1,5 +1,7 @@ #include "EngineTest.h" #include "MinimalEngine.h" +#define BOOST_TEST_MODULE SeeleEngine +#define BOOST_TEST_DYN_LINK #include using namespace Seele; @@ -18,6 +20,8 @@ struct TestStruct } uint32 data; }; + +struct DeclStruct; BOOST_AUTO_TEST_CASE(basic_refcount) { { @@ -30,7 +34,16 @@ BOOST_AUTO_TEST_CASE(basic_refcount) } BOOST_REQUIRE_EQUAL(ptr->data, 10); } + std::shared_ptr test; } +struct DeclStruct +{ + ~DeclStruct() + { + data = 10; + } + uint32 data = 20; +}; struct DerivedStruct : public TestStruct { From 97dcf25a598f967dabe37ca64e5d5d7f9f3723c0 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Thu, 4 Nov 2021 23:47:51 +0100 Subject: [PATCH 2/5] Using indices instead of pointers --- src/Engine/Containers/Array.h | 2 +- src/Engine/Containers/Map.h | 189 ++++++++++++++++++++-------------- 2 files changed, 114 insertions(+), 77 deletions(-) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 2c844dc..3afa991 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -401,7 +401,7 @@ namespace Seele } void pop() { - _data[arraySize--].~T(); + _data[--arraySize].~T(); markIteratorDirty(); } constexpr inline reference operator[](size_type index) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 14c24b8..f771d87 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -36,20 +36,25 @@ struct Map private: struct Node { - Node *leftChild; - Node *rightChild; + size_t self; + size_t leftChild; + size_t rightChild; Pair pair; Node() - : leftChild(nullptr), rightChild(nullptr), pair() + : self(-1) + , leftChild(-1) + , rightChild(-1) + , pair() { } Node(const Node& other) = default; Node(Node&& other) = default; Node& operator=(const Node& other) = default; Node& operator=(Node&& other) = default; - Node(K key) - : leftChild(nullptr) - , rightChild(nullptr) + Node(size_t self, K key) + : self(self) + , leftChild(-1) + , rightChild(-1) , pair(std::move(key)) { } @@ -73,8 +78,8 @@ public: : node(x) { } - IteratorBase(Node *x, Array &&beginIt) - : node(x), traversal(std::move(beginIt)) + IteratorBase(Node *x, Array &&beginIt, const Array* nodeContainer) + : node(x), traversal(std::move(beginIt)), nodeContainer(nodeContainer) { } IteratorBase(const IteratorBase &i) @@ -121,32 +126,34 @@ public: } IteratorBase &operator++() { - node = node->rightChild; - while (node != nullptr && node->leftChild != nullptr) + size_t nextIndex = node->rightChild; + while (nextIndex != -1 && (*nodeContainer)[nextIndex].leftChild != -1) { - traversal.add(node); - node = node->leftChild; + traversal.add(nextIndex); + nextIndex = (*nodeContainer)[nextIndex].leftChild; } - if (node == nullptr && traversal.size() > 0) + if (nextIndex == -1 && traversal.size() > 0) { - node = traversal.back(); + nextIndex = traversal.back(); traversal.pop(); } + node = nextIndex != -1 ? &(*nodeContainer)[nextIndex] : nullptr; return *this; } IteratorBase &operator--() { - node = node->leftChild; - while (node != nullptr && node->rightchild != nullptr) + size_t nextIndex = node->leftChild; + while (nextIndex != -1 && (*nodeContainer)[nextIndex].rightChild != -1) { - traversal.add(node); - node = node->rightChild; + traversal.add(nextIndex); + nextIndex = (*nodeContainer)[nextIndex].rightchild; } - if (node == nullptr && traversal.size() > 0) + if (nextIndex == -1 && traversal.size() > 0) { - node = traversal.back(); + nextIndex = traversal.back(); traversal.pop(); } + node = nextIndex != -1 ? &(*nodeContainer)[nextIndex] : nullptr; return *this; } IteratorBase operator--(int) @@ -164,7 +171,8 @@ public: private: Node *node; - Array traversal; + Array traversal; + const Array* nodeContainer; }; using Iterator = IteratorBase>; using ConstIterator = IteratorBase>; @@ -283,7 +291,7 @@ public: iterator find(const key_type& key) { root = splay(root, key); - markIteratorDirty(); + refreshIterators(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -293,7 +301,7 @@ public: iterator find(key_type&& key) { root = splay(root, std::move(key)); - markIteratorDirty(); + refreshIterators(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -303,13 +311,13 @@ public: iterator erase(const key_type& key) { root = remove(root, key); - markIteratorDirty(); + refreshIterators(); return iterator(root); } iterator erase(K&& key) { root = remove(root, std::move(key)); - markIteratorDirty(); + refreshIterators(); return iterator(root); } void clear() @@ -365,6 +373,26 @@ public: } private: + Node* leftChild(Node* node) + { + if(node->leftChild >= nodeContainer.size()) return nullptr; + return &nodeContainer[node->leftChild]; + } + Node* rightChild(Node* node) + { + if(node->rightChild >= nodeContainer.size()) return nullptr; + return &nodeContainer[node->rightChild]; + } + Node* leftChild(Node* node) const + { + if(node->leftChild >= nodeContainer.size()) return nullptr; + return &nodeContainer[node->leftChild]; + } + Node* rightChild(Node* node) const + { + if(node->rightChild >= nodeContainer.size()) return nullptr; + return &nodeContainer[node->rightChild]; + } void markIteratorDirty() { iteratorsDirty = true; @@ -377,40 +405,40 @@ private: } inline Iterator calcBeginIterator() const { - Node *beginNode = root; if (root == nullptr) { return Iterator(nullptr); } else { - Array beginTraversal; - while (beginNode != nullptr) + size_t beginIndex = root->self; + Array beginTraversal; + while (beginIndex < nodeContainer.size()) { - beginTraversal.add(beginNode); - beginNode = beginNode->leftChild; + beginTraversal.add(beginIndex); + beginIndex = nodeContainer[beginIndex].leftChild; } - beginNode = beginTraversal.back(); + Node* beginNode = &nodeContainer[beginTraversal.back()]; beginTraversal.pop(); - return Iterator(beginNode, std::move(beginTraversal)); + return Iterator(beginNode, std::move(beginTraversal), &nodeContainer); } } inline Iterator calcEndIterator() const { - Node *endNode = root; if (root == nullptr) { return Iterator(nullptr); } else { - Array endTraversal; - while (endNode != nullptr) + size_t endIndex = root->self; + Array endTraversal; + while (endIndex < nodeContainer.size()) { - endTraversal.add(endNode); - endNode = endNode->rightChild; + endTraversal.add(endIndex); + endIndex = nodeContainer[endIndex].rightChild; } - return Iterator(endNode, std::move(endTraversal)); + return Iterator(nullptr, std::move(endTraversal), &nodeContainer); } } Array nodeContainer; @@ -422,16 +450,16 @@ private: Compare comp; Node *rotateRight(Node *node) { - Node *y = node->leftChild; + Node *y = leftChild(node); node->leftChild = y->rightChild; - y->rightChild = node; + y->rightChild = node->self; return y; } Node *rotateLeft(Node *node) { - Node *y = node->rightChild; + Node *y = rightChild(node); node->rightChild = y->leftChild; - y->leftChild = node; + y->leftChild = node->self; return y; } template @@ -439,26 +467,26 @@ private: { if (r == nullptr) { - return &nodeContainer.emplace(std::forward(key)); + return &nodeContainer.emplace(nodeContainer.size(), std::forward(key)); } r = splay(r, key); if (!(comp(r->pair.key, key) || comp(key, r->pair.key))) return r; - Node *newNode = &nodeContainer.emplace(std::forward(key)); + Node *newNode = &nodeContainer.emplace(nodeContainer.size(), std::forward(key)); if (comp(key, r->pair.key)) { - newNode->rightChild = r; + newNode->rightChild = r->self; newNode->leftChild = r->leftChild; - r->leftChild = nullptr; + r->leftChild = -1; } else { - newNode->leftChild = r; + newNode->leftChild = r->self; newNode->rightChild = r->rightChild; - r->rightChild = nullptr; + r->rightChild = -1; } return newNode; } @@ -474,31 +502,36 @@ private: if (comp(r->pair.key, key) || comp(key, r->pair.key)) return r; - if (!r->leftChild) + if (r->leftChild == -1) { temp = r; - r = r->rightChild; + r = rightChild(r); } else { temp = r; - r = splay(r->leftChild, key); + r = splay(leftChild(r), key); r->rightChild = temp->rightChild; } Node& lastNode = nodeContainer.back(); - size_t removedIndex = nodeContainer.indexOf(temp); - nodeContainer[removedIndex] = std::move(lastNode); - for(auto it : nodeContainer) + size_t removedIndex = temp->self; + //Arrays can only pop back, so we need to move the last element to the deleted index + if(removedIndex != lastNode.self) { - if(it.leftChild == &lastNode) + nodeContainer[removedIndex] = std::move(lastNode); + for(auto it : nodeContainer) { - it.leftChild = &nodeContainer[removedIndex]; - } - if(it.rightChild == &lastNode) - { - it.rightChild = &nodeContainer[removedIndex]; + if(it.leftChild == lastNode.self) + { + it.leftChild = removedIndex; + } + if(it.rightChild == lastNode.self) + { + it.rightChild = removedIndex; + } } + lastNode.self = removedIndex; } nodeContainer.pop(); _size--; @@ -514,46 +547,50 @@ private: if (comp(key, r->pair.key)) { - if (r->leftChild == nullptr) + if (r->leftChild >= nodeContainer.size()) return r; - if (comp(key, r->leftChild->pair.key)) + if (comp(key, leftChild(r)->pair.key)) { - r->leftChild->leftChild = splay(r->leftChild->leftChild, key); + Node* res = splay(leftChild(leftChild(r)), key); + leftChild(r)->leftChild = res ? res->self : -1; r = rotateRight(r); } - else if (comp(r->leftChild->pair.key, key)) + else if (comp(leftChild(r)->pair.key, key)) { - r->leftChild->rightChild = splay(r->leftChild->rightChild, key); + Node* res = splay(rightChild(leftChild(r)), key); + leftChild(r)->rightChild = res ? res->self : -1; - if (r->leftChild->rightChild != nullptr) + if (leftChild(r)->rightChild < nodeContainer.size()) { - r->leftChild = rotateLeft(r->leftChild); + r->leftChild = rotateLeft(leftChild(r))->self; } } - return (r->leftChild == nullptr) ? r : rotateRight(r); + return (r->leftChild >= nodeContainer.size()) ? r : rotateRight(r); } else { - if (r->rightChild == nullptr) + if (r->rightChild >= nodeContainer.size()) return r; - if (comp(key, r->rightChild->pair.key)) + if (comp(key, rightChild(r)->pair.key)) { - r->rightChild->leftChild = splay(r->rightChild->leftChild, key); + Node* res = splay(leftChild(rightChild(r)), key); + rightChild(r)->leftChild = res ? res->self : -1; - if (r->rightChild->leftChild != nullptr) + if (rightChild(r)->leftChild < nodeContainer.size()) { - r->rightChild = rotateRight(r->rightChild); + r->rightChild = rotateRight(rightChild(r))->self; } } - else if (comp(r->rightChild->pair.key, key)) + else if (comp(rightChild(r)->pair.key, key)) { - r->rightChild->rightChild = splay(r->rightChild->rightChild, key); + Node* res = splay(rightChild(rightChild(r)), key); + rightChild(r)->rightChild = res ? res->self : -1; r = rotateLeft(r); } - return (r->rightChild == nullptr) ? r : rotateLeft(r); + return (r->rightChild >= nodeContainer.size()) ? r : rotateLeft(r); } } }; From 6708b08d23c8623e4befb174349c6afef35a73a0 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Mon, 8 Nov 2021 15:39:46 +0100 Subject: [PATCH 3/5] Something causing an infinite recursion... --- src/Engine/Containers/Map.h | 299 +++++++++--------- .../Graphics/Vulkan/VulkanAllocator.cpp | 2 +- 2 files changed, 156 insertions(+), 145 deletions(-) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index f771d87..f3a817d 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -36,13 +36,11 @@ struct Map private: struct Node { - size_t self; size_t leftChild; size_t rightChild; Pair pair; Node() - : self(-1) - , leftChild(-1) + : leftChild(-1) , rightChild(-1) , pair() { @@ -51,9 +49,8 @@ private: Node(Node&& other) = default; Node& operator=(const Node& other) = default; Node& operator=(Node&& other) = default; - Node(size_t self, K key) - : self(self) - , leftChild(-1) + Node(K key) + : leftChild(-1) , rightChild(-1) , pair(std::move(key)) { @@ -74,27 +71,28 @@ public: using reference = PairType&; using pointer = PairType*; - IteratorBase(Node *x = nullptr) + IteratorBase(size_t x = -1) : node(x) { } - IteratorBase(Node *x, Array &&beginIt, const Array* nodeContainer) + IteratorBase(size_t x, const Array* nodeContainer, Array &&beginIt = Array()) : node(x), traversal(std::move(beginIt)), nodeContainer(nodeContainer) { } IteratorBase(const IteratorBase &i) - : node(i.node), traversal(i.traversal) + : node(i.node), traversal(i.traversal), nodeContainer(i.nodeContainer) { } IteratorBase(IteratorBase&& i) - : node(std::move(i.node)), traversal(std::move(i.traversal)) + : node(std::move(i.node)), traversal(std::move(i.traversal)), nodeContainer(i.nodeContainer) { } IteratorBase& operator=(const IteratorBase& other) { if(this != &other) { - node = other.node; // No copy, since no ownership + node = other.node; + nodeContainer = other.nodeContainer; traversal = other.traversal; } return *this; @@ -104,17 +102,18 @@ public: if(this != &other) { node = std::move(other.node); + nodeContainer = std::move(other.nodeContainer); traversal = std::move(other.traversal); } return *this; } reference operator*() const { - return node->pair; + return getNode()->pair; } pointer operator->() const { - return &node->pair; + return &(getNode()->pair); } inline bool operator!=(const IteratorBase &other) { @@ -126,34 +125,36 @@ public: } IteratorBase &operator++() { - size_t nextIndex = node->rightChild; - while (nextIndex != -1 && (*nodeContainer)[nextIndex].leftChild != -1) + node = getNode()->rightChild; + while (node < nodeContainer->size() + && getNode()->leftChild < nodeContainer->size()) { - traversal.add(nextIndex); - nextIndex = (*nodeContainer)[nextIndex].leftChild; + traversal.add(node); + node = getNode()->leftChild; } - if (nextIndex == -1 && traversal.size() > 0) + if (node >= nodeContainer->size() + && traversal.size() > 0) { - nextIndex = traversal.back(); + node = traversal.back(); traversal.pop(); } - node = nextIndex != -1 ? &(*nodeContainer)[nextIndex] : nullptr; return *this; } IteratorBase &operator--() { - size_t nextIndex = node->leftChild; - while (nextIndex != -1 && (*nodeContainer)[nextIndex].rightChild != -1) + node = getNode()->leftChild; + while (node < nodeContainer->size() + && getNode()->rightChild < nodeContainer->size()) { - traversal.add(nextIndex); - nextIndex = (*nodeContainer)[nextIndex].rightchild; + traversal.add(node); + node = getNode()->rightchild; } - if (nextIndex == -1 && traversal.size() > 0) + if (node >= nodeContainer->size() + && traversal.size() > 0) { - nextIndex = traversal.back(); + node = traversal.back(); traversal.pop(); } - node = nextIndex != -1 ? &(*nodeContainer)[nextIndex] : nullptr; return *this; } IteratorBase operator--(int) @@ -170,7 +171,11 @@ public: } private: - Node *node; + Node* getNode() const + { + return &(*nodeContainer)[node]; + } + size_t node; Array traversal; const Array* nodeContainer; }; @@ -194,9 +199,9 @@ public: using const_reverse_iterator = std::reverse_iterator; Map() - : root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) + : root(-1) + , beginIt(-1) + , endIt(-1) , iteratorsDirty(true) , _size(0) , comp(Compare()) @@ -205,9 +210,9 @@ public: explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) : nodeContainer(alloc) - , root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) + , root(-1) + , beginIt(-1) + , endIt(-1) , iteratorsDirty(true) , _size(0) , comp(comp) @@ -215,9 +220,9 @@ public: } explicit Map(const Allocator& alloc) : nodeContainer(alloc) - , root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) + , root(-1) + , beginIt(-1) + , endIt(-1) , iteratorsDirty(true) , _size(0) , comp(Compare()) @@ -225,18 +230,18 @@ public: } Map(const Map& other) : nodeContainer(other.nodeContainer) + , root(other.root) , _size(other._size) , comp(other.comp) { - root = &nodeContainer[nodeContainer.indexOf(other.root)]; markIteratorDirty(); } Map(Map&& other) : nodeContainer(other.nodeContainer) + , root(std::move(other.root)) , _size(std::move(other._size)) , comp(std::move(other.comp)) { - root = &nodeContainer[nodeContainer.indexOf(other.root)]; markIteratorDirty(); } ~Map() @@ -247,7 +252,7 @@ public: if(this != &other) { nodeContainer = other.nodeContainer; - root = &nodeContainer[nodeContainer.indexOf(other.root)]; + root = other.root; _size = other._size; comp = other.comp; markIteratorDirty(); @@ -259,7 +264,7 @@ public: if(this != &other) { nodeContainer = std::move(other.nodeContainer); - root = &nodeContainer[nodeContainer.indexOf(other.root)]; + root = std::move(other.root); _size = std::move(other._size); comp = std::move(other.comp); markIteratorDirty(); @@ -270,60 +275,68 @@ public: { root = splay(root, key); markIteratorDirty(); - if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) + if (root >= nodeContainer.size() + || comp(getNode(root)->pair.key, key) + || comp(key, getNode(root)->pair.key)) { root = insert(root, key); _size++; } - return root->pair.value; + return getNode(root)->pair.value; } inline mapped_type& operator[](key_type&& key) { root = splay(root, std::move(key)); markIteratorDirty(); - if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) + if (root >= nodeContainer.size() + || comp(getNode(root)->pair.key, key) + || comp(key, getNode(root)->pair.key)) { root = insert(root, std::move(key)); _size++; } - return root->pair.value; + return getNode(root)->pair.value; } iterator find(const key_type& key) { root = splay(root, key); refreshIterators(); - if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) + if (!isValid(root) + || comp(getNode(root)->pair.key, key) + || comp(key, getNode(root)->pair.key)) { return endIt; } - return iterator(root); + return iterator(root, &nodeContainer); } iterator find(key_type&& key) { root = splay(root, std::move(key)); refreshIterators(); - if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) + if (!isValid(root) + || comp(getNode(root)->pair.key, key) + || comp(key, getNode(root)->pair.key)) { return endIt; } - return iterator(root); + return iterator(root, &nodeContainer); } iterator erase(const key_type& key) { root = remove(root, key); refreshIterators(); - return iterator(root); + return iterator(root, &nodeContainer); } iterator erase(K&& key) { root = remove(root, std::move(key)); refreshIterators(); - return iterator(root); + return iterator(root, &nodeContainer); } void clear() { nodeContainer.clear(); - root = nullptr; + root = -1; _size = 0; markIteratorDirty(); } @@ -373,25 +386,14 @@ public: } private: - Node* leftChild(Node* node) + Node* getNode(size_t index) const { - if(node->leftChild >= nodeContainer.size()) return nullptr; - return &nodeContainer[node->leftChild]; + if(!isValid(index)) return nullptr; + return &nodeContainer[index]; } - Node* rightChild(Node* node) + inline bool isValid(size_t index) const { - if(node->rightChild >= nodeContainer.size()) return nullptr; - return &nodeContainer[node->rightChild]; - } - Node* leftChild(Node* node) const - { - if(node->leftChild >= nodeContainer.size()) return nullptr; - return &nodeContainer[node->leftChild]; - } - Node* rightChild(Node* node) const - { - if(node->rightChild >= nodeContainer.size()) return nullptr; - return &nodeContainer[node->rightChild]; + return index < nodeContainer.size(); } void markIteratorDirty() { @@ -405,192 +407,201 @@ private: } inline Iterator calcBeginIterator() const { - if (root == nullptr) + if (!isValid(root)) { - return Iterator(nullptr); + return Iterator(-1, &nodeContainer); } else { - size_t beginIndex = root->self; + size_t beginIndex = root; Array beginTraversal; - while (beginIndex < nodeContainer.size()) + while (isValid(beginIndex)) { beginTraversal.add(beginIndex); - beginIndex = nodeContainer[beginIndex].leftChild; + beginIndex = getNode(beginIndex)->leftChild; } - Node* beginNode = &nodeContainer[beginTraversal.back()]; + beginIndex = beginTraversal.back(); beginTraversal.pop(); - return Iterator(beginNode, std::move(beginTraversal), &nodeContainer); + return Iterator(beginIndex, &nodeContainer, std::move(beginTraversal)); } } inline Iterator calcEndIterator() const { - if (root == nullptr) + if (!isValid(root)) { - return Iterator(nullptr); + return Iterator(-1, &nodeContainer); } else { - size_t endIndex = root->self; + size_t endIndex = root; Array endTraversal; - while (endIndex < nodeContainer.size()) + while (isValid(endIndex)) { endTraversal.add(endIndex); - endIndex = nodeContainer[endIndex].rightChild; + endIndex = getNode(endIndex)->rightChild; } - return Iterator(nullptr, std::move(endTraversal), &nodeContainer); + return Iterator(-1, &nodeContainer, std::move(endTraversal)); } } Array nodeContainer; - Node *root; + size_t root; Iterator beginIt; Iterator endIt; bool iteratorsDirty; uint32 _size; Compare comp; - Node *rotateRight(Node *node) + size_t rotateRight(size_t node) { - Node *y = leftChild(node); - node->leftChild = y->rightChild; - y->rightChild = node->self; - return y; + Node* x = getNode(node); + size_t res = x->leftChild; + Node* y = getNode(x->leftChild); + x->leftChild = y->rightChild; + y->rightChild = node; + return res; } - Node *rotateLeft(Node *node) + size_t rotateLeft(size_t node) { - Node *y = rightChild(node); - node->rightChild = y->leftChild; - y->leftChild = node->self; - return y; + Node* x = getNode(node); + size_t res = x->rightChild; + Node* y = getNode(x->rightChild); + x->rightChild = y->leftChild; + y->leftChild = node; + return res; } template - Node *insert(Node *r, KeyType&& key) + size_t insert(size_t r, KeyType&& key) { - if (r == nullptr) + if (!isValid(r)) { - return &nodeContainer.emplace(nodeContainer.size(), std::forward(key)); + nodeContainer.emplace(std::forward(key)); + return 0; } r = splay(r, key); - if (!(comp(r->pair.key, key) || comp(key, r->pair.key))) + if (!(comp(node->pair.key, key) || comp(key, node->pair.key))) return r; - Node *newNode = &nodeContainer.emplace(nodeContainer.size(), std::forward(key)); + Node* node = getNode(r); + Node *newNode = &nodeContainer.emplace(std::forward(key)); - if (comp(key, r->pair.key)) + if (comp(key, node->pair.key)) { - newNode->rightChild = r->self; - newNode->leftChild = r->leftChild; - r->leftChild = -1; + newNode->rightChild = r; + newNode->leftChild = node->leftChild; + node->leftChild = -1; } else { - newNode->leftChild = r->self; - newNode->rightChild = r->rightChild; - r->rightChild = -1; + newNode->leftChild = r; + newNode->rightChild = node->rightChild; + node->rightChild = -1; } - return newNode; + return nodeContainer.size() - 1; } template - Node *remove(Node *r, KeyType&& key) + size_t remove(size_t r, KeyType&& key) { - Node *temp; - if (!r) - return nullptr; + size_t temp; + if (!isValid(r)) + return -1; r = splay(r, key); + Node* node = getNode(r); - if (comp(r->pair.key, key) || comp(key, r->pair.key)) + if (comp(node->pair.key, key) || comp(key, node->pair.key)) return r; - if (r->leftChild == -1) + if (!isValid(node->leftChild)) { temp = r; - r = rightChild(r); + r = node->rightChild; } else { temp = r; - r = splay(leftChild(r), key); - r->rightChild = temp->rightChild; + r = splay(node->leftChild, key); + node = getNode(r); + node->rightChild = getNode(temp)->rightChild; } Node& lastNode = nodeContainer.back(); - size_t removedIndex = temp->self; + size_t lastIndex = nodeContainer.size() - 1; + size_t removedIndex = temp; //Arrays can only pop back, so we need to move the last element to the deleted index - if(removedIndex != lastNode.self) + if(removedIndex != lastIndex) { nodeContainer[removedIndex] = std::move(lastNode); - for(auto it : nodeContainer) + for(auto& it : nodeContainer) { - if(it.leftChild == lastNode.self) + if(it.leftChild == lastIndex) { it.leftChild = removedIndex; } - if(it.rightChild == lastNode.self) + if(it.rightChild == lastIndex) { it.rightChild = removedIndex; } } - lastNode.self = removedIndex; } nodeContainer.pop(); _size--; return r; } template - Node *splay(Node *r, KeyType&& key) + size_t splay(size_t r, KeyType&& key) { - if (r == nullptr || !(comp(r->pair.key, key) || comp(key, r->pair.key))) + Node* node = getNode(r); + if (node == nullptr + || !(comp(node->pair.key, key) + || comp(key, node->pair.key))) { return r; } - - if (comp(key, r->pair.key)) + if (comp(key, node->pair.key)) { - if (r->leftChild >= nodeContainer.size()) + if (!isValid(node->leftChild)) return r; - if (comp(key, leftChild(r)->pair.key)) + if (comp(key, getNode(node->leftChild)->pair.key)) { - Node* res = splay(leftChild(leftChild(r)), key); - leftChild(r)->leftChild = res ? res->self : -1; + getNode(node->leftChild)->leftChild = splay(getNode(node->leftChild)->leftChild, key); r = rotateRight(r); + node = getNode(r); } - else if (comp(leftChild(r)->pair.key, key)) + else if (comp(getNode(node->leftChild)->pair.key, key)) { - Node* res = splay(rightChild(leftChild(r)), key); - leftChild(r)->rightChild = res ? res->self : -1; + getNode(node->leftChild)->rightChild = splay(getNode(node->leftChild)->rightChild, key); - if (leftChild(r)->rightChild < nodeContainer.size()) + if (isValid(getNode(node->leftChild)->rightChild)) { - r->leftChild = rotateLeft(leftChild(r))->self; + node->leftChild = rotateLeft(node->leftChild); } } - return (r->leftChild >= nodeContainer.size()) ? r : rotateRight(r); + return (!isValid(node->leftChild)) ? r : rotateRight(r); } else { - if (r->rightChild >= nodeContainer.size()) + if (!isValid(node->rightChild)) return r; - if (comp(key, rightChild(r)->pair.key)) + if (comp(key, getNode(node->rightChild)->pair.key)) { - Node* res = splay(leftChild(rightChild(r)), key); - rightChild(r)->leftChild = res ? res->self : -1; + getNode(node->rightChild)->leftChild = splay(getNode(node->rightChild)->leftChild, key); - if (rightChild(r)->leftChild < nodeContainer.size()) + if (isValid(getNode(node->rightChild)->leftChild)) { - r->rightChild = rotateRight(rightChild(r))->self; + node->rightChild = rotateRight(node->rightChild); } } - else if (comp(rightChild(r)->pair.key, key)) + else if (comp(getNode(node->rightChild)->pair.key, key)) { - Node* res = splay(rightChild(rightChild(r)), key); - rightChild(r)->rightChild = res ? res->self : -1; + getNode(node->rightChild)->rightChild = splay(getNode(node->rightChild)->rightChild, key); + r = rotateLeft(r); + node = getNode(r); } - return (r->rightChild >= nodeContainer.size()) ? r : rotateLeft(r); + return (!isValid(node->rightChild)) ? r : rotateLeft(r); } } }; diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index 476c80f..45003e1 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -124,7 +124,7 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice void Allocation::markFree(SubAllocation *allocation) { // Dont free if it is already a free allocation, since they also mark themselves on deletion - if (freeRanges.find(allocation->allocatedOffset) != nullptr) + if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end()) { return; } From 8fe9195fd7ae4829f157e993a95bcfd2ad1a3c55 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 9 Nov 2021 00:11:02 +0100 Subject: [PATCH 4/5] trying to debug map --- src/Engine/Containers/Map.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index f3a817d..b7d14d1 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -274,6 +274,7 @@ public: inline mapped_type& operator[](const key_type& key) { root = splay(root, key); + verifyTree(); markIteratorDirty(); if (root >= nodeContainer.size() || comp(getNode(root)->pair.key, key) @@ -287,6 +288,7 @@ public: inline mapped_type& operator[](key_type&& key) { root = splay(root, std::move(key)); + verifyTree(); markIteratorDirty(); if (root >= nodeContainer.size() || comp(getNode(root)->pair.key, key) @@ -300,6 +302,7 @@ public: iterator find(const key_type& key) { root = splay(root, key); + verifyTree(); refreshIterators(); if (!isValid(root) || comp(getNode(root)->pair.key, key) @@ -312,6 +315,7 @@ public: iterator find(key_type&& key) { root = splay(root, std::move(key)); + verifyTree(); refreshIterators(); if (!isValid(root) || comp(getNode(root)->pair.key, key) @@ -324,12 +328,14 @@ public: iterator erase(const key_type& key) { root = remove(root, key); + verifyTree(); refreshIterators(); return iterator(root, &nodeContainer); } iterator erase(K&& key) { root = remove(root, std::move(key)); + verifyTree(); refreshIterators(); return iterator(root, &nodeContainer); } @@ -386,6 +392,34 @@ public: } private: + void verifyTree() + { + for(size_t i = 0; i < nodeContainer.size(); ++i) + { + bool found = false; + for(auto it : nodeContainer) + { + if(it.leftChild == i) + { + assert(!found); + found = true; + } + if(it.rightChild == i) + { + assert(!found); + found = true; + } + } + if(isValid(nodeContainer[i].leftChild)) + { + assert(comp(nodeContainer[nodeContainer[i].leftChild].pair.key, nodeContainer[i].pair.key)); + } + if(isValid(nodeContainer[i].rightChild)) + { + assert(comp(nodeContainer[i].pair.key, nodeContainer[nodeContainer[i].rightChild].pair.key)); + } + } + } Node* getNode(size_t index) const { if(!isValid(index)) return nullptr; @@ -477,11 +511,11 @@ private: return 0; } r = splay(r, key); + Node* node = getNode(r); if (!(comp(node->pair.key, key) || comp(key, node->pair.key))) return r; - Node* node = getNode(r); Node *newNode = &nodeContainer.emplace(std::forward(key)); if (comp(key, node->pair.key)) From c65855c4af981b4f1c82b2d2c819fa8b2a915101 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 9 Nov 2021 16:38:26 +0100 Subject: [PATCH 5/5] Fixed the map, yay --- src/Engine/Containers/Map.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index b7d14d1..6f63df7 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -274,7 +274,6 @@ public: inline mapped_type& operator[](const key_type& key) { root = splay(root, key); - verifyTree(); markIteratorDirty(); if (root >= nodeContainer.size() || comp(getNode(root)->pair.key, key) @@ -288,7 +287,6 @@ public: inline mapped_type& operator[](key_type&& key) { root = splay(root, std::move(key)); - verifyTree(); markIteratorDirty(); if (root >= nodeContainer.size() || comp(getNode(root)->pair.key, key) @@ -302,7 +300,6 @@ public: iterator find(const key_type& key) { root = splay(root, key); - verifyTree(); refreshIterators(); if (!isValid(root) || comp(getNode(root)->pair.key, key) @@ -315,7 +312,6 @@ public: iterator find(key_type&& key) { root = splay(root, std::move(key)); - verifyTree(); refreshIterators(); if (!isValid(root) || comp(getNode(root)->pair.key, key) @@ -328,14 +324,12 @@ public: iterator erase(const key_type& key) { root = remove(root, key); - verifyTree(); refreshIterators(); return iterator(root, &nodeContainer); } iterator erase(K&& key) { root = remove(root, std::move(key)); - verifyTree(); refreshIterators(); return iterator(root, &nodeContainer); } @@ -517,6 +511,7 @@ private: return r; Node *newNode = &nodeContainer.emplace(std::forward(key)); + node = getNode(r); if (comp(key, node->pair.key)) {