From a8298be6ca1e9e046a52117ec63212d2e00264fa Mon Sep 17 00:00:00 2001 From: lifegpc Date: Thu, 18 Jul 2024 15:35:55 +0800 Subject: [PATCH] Update hash map --- hash_map.h | 24 ++++++++++++++++++++++++ test/hash_map_test.cpp | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/hash_map.h b/hash_map.h index 6ec94f5..b8e4f43 100644 --- a/hash_map.h +++ b/hash_map.h @@ -110,6 +110,29 @@ void hash_map_clear(struct hash_map* map, bool shrink = true) { } } +template +bool hash_map_delete(struct hash_map* map, K key, V* deleted_value = nullptr) { + if (!map) return false; + size_t h = map->hash(key); + size_t loc = h % map->cap; + size_t i = 1; + while (map->map[loc] && map->map[loc]->key != key) { + loc = (h + map->probing(i++)) % map->cap; + } + if (!map->map[loc]) return false; + if (deleted_value) *deleted_value = map->map[loc]->value; + if (map->free_key) map->free_key(map->map[loc]->key); + if (!deleted_value && map->free_value) map->free_value(map->map[loc]->value); + delete map->map[loc]; + map->map[loc] = nullptr; + return true; +} + +template +inline bool hash_map_delete(struct hash_map* map, X key, V* deleted_value = nullptr) { + return hash_map_delete(map, K(key), deleted_value); +} + template struct hash_map_entry* hash_map_get_entry(struct hash_map* map, K key) { if (!map) return nullptr; @@ -136,6 +159,7 @@ bool hash_map_get(struct hash_map* map, K key, V& value) { while (map->map[loc] && map->map[loc]->key != key) { loc = (h + map->probing(i++)) % map->cap; } + if (!map->map[loc]) return false; value = map->map[loc]->value; return true; } diff --git a/test/hash_map_test.cpp b/test/hash_map_test.cpp index d1cba00..5f663a3 100644 --- a/test/hash_map_test.cpp +++ b/test/hash_map_test.cpp @@ -31,7 +31,14 @@ TEST(HashMapTest, HashMap) { GTEST_ASSERT_EQ(hash_map_get_entry(map, "123")->value, 123); int v = 0; GTEST_ASSERT_TRUE(hash_map_get(map, "234", v)); + GTEST_ASSERT_FALSE(hash_map_get(map, "333", v)); + GTEST_ASSERT_FALSE(hash_map_get_entry(map, "333")); GTEST_ASSERT_EQ(v, 234); + GTEST_ASSERT_TRUE(hash_map_insert(map, "2222", 2222)); + GTEST_ASSERT_TRUE(hash_map_get_entry(map, "2222")); + GTEST_ASSERT_TRUE(hash_map_delete(map, "2222", &v)); + GTEST_ASSERT_EQ(v, 2222); + GTEST_ASSERT_FALSE(hash_map_get_entry(map, "2222")); free_hash_map(map); }