From c0691d4b3e7712915e20151a9b3118a4dc527a58 Mon Sep 17 00:00:00 2001 From: Isaac0-dev <62234577+Isaac0-dev@users.noreply.github.com> Date: Sat, 30 Nov 2024 15:33:11 +1000 Subject: [PATCH] add unordered map to cmap --- data/dynos_cmap.cpp | 209 ++++++++++++++++++++++++--------- data/dynos_cmap.cpp.h | 8 +- src/pc/djui/djui_unicode.c | 4 +- src/pc/lua/smlua_cobject_map.c | 7 +- src/pc/network/sync_object.c | 8 +- 5 files changed, 166 insertions(+), 70 deletions(-) diff --git a/data/dynos_cmap.cpp b/data/dynos_cmap.cpp index c158be20f..a89f859f6 100644 --- a/data/dynos_cmap.cpp +++ b/data/dynos_cmap.cpp @@ -1,84 +1,187 @@ #include +#include #include #include +#include -typedef std::map Map; +enum class MapType { + Ordered, + Unordered +}; -struct MapIter { - Map* map; - Map::iterator itr; +// Ordered maps can be iterated by key order +// Unordered maps have the fastest lookup times (also called a hash map) + +template +class HMap { +public: + HMap(MapType type = MapType::Ordered) : mMapType(type) { + switch (mMapType) { + case MapType::Ordered: + mOrderedMap = std::make_unique>(); + break; + case MapType::Unordered: + mUnorderedMap = std::make_unique>(); + break; + } + } + + Value get(Key key) { + switch (mMapType) { + case MapType::Ordered: + if (mOrderedMap->count(key)) { + return mOrderedMap->at(key); + } + break; + case MapType::Unordered: + if (mUnorderedMap->count(key)) { + return mUnorderedMap->at(key); + } + break; + } + return nullptr; + } + + void put(Key key, Value value) { + switch (mMapType) { + case MapType::Ordered: + if (mOrderedMap->count(key)) { mOrderedMap->erase(key); } + mOrderedMap->insert({key, value}); + break; + case MapType::Unordered: + if (mUnorderedMap->count(key)) { mUnorderedMap->erase(key); } + mUnorderedMap->insert({key, value}); + break; + } + } + + void erase(Key key) { + switch (mMapType) { + case MapType::Ordered: + mOrderedMap->erase(key); + break; + case MapType::Unordered: + mUnorderedMap->erase(key); + break; + } + } + + void clear() { + switch (mMapType) { + case MapType::Ordered: + mOrderedMap->clear(); + break; + case MapType::Unordered: + mUnorderedMap->clear(); + break; + } + } + + size_t size() const { + switch (mMapType) { + case MapType::Ordered: + return mOrderedMap->size(); + case MapType::Unordered: + return mUnorderedMap->size(); + } + return 0; + } + + void* begin() { + switch (mMapType) { + case MapType::Ordered: { + auto& orderedMap = *mOrderedMap; + if (orderedMap.empty()) { return nullptr; } + mOrderedIterator = mOrderedMap->begin(); + return mOrderedIterator->second; + } + case MapType::Unordered: { + auto& unorderedMap = *mUnorderedMap; + if (unorderedMap.empty()) { return nullptr; } + mUnorderedIterator = mUnorderedMap->begin(); + return mUnorderedIterator->second; + } + } + return nullptr; + } + + void* next() { + switch (mMapType) { + case MapType::Ordered: { + if (++mOrderedIterator != mOrderedMap->end()) { + return mOrderedIterator->second; + } + break; + } + case MapType::Unordered: { + if (++mUnorderedIterator != mUnorderedMap->end()) { + return mUnorderedIterator->second; + } + break; + } + } + return nullptr; + } + +private: + MapType mMapType; + + std::unique_ptr> mOrderedMap; + typename std::map::iterator mOrderedIterator; + + std::unique_ptr> mUnorderedMap; + typename std::unordered_map::iterator mUnorderedIterator; }; extern "C" { - -void* hmap_create() { - return reinterpret_cast (new Map()); +void* hmap_create(MapType type) { + return new HMap(type); } -void* hmap_get(void* map, int64_t k) { +void* hmap_get(void* map, int64_t key) { if (!map) { return NULL; } - Map* m = reinterpret_cast (map); - Map::iterator pos = m->find(k); - if (pos == m->end()) { - return NULL; - } else { - return pos->second; - } + HMap* hmap = reinterpret_cast*>(map); + return hmap->get(key); } -void hmap_put(void* map, int64_t k, void* v) { +void hmap_put(void* map, int64_t key, void* value) { if (!map) { return; } - Map* m = reinterpret_cast (map); - if (m->count(k) > 0) { - m->erase(k); - } - m->insert(std::pair(k, v)); + HMap* hmap = reinterpret_cast*>(map); + hmap->put(key, value); } -void hmap_del(void* map, int64_t k) { +void hmap_del(void* map, int64_t key) { if (!map) { return; } - Map* m = reinterpret_cast (map); - m->erase(k); + HMap* hmap = reinterpret_cast*>(map); + hmap->erase(key); } void hmap_clear(void* map) { if (!map) { return; } - Map* m = reinterpret_cast (map); - m->clear(); + HMap* hmap = reinterpret_cast*>(map); + hmap->clear(); +} + +void hmap_destroy(void* map) { + if (!map) { return; } + delete reinterpret_cast*>(map); } size_t hmap_len(void* map) { if (!map) { return 0; } - Map* m = reinterpret_cast (map); - return m->size(); + HMap* hmap = reinterpret_cast*>(map); + return hmap->size(); } -void* hmap_iter(void* map) { - if (!map) { return nullptr; } - auto iter = new MapIter(); - Map* m = reinterpret_cast (map); - iter->map = m; - return reinterpret_cast (iter); +void* hmap_begin(void* map) { + if (!map) { return NULL; } + HMap* hmap = reinterpret_cast*>(map); + return hmap->begin(); } -void* hmap_begin(void* iter) { - if (!iter) { return nullptr; } - MapIter* i = reinterpret_cast (iter); - i->itr = i->map->begin(); - if (i->itr == i->map->end()) { - return NULL; - } - return i->itr->second; +void* hmap_next(void* map) { + if (!map) { return NULL; } + HMap* hmap = reinterpret_cast*>(map); + return hmap->next(); } - -void* hmap_next(void* iter) { - if (!iter) { return nullptr; } - MapIter* i = reinterpret_cast (iter); - i->itr++; - if (i->itr == i->map->end()) { - return NULL; - } - return i->itr->second; } - -} // extern "C" \ No newline at end of file diff --git a/data/dynos_cmap.cpp.h b/data/dynos_cmap.cpp.h index 77c7c7f7c..09d6553d8 100644 --- a/data/dynos_cmap.cpp.h +++ b/data/dynos_cmap.cpp.h @@ -2,16 +2,16 @@ #define DYNOS_CMAP_CPP_H #ifndef __cplusplus -void* hmap_create(); +void* hmap_create(bool useUnordered); void* hmap_get(void* map, int64_t k); void hmap_put(void* map, int64_t k, void* v); void hmap_del(void* map, int64_t k); void hmap_clear(void* map); +void hmap_destroy(void* map); size_t hmap_len(void* map); -void* hmap_iter(void* map); -void* hmap_begin(void* iter); -void* hmap_next(void* iter); +void* hmap_begin(void* map); +void* hmap_next(void* map); #endif #endif \ No newline at end of file diff --git a/src/pc/djui/djui_unicode.c b/src/pc/djui/djui_unicode.c index 0bc63757f..0e663023b 100644 --- a/src/pc/djui/djui_unicode.c +++ b/src/pc/djui/djui_unicode.c @@ -199,7 +199,6 @@ struct SmCodeGlyph sSmCodeDuplicateGlyphs[] = { }; static void* sCharMap = NULL; -static void* sCharIter = NULL; static s32 count_bytes_for_char(char* text) { s32 bytes = 0; @@ -229,8 +228,7 @@ static u64 convert_unicode_char_to_u64(char* text) { } void djui_unicode_init(void) { - sCharMap = hmap_create(); - sCharIter = hmap_iter(sCharMap); + sCharMap = hmap_create(true); size_t glyphCount = sizeof(sSmCodeGlyphs) / sizeof(sSmCodeGlyphs[0]); for (size_t i = 0; i < glyphCount; i++) { diff --git a/src/pc/lua/smlua_cobject_map.c b/src/pc/lua/smlua_cobject_map.c index d0bf51287..f3d0a0d69 100644 --- a/src/pc/lua/smlua_cobject_map.c +++ b/src/pc/lua/smlua_cobject_map.c @@ -16,12 +16,9 @@ void smlua_pointer_user_data_add(uintptr_t pointer, CObject *obj) { if (pointer == 0) { return; } if (!sPointers) { - sPointers = hmap_create(); - } - - if (!hmap_get(sPointers, pointer)) { - hmap_put(sPointers, pointer, obj); + sPointers = hmap_create(true); } + hmap_put(sPointers, pointer, obj); } void smlua_pointer_user_data_delete(uintptr_t pointer) { diff --git a/src/pc/network/sync_object.c b/src/pc/network/sync_object.c index d16daba95..3e936b10d 100644 --- a/src/pc/network/sync_object.c +++ b/src/pc/network/sync_object.c @@ -14,7 +14,6 @@ #include "pc/debug_context.h" static void* sSoMap = NULL; -static void* sSoIter = NULL; #define FORGET_TIMEOUT 10 @@ -33,8 +32,7 @@ static bool sFreeingAll = false; //////////// void sync_objects_init_system(void) { - sSoMap = hmap_create(); - sSoIter = hmap_iter(sSoMap); + sSoMap = hmap_create(true); } static bool sync_objects_forget_list_contains(struct SyncObject* so) { @@ -254,11 +252,11 @@ struct SyncObject* sync_object_get(u32 syncId) { } struct SyncObject* sync_object_get_first(void) { - return hmap_begin(sSoIter); + return hmap_begin(sSoMap); } struct SyncObject* sync_object_get_next(void) { - return hmap_next(sSoIter); + return hmap_next(sSoMap); } struct Object* sync_object_get_object(u32 syncId) {