diff --git a/storm/Hash.hpp b/storm/Hash.hpp index 0323aff..4bc513b 100644 --- a/storm/Hash.hpp +++ b/storm/Hash.hpp @@ -2,6 +2,7 @@ #define STORM_HASH_HPP #include "storm/hash/Hashkey.hpp" +#include "storm/hash/TSExportTableSimpleReuse.hpp" #include "storm/hash/TSHashObject.hpp" #include "storm/hash/TSHashTable.hpp" #include "storm/hash/TSHashTableReuse.hpp" diff --git a/storm/hash/TSExportTableSimple.hpp b/storm/hash/TSExportTableSimple.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/storm/hash/TSExportTableSimpleReuse.hpp b/storm/hash/TSExportTableSimpleReuse.hpp new file mode 100644 index 0000000..f2a1854 --- /dev/null +++ b/storm/hash/TSExportTableSimpleReuse.hpp @@ -0,0 +1,69 @@ +#ifndef STORM_HASH_TS_EXPORT_TABLE_SIMPLE_REUSE_HPP +#define STORM_HASH_TS_EXPORT_TABLE_SIMPLE_REUSE_HPP + +#include "storm/hash/Hashkey.hpp" +#include "storm/hash/TSHashTableReuse.hpp" + +template +class TSExportTableSimpleReuse : public TSHashTableReuse { + public: + // Virtual member functions + virtual ~TSExportTableSimpleReuse() = default; + + // Member functions + void Delete(T* ptr); + T* New(THandle* handlePtr); + T* Ptr(THandle handle); + + private: + // Member variables + HASHKEY_NONE m_key; + uint32_t m_sequence = ~reinterpret_cast(this) & 0xFFFFFFF; + int32_t m_wrapped = 0; + + // Member functions + THandle GenerateUniqueHandle(); +}; + +template +void TSExportTableSimpleReuse::Delete(T* ptr) { + TSHashTable::Delete(ptr); +} + +template +THandle TSExportTableSimpleReuse::GenerateUniqueHandle() { + while (true) { + while (true) { + this->m_sequence += 1; + + if (this->m_sequence) { + break; + } + + this->m_wrapped = 1; + } + + if (!this->m_wrapped || !this->Ptr(reinterpret_cast(this->m_sequence))) { + break; + } + } + + return reinterpret_cast(this->m_sequence); +} + +template +T* TSExportTableSimpleReuse::New(THandle* handlePtr) { + auto handle = this->GenerateUniqueHandle(); + *handlePtr = handle; + + auto hashval = static_cast(reinterpret_cast(handle)); + return this->TSHashTable::New(hashval, this->m_key, 0, 0x0); +} + +template +T* TSExportTableSimpleReuse::Ptr(THandle handle) { + auto hashval = static_cast(reinterpret_cast(handle)); + return this->TSHashTable::Ptr(hashval, this->m_key); +} + +#endif diff --git a/test/Hash.cpp b/test/Hash.cpp index b773d9a..76b4ab3 100644 --- a/test/Hash.cpp +++ b/test/Hash.cpp @@ -5,6 +5,12 @@ struct TestHashObject : TSHashObject { uint32_t index = 255; }; +struct TestExportObject : TSHashObject { + uint32_t index = 255; +}; + +typedef void* TestExportObjectHandle; + TEST_CASE("TSHashTable", "[hash]") { SECTION("constructs correctly") { TSHashTable hashTable; @@ -75,3 +81,39 @@ TEST_CASE("TSHashTableReuse::New", "[hash]") { REQUIRE(hashTable.Ptr("testKey3")->index == 255); } } + +TEST_CASE("TSExportTableSimpleReuse", "[hash]") { + SECTION("constructs correctly") { + TSExportTableSimpleReuse exportTable; + REQUIRE(exportTable.Head() == nullptr); + } +} + +TEST_CASE("TSExportTableSimpleReuse::New", "[hash]") { + SECTION("returns a new object and handle") { + TSExportTableSimpleReuse exportTable; + TestExportObjectHandle handle; + auto object = exportTable.New(&handle); + + REQUIRE(handle != nullptr); + REQUIRE(object != nullptr); + REQUIRE(object != handle); + REQUIRE(exportTable.Head() == object); + REQUIRE(exportTable.Ptr(handle) == object); + } +} + +TEST_CASE("TSExportTableSimpleReuse::Delete", "[hash]") { + SECTION("deletes object from export table") { + TSExportTableSimpleReuse exportTable; + TestExportObjectHandle handle; + auto object = exportTable.New(&handle); + exportTable.Delete(object); + + REQUIRE(handle != nullptr); + REQUIRE(object != nullptr); + REQUIRE(object != handle); + REQUIRE(exportTable.Head() == nullptr); + REQUIRE(exportTable.Ptr(handle) == nullptr); + } +}