mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Fix HashTable::find() return iterator for items found in non-0 buckets.
This commit is contained in:
parent
c94044a04a
commit
39444c5916
Notes:
sideshowbarker
2024-07-19 18:48:15 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/39444c5916c
2 changed files with 31 additions and 15 deletions
|
@ -40,10 +40,12 @@ public:
|
|||
{
|
||||
auto* node = new Node(std::move(value));
|
||||
if (!m_head) {
|
||||
ASSERT(!m_tail);
|
||||
m_head = node;
|
||||
m_tail = node;
|
||||
return;
|
||||
}
|
||||
ASSERT(m_tail);
|
||||
m_tail->next = node;
|
||||
node->prev = m_tail;
|
||||
m_tail = node;
|
||||
|
@ -112,14 +114,20 @@ public:
|
|||
{
|
||||
ASSERT(it.m_node);
|
||||
auto* node = it.m_node;
|
||||
if (node->prev)
|
||||
if (node->prev) {
|
||||
ASSERT(node != m_head);
|
||||
node->prev->next = node->next;
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
if (m_head == node)
|
||||
} else {
|
||||
ASSERT(node == m_head);
|
||||
m_head = node->next;
|
||||
if (m_tail == node)
|
||||
}
|
||||
if (node->next) {
|
||||
ASSERT(node != m_tail);
|
||||
node->next->prev = node->prev;
|
||||
} else {
|
||||
ASSERT(node == m_tail);
|
||||
m_tail = node->prev;
|
||||
}
|
||||
delete node;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue