feat(hash): add unsynchronized export table template

This commit is contained in:
fallenoak 2023-03-26 21:44:06 -05:00 committed by GitHub
parent 355733263f
commit 368c2f16c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 0 deletions

View file

@ -2,6 +2,7 @@
#define STORM_HASH_HPP #define STORM_HASH_HPP
#include "storm/hash/Hashkey.hpp" #include "storm/hash/Hashkey.hpp"
#include "storm/hash/TSExportTableSimpleReuse.hpp"
#include "storm/hash/TSHashObject.hpp" #include "storm/hash/TSHashObject.hpp"
#include "storm/hash/TSHashTable.hpp" #include "storm/hash/TSHashTable.hpp"
#include "storm/hash/TSHashTableReuse.hpp" #include "storm/hash/TSHashTableReuse.hpp"

View file

@ -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 T, class THandle>
class TSExportTableSimpleReuse : public TSHashTableReuse<T, HASHKEY_NONE> {
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<uintptr_t>(this) & 0xFFFFFFF;
int32_t m_wrapped = 0;
// Member functions
THandle GenerateUniqueHandle();
};
template <class T, class THandle>
void TSExportTableSimpleReuse<T, THandle>::Delete(T* ptr) {
TSHashTable<T, HASHKEY_NONE>::Delete(ptr);
}
template <class T, class THandle>
THandle TSExportTableSimpleReuse<T, THandle>::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<THandle>(this->m_sequence))) {
break;
}
}
return reinterpret_cast<THandle>(this->m_sequence);
}
template <class T, class THandle>
T* TSExportTableSimpleReuse<T, THandle>::New(THandle* handlePtr) {
auto handle = this->GenerateUniqueHandle();
*handlePtr = handle;
auto hashval = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(handle));
return this->TSHashTable<T, HASHKEY_NONE>::New(hashval, this->m_key, 0, 0x0);
}
template <class T, class THandle>
T* TSExportTableSimpleReuse<T, THandle>::Ptr(THandle handle) {
auto hashval = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(handle));
return this->TSHashTable<T, HASHKEY_NONE>::Ptr(hashval, this->m_key);
}
#endif

View file

@ -5,6 +5,12 @@ struct TestHashObject : TSHashObject<TestHashObject, HASHKEY_STRI> {
uint32_t index = 255; uint32_t index = 255;
}; };
struct TestExportObject : TSHashObject<TestHashObject, HASHKEY_NONE> {
uint32_t index = 255;
};
typedef void* TestExportObjectHandle;
TEST_CASE("TSHashTable", "[hash]") { TEST_CASE("TSHashTable", "[hash]") {
SECTION("constructs correctly") { SECTION("constructs correctly") {
TSHashTable<TestHashObject, HASHKEY_STRI> hashTable; TSHashTable<TestHashObject, HASHKEY_STRI> hashTable;
@ -75,3 +81,39 @@ TEST_CASE("TSHashTableReuse::New", "[hash]") {
REQUIRE(hashTable.Ptr("testKey3")->index == 255); REQUIRE(hashTable.Ptr("testKey3")->index == 255);
} }
} }
TEST_CASE("TSExportTableSimpleReuse", "[hash]") {
SECTION("constructs correctly") {
TSExportTableSimpleReuse<TestExportObject, TestExportObjectHandle> exportTable;
REQUIRE(exportTable.Head() == nullptr);
}
}
TEST_CASE("TSExportTableSimpleReuse::New", "[hash]") {
SECTION("returns a new object and handle") {
TSExportTableSimpleReuse<TestExportObject, TestExportObjectHandle> 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<TestExportObject, TestExportObjectHandle> 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);
}
}