1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-21 14:45:07 +00:00

AK: HashTable/HashMap return whether action was performed for set/remove

This allows performing an action based on whether something
was actually added or removed without having to look it up
prior to calling set() or remove().
This commit is contained in:
Tom 2020-07-06 15:44:33 -06:00 committed by Andreas Kling
parent df54229954
commit dadd53e4f2
2 changed files with 25 additions and 12 deletions

View file

@ -54,13 +54,16 @@ public:
size_t capacity() const { return m_table.capacity(); } size_t capacity() const { return m_table.capacity(); }
void clear() { m_table.clear(); } void clear() { m_table.clear(); }
void set(const K& key, const V& value) { m_table.set({ key, value }); } HashSetResult set(const K& key, const V& value) { return m_table.set({ key, value }); }
void set(const K& key, V&& value) { m_table.set({ key, move(value) }); } HashSetResult set(const K& key, V&& value) { return m_table.set({ key, move(value) }); }
void remove(const K& key) bool remove(const K& key)
{ {
auto it = find(key); auto it = find(key);
if (it != end()) if (it != end()) {
m_table.remove(it); m_table.remove(it);
return true;
}
return false;
} }
void remove_one_randomly() { m_table.remove(m_table.begin()); } void remove_one_randomly() { m_table.remove(m_table.begin()); }

View file

@ -34,6 +34,11 @@
namespace AK { namespace AK {
enum class HashSetResult {
InsertedNewEntry,
ReplacedExistingEntry
};
template<typename T, typename> template<typename T, typename>
class HashTable; class HashTable;
@ -157,8 +162,8 @@ public:
rehash(capacity); rehash(capacity);
} }
void set(const T&); HashSetResult set(const T&);
void set(T&&); HashSetResult set(T&&);
bool contains(const T&) const; bool contains(const T&) const;
void clear(); void clear();
@ -208,11 +213,14 @@ 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); });
} }
void remove(const T& value) bool remove(const T& value)
{ {
auto it = find(value); auto it = find(value);
if (it != end()) if (it != end()) {
remove(it); remove(it);
return true;
}
return false;
} }
void remove(Iterator); void remove(Iterator);
@ -251,7 +259,7 @@ private:
}; };
template<typename T, typename TraitsForT> template<typename T, typename TraitsForT>
void HashTable<T, TraitsForT>::set(T&& value) HashSetResult HashTable<T, TraitsForT>::set(T&& value)
{ {
if (!m_capacity) if (!m_capacity)
rehash(1); rehash(1);
@ -259,7 +267,7 @@ void HashTable<T, TraitsForT>::set(T&& value)
for (auto& e : bucket) { for (auto& e : bucket) {
if (TraitsForT::equals(e, value)) { if (TraitsForT::equals(e, value)) {
e = move(value); e = move(value);
return; return HashSetResult::ReplacedExistingEntry;
} }
} }
if (size() >= capacity()) { if (size() >= capacity()) {
@ -269,10 +277,11 @@ void HashTable<T, TraitsForT>::set(T&& value)
bucket.append(move(value)); bucket.append(move(value));
} }
m_size++; m_size++;
return HashSetResult::InsertedNewEntry;
} }
template<typename T, typename TraitsForT> template<typename T, typename TraitsForT>
void HashTable<T, TraitsForT>::set(const T& value) HashSetResult HashTable<T, TraitsForT>::set(const T& value)
{ {
if (!m_capacity) if (!m_capacity)
rehash(1); rehash(1);
@ -280,7 +289,7 @@ void HashTable<T, TraitsForT>::set(const T& value)
for (auto& e : bucket) { for (auto& e : bucket) {
if (TraitsForT::equals(e, value)) { if (TraitsForT::equals(e, value)) {
e = value; e = value;
return; return HashSetResult::ReplacedExistingEntry;
} }
} }
if (size() >= capacity()) { if (size() >= capacity()) {
@ -290,6 +299,7 @@ void HashTable<T, TraitsForT>::set(const T& value)
bucket.append(value); bucket.append(value);
} }
m_size++; m_size++;
return HashSetResult::InsertedNewEntry;
} }
template<typename T, typename TraitsForT> template<typename T, typename TraitsForT>