From cc54b43e68608b10af87258c6e30d148ac7760db Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 12 Feb 2019 22:46:28 -0500 Subject: [PATCH] shared: Finish HashSet and fixup HashMap. Changes are pretty straightforward. The iterator is now const again, but can be passed to the hash table itself for removal of the current item. Change-Id: Ifd3c8096ffb187a183ca5963ed69a256562a524f Reviewed-on: https://review.haiku-os.org/c/1042 Reviewed-by: waddlesplash --- headers/private/shared/HashMap.h | 75 ++++++++++++++++++++++---------- headers/private/shared/HashSet.h | 49 ++++++++++----------- 2 files changed, 74 insertions(+), 50 deletions(-) diff --git a/headers/private/shared/HashMap.h b/headers/private/shared/HashMap.h index 453c56b506..d7168c14c4 100644 --- a/headers/private/shared/HashMap.h +++ b/headers/private/shared/HashMap.h @@ -1,16 +1,18 @@ /* * Copyright 2004-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2019, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef HASH_MAP_H #define HASH_MAP_H -//#include - -#include +#include +#include #include "AutoLocker.h" -#include "Locker.h" + + +namespace BPrivate { // HashMapElement @@ -98,20 +100,6 @@ public: return Entry(fElement->fKey, fElement->fValue); } - Entry Remove() - { - if (fElement == NULL) - return Entry(); - - Entry result(fElement->fKey, fElement->fValue); - - fMap->fTable.RemoveUnchecked(fElement); - delete fElement; - fElement = NULL; - - return result; - } - Iterator& operator=(const Iterator& other) { fMap = other.fMap; @@ -121,7 +109,7 @@ public: } private: - Iterator(HashMap* map) + Iterator(const HashMap* map) : fMap(map), fIterator(map->fTable.GetIterator()), @@ -134,7 +122,7 @@ public: typedef BOpenHashTable > ElementTable; - HashMap* fMap; + const HashMap* fMap; typename ElementTable::Iterator fIterator; Element* fElement; }; @@ -146,14 +134,16 @@ public: status_t Put(const Key& key, const Value& value); Value Remove(const Key& key); + Value Remove(Iterator& it); void Clear(); Value Get(const Key& key) const; + bool Get(const Key& key, Value*& _value) const; bool ContainsKey(const Key& key) const; int32 Size() const; - Iterator GetIterator(); + Iterator GetIterator() const; protected: typedef BOpenHashTable > ElementTable; @@ -166,7 +156,7 @@ protected: // SynchronizedHashMap -template +template class SynchronizedHashMap : public Locker { public: typedef typename HashMap::Entry Entry; @@ -414,6 +404,25 @@ HashMap::Remove(const Key& key) } +// Remove +template +Value +HashMap::Remove(Iterator& it) +{ + Element* element = it.fElement; + if (element == NULL) + return Value(); + + Value value = element->fValue; + + fTable.RemoveUnchecked(element); + delete element; + it.fElement = NULL; + + return value; +} + + // Clear template void @@ -440,6 +449,19 @@ HashMap::Get(const Key& key) const } +// Get +template +bool +HashMap::Get(const Key& key, Value*& _value) const +{ + if (Element* element = fTable.Lookup(key)) { + _value = &element->fValue; + return true; + } + return false; +} + + // ContainsKey template bool @@ -461,10 +483,17 @@ HashMap::Size() const // GetIterator template typename HashMap::Iterator -HashMap::GetIterator() +HashMap::GetIterator() const { return Iterator(this); } +} // namespace BPrivate + +using BPrivate::HashMap; +using BPrivate::HashKey32; +using BPrivate::HashKey64; +using BPrivate::HashKeyPointer; +using BPrivate::SynchronizedHashMap; #endif // HASH_MAP_H diff --git a/headers/private/shared/HashSet.h b/headers/private/shared/HashSet.h index 373f127ae8..195d994d13 100644 --- a/headers/private/shared/HashSet.h +++ b/headers/private/shared/HashSet.h @@ -1,36 +1,43 @@ /* * Copyright 2004-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2019, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef HASH_SET_H #define HASH_SET_H -#include +#include +#include #include "AutoLocker.h" -#include "Locker.h" + + +namespace BPrivate { // HashSetElement template -class HashSetElement : public HashTableLink > { +class HashSetElement { private: typedef HashSetElement Element; public: HashSetElement() : - fKey() + fKey(), + fNext(NULL) { } HashSetElement(const Key& key) : - fKey(key) + fKey(key), + fNext(NULL) { } - Key fKey; + Key fKey; + HashSetElement* fNext; }; @@ -46,8 +53,8 @@ struct HashSetTableDefinition { { return HashKey(value->fKey); } bool Compare(const KeyType& key, const ValueType* value) const { return value->fKey == key; } - HashTableLink* GetLink(ValueType* value) const - { return value; } + ValueType*& GetLink(ValueType* value) const + { return value->fNext; } }; @@ -111,8 +118,7 @@ public: } private: - friend class HashMap; - typedef OpenHashTable > ElementTable; + typedef BOpenHashTable > ElementTable; HashSet* fSet; ElementTable::Iterator fIterator; @@ -137,7 +143,7 @@ public: Iterator GetIterator(); protected: - typedef OpenHashTable > ElementTable; + typedef BOpenHashTable > ElementTable; typedef HashSetElement Element; friend class Iterator; @@ -147,7 +153,7 @@ protected: // SynchronizedHashSet -template +template class SynchronizedHashSet : public Locker { public: typedef HashSet::Iterator Iterator; @@ -284,7 +290,7 @@ HashSet::Remove(const Key& key) // Clear -template +template void HashSet::Clear() { @@ -315,6 +321,7 @@ HashSet::Size() const return fTable.CountElements(); } + // GetIterator template HashSet::Iterator @@ -323,20 +330,8 @@ HashSet::GetIterator() return Iterator(this); } -// _FindElement -template -HashSet::Element * -HashSet::_FindElement(const Key& key) const -{ - Element* element = fTable.FindFirst(key.GetHashCode()); - while (element && element->fKey != key) { - if (element->fNext >= 0) - element = fTable.ElementAt(element->fNext); - else - element = NULL; - } - return element; -} +} // namespace BPrivate +using BPrivate::HashSet; #endif // HASH_SET_H