Daniele Bartolini 1 год назад
Родитель
Сommit
d21ed910b4

+ 1 - 0
docs/changelog.rst

@@ -12,6 +12,7 @@ Changelog
 
 * Fixed intra-frame button press/release detection.
 * Added ``--hidden`` CLI option.
+* Fixed HashMap and HashSet.
 
 **Tools**
 

+ 2 - 1
src/core/containers/hash_map.inl

@@ -106,10 +106,11 @@ namespace hash_map_internal
 
 		const u32 hash = key_hash<TKey, Hash>(key);
 		u32 hash_i = hash & m._mask;
+		const u32 pos = m._index[hash_i].hash;
 		for (u32 dist = 0;;) {
 			if (m._index[hash_i].index == FREE)
 				return END_OF_LIST;
-			else if (dist > probe_distance(m, m._index[hash_i].hash, hash_i))
+			else if (dist > probe_distance(m, pos, hash_i))
 				return END_OF_LIST;
 			else if (!is_deleted(m._index[hash_i].index) && m._index[hash_i].hash == hash && key_equals<TKey, KeyEqual>(m._data[hash_i].first, key))
 				return hash_i;

+ 2 - 1
src/core/containers/hash_set.inl

@@ -95,10 +95,11 @@ namespace hash_set_internal
 
 		const u32 hash = key_hash<TKey, Hash>(key);
 		u32 hash_i = hash & m._mask;
+		const u32 pos = m._index[hash_i].hash;
 		for (u32 dist = 0;;) {
 			if (m._index[hash_i].index == FREE)
 				return END_OF_LIST;
-			else if (dist > probe_distance(m, m._index[hash_i].hash, hash_i))
+			else if (dist > probe_distance(m, pos, hash_i))
 				return END_OF_LIST;
 			else if (!is_deleted(m._index[hash_i].index) && m._index[hash_i].hash == hash && key_equals<TKey, KeyEqual>(m._data[hash_i], key))
 				return hash_i;

+ 32 - 0
src/core/unit_tests.cpp

@@ -140,6 +140,22 @@ static void test_hash_map()
 		for (s32 i = 0; i < 100; ++i)
 			ENSURE(!hash_map::has(m, i));
 	}
+	{
+		HashMap<s32, s32> m(a);
+
+		for (s32 i = 0; i < 12; ++i)
+		{
+			s32 key = 12 + i;
+			hash_map::set(m, key, 99);
+			hash_map::set(m, i, i);
+			hash_map::remove(m, key);
+		}
+
+		ENSURE(hash_map::size(m) == 12);
+
+		for (s32 i = 0; i < 12; ++i)
+			ENSURE(hash_map::get(m, i, 0) == i);
+	}
 	{
 		HashMap<s32, s32> m(a);
 		hash_map_internal::grow(m);
@@ -195,6 +211,22 @@ static void test_hash_set()
 		for (s32 i = 0; i < 100; ++i)
 			ENSURE(!hash_set::has(m, i*i));
 	}
+	{
+		HashSet<s32> m(a);
+
+		for (s32 i = 0; i < 12; ++i)
+		{
+			s32 key = 12 + i;
+			hash_set::insert(m, key);
+			hash_set::insert(m, i);
+			hash_set::remove(m, key);
+		}
+
+		ENSURE(hash_set::size(m) == 12);
+
+		for (s32 i = 0; i < 12; ++i)
+			ENSURE(hash_set::has(m, i));
+	}
 	{
 		HashSet<s32> ma(a);
 		HashSet<s32> mb(a);