diff options
author | Andreas Kling <kling@serenityos.org> | 2021-11-10 23:00:21 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-11 01:27:46 +0100 |
commit | 9d1f2384505f08bb5b041990627eb50f2a6b941c (patch) | |
tree | c4eb2dac6b9ada5e3a5aa1a96fb4ca76f2ca9ea4 | |
parent | 4eaa95769d40e1838ea5a0577d41f005540fe92e (diff) | |
download | serenity-9d1f2384505f08bb5b041990627eb50f2a6b941c.zip |
AK: Make HashTable and HashMap try_* functions return ErrorOr<T>
This allows us to use TRY() and MUST() with them.
-rw-r--r-- | AK/HashMap.h | 6 | ||||
-rw-r--r-- | AK/HashTable.h | 48 | ||||
-rw-r--r-- | Kernel/PerformanceEventBuffer.cpp | 5 |
3 files changed, 22 insertions, 37 deletions
diff --git a/AK/HashMap.h b/AK/HashMap.h index 9c9b9d972a..733a7057cc 100644 --- a/AK/HashMap.h +++ b/AK/HashMap.h @@ -49,8 +49,8 @@ public: HashSetResult set(const K& key, const V& value) { return m_table.set({ key, value }); } HashSetResult set(const K& key, V&& value) { return m_table.set({ key, move(value) }); } - HashSetResult try_set(const K& key, const V& value) { return m_table.try_set({ key, value }); } - HashSetResult try_set(const K& key, V&& value) { return m_table.try_set({ key, move(value) }); } + ErrorOr<HashSetResult> try_set(const K& key, const V& value) { return m_table.try_set({ key, value }); } + ErrorOr<HashSetResult> try_set(const K& key, V&& value) { return m_table.try_set({ key, move(value) }); } bool remove(const K& key) { @@ -91,7 +91,7 @@ public: } void ensure_capacity(size_t capacity) { m_table.ensure_capacity(capacity); } - bool 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); } Optional<typename Traits<V>::PeekType> get(const K& key) const requires(!IsPointer<typename Traits<V>::PeekType>) { diff --git a/AK/HashTable.h b/AK/HashTable.h index b50d4486d5..7af8f89e07 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -6,6 +6,7 @@ #pragma once +#include <AK/Error.h> #include <AK/Forward.h> #include <AK/HashFunctions.h> #include <AK/StdLibExtras.h> @@ -16,7 +17,6 @@ namespace AK { enum class HashSetResult { - Failed = 0, InsertedNewEntry, ReplacedExistingEntry, KeptExistingEntry @@ -186,19 +186,16 @@ public: [[nodiscard]] size_t capacity() const { return m_capacity; } template<typename U, size_t N> - bool try_set_from(U (&from_array)[N]) + ErrorOr<void> try_set_from(U (&from_array)[N]) { - for (size_t i = 0; i < N; ++i) { - if (try_set(from_array[i]) == HashSetResult::Failed) - return false; - } - return true; + for (size_t i = 0; i < N; ++i) + TRY(try_set(from_array[i])); + return {}; } template<typename U, size_t N> void set_from(U (&from_array)[N]) { - bool result = try_set_from(from_array); - VERIFY(result); + MUST(try_set_from(from_array)); } void ensure_capacity(size_t capacity) @@ -260,11 +257,9 @@ public: } template<typename U = T> - HashSetResult try_set(U&& value, HashSetExistingEntryBehavior existing_entry_behavior = HashSetExistingEntryBehavior::Replace) + ErrorOr<HashSetResult> try_set(U&& value, HashSetExistingEntryBehavior existing_entry_behavior = HashSetExistingEntryBehavior::Replace) { - auto* bucket = try_lookup_for_writing(value); - if (!bucket) - return HashSetResult::Failed; + auto* bucket = TRY(try_lookup_for_writing(value)); if (bucket->used) { if (existing_entry_behavior == HashSetExistingEntryBehavior::Keep) return HashSetResult::KeptExistingEntry; @@ -295,9 +290,7 @@ public: template<typename U = T> HashSetResult set(U&& value, HashSetExistingEntryBehavior existing_entry_behaviour = HashSetExistingEntryBehavior::Replace) { - auto result = try_set(forward<U>(value), existing_entry_behaviour); - VERIFY(result != HashSetResult::Failed); - return result; + return MUST(try_set(forward<U>(value), existing_entry_behaviour)); } template<typename TUnaryPredicate> @@ -388,7 +381,7 @@ private: } } - bool try_rehash(size_t new_capacity) + ErrorOr<void> try_rehash(size_t new_capacity) { new_capacity = max(new_capacity, static_cast<size_t>(4)); new_capacity = kmalloc_good_size(new_capacity * sizeof(BucketType)) / sizeof(BucketType); @@ -399,7 +392,7 @@ private: auto new_buckets = kmalloc(size_in_bytes(new_capacity)); if (!new_buckets) - return false; + return Error::from_errno(ENOMEM); m_buckets = (BucketType*)new_buckets; __builtin_memset(m_buckets, 0, size_in_bytes(new_capacity)); @@ -413,7 +406,7 @@ private: m_buckets[m_capacity].end = true; if (!old_buckets) - return true; + return {}; for (auto it = move(old_iter); it != end(); ++it) { insert_during_rehash(move(*it)); @@ -421,12 +414,11 @@ private: } kfree_sized(old_buckets, size_in_bytes(old_capacity)); - return true; + return {}; } void rehash(size_t new_capacity) { - bool result = try_rehash(new_capacity); - VERIFY(result); + MUST(try_rehash(new_capacity)); } template<typename TUnaryPredicate> @@ -448,15 +440,13 @@ private: } } - [[nodiscard]] BucketType* try_lookup_for_writing(T const& value) + ErrorOr<BucketType*> try_lookup_for_writing(T const& value) { // FIXME: Maybe overrun the "allowed" load factor to avoid OOM // If we are allowed to do that, separate that logic from // the normal lookup_for_writing - if (should_grow()) { - if (!try_rehash(capacity() * 2)) - return nullptr; - } + if (should_grow()) + TRY(try_rehash(capacity() * 2)); auto hash = TraitsForT::hash(value); BucketType* first_empty_bucket = nullptr; for (;;) { @@ -478,9 +468,7 @@ private: } [[nodiscard]] BucketType& lookup_for_writing(T const& value) { - auto* item = try_lookup_for_writing(value); - VERIFY(item); - return *item; + return *MUST(try_lookup_for_writing(value)); } [[nodiscard]] size_t used_bucket_count() const { return m_size + m_deleted_count; } diff --git a/Kernel/PerformanceEventBuffer.cpp b/Kernel/PerformanceEventBuffer.cpp index fc8e10f3da..7bf55726fb 100644 --- a/Kernel/PerformanceEventBuffer.cpp +++ b/Kernel/PerformanceEventBuffer.cpp @@ -315,10 +315,7 @@ void PerformanceEventBuffer::add_process(const Process& process, ProcessEventTyp ErrorOr<FlatPtr> PerformanceEventBuffer::register_string(NonnullOwnPtr<KString> string) { FlatPtr string_id = m_strings.size(); - - if (m_strings.try_set(move(string)) == AK::HashSetResult::Failed) - return ENOBUFS; - + TRY(m_strings.try_set(move(string))); return string_id; } |