tint/utils: Add Hashmap equality and hashing
Allows Hashmaps to be used as keys to other hashmaps. Change-Id: I557d99515451c55e599dda847e15ce8e2b4500c5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112282 Kokoro: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
2d108ae5ed
commit
c158e845e6
|
@ -206,6 +206,31 @@ class Hashmap : public HashmapBase<KEY, VALUE, N, HASH, EQUAL> {
|
|||
return out;
|
||||
}
|
||||
|
||||
/// Equality operator
|
||||
/// @param other the other Hashmap to compare this Hashmap to
|
||||
/// @returns true if this Hashmap has the same key and value pairs as @p other
|
||||
template <typename K, typename V, size_t N2>
|
||||
bool operator==(const Hashmap<K, V, N2>& other) const {
|
||||
if (this->Count() != other.Count()) {
|
||||
return false;
|
||||
}
|
||||
for (auto it : *this) {
|
||||
auto other_val = other.Find(it.key);
|
||||
if (!other_val || it.value != *other_val) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Inequality operator
|
||||
/// @param other the other Hashmap to compare this Hashmap to
|
||||
/// @returns false if this Hashmap has the same key and value pairs as @p other
|
||||
template <typename K, typename V, size_t N2>
|
||||
bool operator!=(const Hashmap<K, V, N2>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
Value* Lookup(const Key& key) {
|
||||
if (auto [found, index] = this->IndexOf(key); found) {
|
||||
|
@ -222,6 +247,22 @@ class Hashmap : public HashmapBase<KEY, VALUE, N, HASH, EQUAL> {
|
|||
}
|
||||
};
|
||||
|
||||
/// Hasher specialization for Hashmap
|
||||
template <typename K, typename V, size_t N, typename HASH, typename EQUAL>
|
||||
struct Hasher<Hashmap<K, V, N, HASH, EQUAL>> {
|
||||
/// @param map the Hashmap to hash
|
||||
/// @returns a hash of the map
|
||||
size_t operator()(const Hashmap<K, V, N, HASH, EQUAL>& map) const {
|
||||
auto hash = Hash(map.Count());
|
||||
for (auto it : map) {
|
||||
// Use an XOR to ensure that the non-deterministic ordering of the map still produces
|
||||
// the same hash value for the same entries.
|
||||
hash ^= Hash(it.key) * 31 + Hash(it.value);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tint::utils
|
||||
|
||||
#endif // SRC_TINT_UTILS_HASHMAP_H_
|
||||
|
|
|
@ -355,5 +355,61 @@ TEST(Hashmap, Soak) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(Hashmap, EqualitySameSize) {
|
||||
Hashmap<int, std::string, 8> a;
|
||||
Hashmap<int, std::string, 8> b;
|
||||
EXPECT_EQ(a, b);
|
||||
a.Add(1, "one");
|
||||
EXPECT_NE(a, b);
|
||||
b.Add(2, "two");
|
||||
EXPECT_NE(a, b);
|
||||
a.Add(2, "two");
|
||||
EXPECT_NE(a, b);
|
||||
b.Add(1, "one");
|
||||
EXPECT_EQ(a, b);
|
||||
}
|
||||
|
||||
TEST(Hashmap, EqualityDifferentSize) {
|
||||
Hashmap<int, std::string, 8> a;
|
||||
Hashmap<int, std::string, 4> b;
|
||||
EXPECT_EQ(a, b);
|
||||
a.Add(1, "one");
|
||||
EXPECT_NE(a, b);
|
||||
b.Add(2, "two");
|
||||
EXPECT_NE(a, b);
|
||||
a.Add(2, "two");
|
||||
EXPECT_NE(a, b);
|
||||
b.Add(1, "one");
|
||||
EXPECT_EQ(a, b);
|
||||
}
|
||||
|
||||
TEST(Hashmap, HashSameSize) {
|
||||
Hashmap<int, std::string, 8> a;
|
||||
Hashmap<int, std::string, 8> b;
|
||||
EXPECT_EQ(Hash(a), Hash(b));
|
||||
a.Add(1, "one");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
b.Add(2, "two");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
a.Add(2, "two");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
b.Add(1, "one");
|
||||
EXPECT_EQ(Hash(a), Hash(b));
|
||||
}
|
||||
|
||||
TEST(Hashmap, HashDifferentSize) {
|
||||
Hashmap<int, std::string, 8> a;
|
||||
Hashmap<int, std::string, 4> b;
|
||||
EXPECT_EQ(Hash(a), Hash(b));
|
||||
a.Add(1, "one");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
b.Add(2, "two");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
a.Add(2, "two");
|
||||
EXPECT_NE(Hash(a), Hash(b));
|
||||
b.Add(1, "one");
|
||||
EXPECT_EQ(Hash(a), Hash(b));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::utils
|
||||
|
|
Loading…
Reference in New Issue