summaryrefslogtreecommitdiff
path: root/AK/HashTable.h
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-14 22:08:36 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-14 22:08:36 +0200
commit39444c5916c2b9519417163e173713122ec6f8ce (patch)
treee1a4cd1d2be8e495d79c371d0f9c32faa07f9ebe /AK/HashTable.h
parentc94044a04a05b18b723aba82a69a15d379fed87f (diff)
downloadserenity-39444c5916c2b9519417163e173713122ec6f8ce.zip
Fix HashTable::find() return iterator for items found in non-0 buckets.
Diffstat (limited to 'AK/HashTable.h')
-rw-r--r--AK/HashTable.h28
1 files changed, 18 insertions, 10 deletions
diff --git a/AK/HashTable.h b/AK/HashTable.h
index 4de631a582..e42c3c4dbe 100644
--- a/AK/HashTable.h
+++ b/AK/HashTable.h
@@ -104,8 +104,9 @@ public:
}
private:
friend class HashTable;
- explicit Iterator(HashTable& table, bool isEnd, typename DoublyLinkedList<T>::Iterator bucketIterator = DoublyLinkedList<T>::Iterator::universalEnd())
+ explicit Iterator(HashTable& table, bool isEnd, typename DoublyLinkedList<T>::Iterator bucketIterator = DoublyLinkedList<T>::Iterator::universalEnd(), unsigned bucketIndex = 0)
: m_table(table)
+ , m_bucketIndex(bucketIndex)
, m_isEnd(isEnd)
, m_bucketIterator(bucketIterator)
{
@@ -179,8 +180,9 @@ public:
}
private:
friend class HashTable;
- ConstIterator(const HashTable& table, bool isEnd, typename DoublyLinkedList<T>::ConstIterator bucketIterator = DoublyLinkedList<T>::ConstIterator::universalEnd())
+ ConstIterator(const HashTable& table, bool isEnd, typename DoublyLinkedList<T>::ConstIterator bucketIterator = DoublyLinkedList<T>::ConstIterator::universalEnd(), unsigned bucketIndex = 0)
: m_table(table)
+ , m_bucketIndex(bucketIndex)
, m_isEnd(isEnd)
, m_bucketIterator(bucketIterator)
{
@@ -217,8 +219,8 @@ public:
void remove(Iterator&);
private:
- Bucket& lookup(const T&);
- const Bucket& lookup(const T&) const;
+ Bucket& lookup(const T&, unsigned* bucketIndex = nullptr);
+ const Bucket& lookup(const T&, unsigned* bucketIndex = nullptr) const;
void rehash(unsigned capacity);
void insert(T&&);
@@ -305,10 +307,11 @@ auto HashTable<T, TraitsForT>::find(const T& value) -> Iterator
{
if (isEmpty())
return end();
- auto& bucket = lookup(value);
+ unsigned bucketIndex;
+ auto& bucket = lookup(value, &bucketIndex);
auto bucketIterator = bucket.chain.find(value);
if (bucketIterator != bucket.chain.end())
- return Iterator(*this, false, bucketIterator);
+ return Iterator(*this, false, bucketIterator, bucketIndex);
return end();
}
@@ -317,10 +320,11 @@ auto HashTable<T, TraitsForT>::find(const T& value) const -> ConstIterator
{
if (isEmpty())
return end();
- auto& bucket = lookup(value);
+ unsigned bucketIndex;
+ auto& bucket = lookup(value, &bucketIndex);
auto bucketIterator = bucket.chain.find(value);
if (bucketIterator != bucket.chain.end())
- return ConstIterator(*this, false, bucketIterator);
+ return ConstIterator(*this, false, bucketIterator, bucketIndex);
return end();
}
@@ -333,7 +337,7 @@ void HashTable<T, TraitsForT>::remove(Iterator& it)
}
template<typename T, typename TraitsForT>
-typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(const T& value)
+typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(const T& value, unsigned* bucketIndex)
{
unsigned hash = TraitsForT::hash(value);
#ifdef HASHTABLE_DEBUG
@@ -341,11 +345,13 @@ typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(cons
TraitsForT::dump(value);
printf(" is %u\n", hash);
#endif
+ if (bucketIndex)
+ *bucketIndex = hash % m_capacity;
return m_buckets[hash % m_capacity];
}
template<typename T, typename TraitsForT>
-const typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(const T& value) const
+const typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::lookup(const T& value, unsigned* bucketIndex) const
{
unsigned hash = TraitsForT::hash(value);
#ifdef HASHTABLE_DEBUG
@@ -353,6 +359,8 @@ const typename HashTable<T, TraitsForT>::Bucket& HashTable<T, TraitsForT>::looku
TraitsForT::dump(value);
printf(" is %u\n", hash);
#endif
+ if (bucketIndex)
+ *bucketIndex = hash % m_capacity;
return m_buckets[hash % m_capacity];
}