mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:27:45 +00:00
AK: Allow hash-compatible key types in Hash[Table|Map] lookup
This will allow us to avoid some potentially expensive type conversion during lookup, like form String to StringView, which would allocate memory otherwise.
This commit is contained in:
parent
c8bee92fb9
commit
d50360f5dd
2 changed files with 79 additions and 0 deletions
46
AK/HashMap.h
46
AK/HashMap.h
|
@ -91,6 +91,19 @@ public:
|
||||||
return m_table.find(hash, predicate);
|
return m_table.find(hash, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Use some sort of Traits to get the comparison operation
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] IteratorType find(Key const& value)
|
||||||
|
{
|
||||||
|
return m_table.find(Traits<Key>::hash(value), [&](auto& entry) { return value == entry.key; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] ConstIteratorType find(Key const& value) const
|
||||||
|
{
|
||||||
|
return m_table.find(Traits<Key>::hash(value), [&](auto& entry) { return value == entry.key; });
|
||||||
|
}
|
||||||
|
|
||||||
void ensure_capacity(size_t capacity) { m_table.ensure_capacity(capacity); }
|
void ensure_capacity(size_t capacity) { m_table.ensure_capacity(capacity); }
|
||||||
ErrorOr<void> try_ensure_capacity(size_t capacity) { return m_table.try_ensure_capacity(capacity); }
|
ErrorOr<void> try_ensure_capacity(size_t capacity) { return m_table.try_ensure_capacity(capacity); }
|
||||||
|
|
||||||
|
@ -118,11 +131,44 @@ public:
|
||||||
return (*it).value;
|
return (*it).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::PeekType> get(const Key& key) const requires(!IsPointer<typename Traits<V>::PeekType>)
|
||||||
|
{
|
||||||
|
auto it = find(key);
|
||||||
|
if (it == end())
|
||||||
|
return {};
|
||||||
|
return (*it).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::ConstPeekType> get(const Key& key) const requires(IsPointer<typename Traits<V>::PeekType>)
|
||||||
|
{
|
||||||
|
auto it = find(key);
|
||||||
|
if (it == end())
|
||||||
|
return {};
|
||||||
|
return (*it).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) Optional<typename Traits<V>::PeekType> get(const Key& key) requires(!IsConst<typename Traits<V>::PeekType>)
|
||||||
|
{
|
||||||
|
auto it = find(key);
|
||||||
|
if (it == end())
|
||||||
|
return {};
|
||||||
|
return (*it).value;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool contains(const K& key) const
|
[[nodiscard]] bool contains(const K& key) const
|
||||||
{
|
{
|
||||||
return find(key) != end();
|
return find(key) != end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<K> Key>
|
||||||
|
requires(IsSame<KeyTraits, Traits<K>>) [[nodiscard]] bool contains(Key const& value)
|
||||||
|
{
|
||||||
|
return find(value) != end();
|
||||||
|
}
|
||||||
|
|
||||||
void remove(IteratorType it)
|
void remove(IteratorType it)
|
||||||
{
|
{
|
||||||
m_table.remove(it);
|
m_table.remove(it);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Concepts.h>
|
||||||
#include <AK/Error.h>
|
#include <AK/Error.h>
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
#include <AK/HashFunctions.h>
|
#include <AK/HashFunctions.h>
|
||||||
|
@ -209,6 +210,12 @@ public:
|
||||||
return find(value) != end();
|
return find(value) != end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<T> K>
|
||||||
|
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] bool contains(K const& value) const
|
||||||
|
{
|
||||||
|
return find(value) != end();
|
||||||
|
}
|
||||||
|
|
||||||
using Iterator = Conditional<IsOrdered,
|
using Iterator = Conditional<IsOrdered,
|
||||||
OrderedHashTableIterator<HashTable, T, BucketType>,
|
OrderedHashTableIterator<HashTable, T, BucketType>,
|
||||||
HashTableIterator<HashTable, T, BucketType>>;
|
HashTableIterator<HashTable, T, BucketType>>;
|
||||||
|
@ -329,6 +336,32 @@ public:
|
||||||
{
|
{
|
||||||
return find(TraitsForT::hash(value), [&](auto& other) { return TraitsForT::equals(value, other); });
|
return find(TraitsForT::hash(value), [&](auto& other) { return TraitsForT::equals(value, other); });
|
||||||
}
|
}
|
||||||
|
// FIXME: Use some Traits to get the comparison operation
|
||||||
|
// FIXME: Support for predicates, while guaranteeing that the predicate call
|
||||||
|
// does not call a non trivial constructor each time invoked
|
||||||
|
template<Concepts::HashCompatible<T> K>
|
||||||
|
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] Iterator find(K const& value)
|
||||||
|
{
|
||||||
|
return find(Traits<K>::hash(value), [&](auto& other) { return value == other; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<T> K, typename TUnaryPredicate>
|
||||||
|
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] Iterator find(K const& value, TUnaryPredicate predicate)
|
||||||
|
{
|
||||||
|
return find(Traits<K>::hash(value), move(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<T> K>
|
||||||
|
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] ConstIterator find(K const& value) const
|
||||||
|
{
|
||||||
|
return find(Traits<K>::hash(value), [&](auto& other) { return value == other; });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Concepts::HashCompatible<T> K, typename TUnaryPredicate>
|
||||||
|
requires(IsSame<TraitsForT, Traits<T>>) [[nodiscard]] ConstIterator find(K const& value, TUnaryPredicate predicate) const
|
||||||
|
{
|
||||||
|
return find(Traits<K>::hash(value), move(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
bool remove(const T& value)
|
bool remove(const T& value)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue