BAN: Implement find() for HashMap

This commit is contained in:
Bananymous 2024-02-27 15:40:30 +02:00
parent 5c39903323
commit 3c88d2aad3
2 changed files with 53 additions and 10 deletions

View File

@ -57,6 +57,8 @@ namespace BAN
T& operator[](const Key&); T& operator[](const Key&);
const T& operator[](const Key&) const; const T& operator[](const Key&) const;
iterator find(const Key& key);
const_iterator find(const Key& key) const;
bool contains(const Key&) const; bool contains(const Key&) const;
bool empty() const; bool empty() const;
@ -66,6 +68,8 @@ namespace BAN
ErrorOr<void> rebucket(size_type); ErrorOr<void> rebucket(size_type);
LinkedList<Entry>& get_bucket(const Key&); LinkedList<Entry>& get_bucket(const Key&);
const LinkedList<Entry>& get_bucket(const Key&) const; const LinkedList<Entry>& get_bucket(const Key&) const;
Vector<LinkedList<Entry>>::iterator get_bucket_iterator(const Key&);
Vector<LinkedList<Entry>>::const_iterator get_bucket_iterator(const Key&) const;
private: private:
Vector<LinkedList<Entry>> m_buckets; Vector<LinkedList<Entry>> m_buckets;
@ -187,15 +191,34 @@ namespace BAN
ASSERT(false); ASSERT(false);
} }
template<typename Key, typename T, typename HASH>
typename HashMap<Key, T, HASH>::iterator HashMap<Key, T, HASH>::find(const Key& key)
{
if (empty())
return end();
auto bucket_it = get_bucket_iterator(key);
for (auto it = bucket_it->begin(); it != bucket_it->end(); it++)
if (it->key == key)
return iterator(m_buckets.end(), bucket_it, it);
return end();
}
template<typename Key, typename T, typename HASH>
typename HashMap<Key, T, HASH>::const_iterator HashMap<Key, T, HASH>::find(const Key& key) const
{
if (empty())
return end();
auto bucket_it = get_bucket_iterator(key);
for (auto it = bucket_it->begin(); it != bucket_it->end(); it++)
if (it->key == key)
return const_iterator(m_buckets.end(), bucket_it, it);
return end();
}
template<typename Key, typename T, typename HASH> template<typename Key, typename T, typename HASH>
bool HashMap<Key, T, HASH>::contains(const Key& key) const bool HashMap<Key, T, HASH>::contains(const Key& key) const
{ {
if (empty()) return false; return find(key) != end();
const auto& bucket = get_bucket(key);
for (const Entry& entry : bucket)
if (entry.key == key)
return true;
return false;
} }
template<typename Key, typename T, typename HASH> template<typename Key, typename T, typename HASH>
@ -236,17 +259,29 @@ namespace BAN
template<typename Key, typename T, typename HASH> template<typename Key, typename T, typename HASH>
LinkedList<typename HashMap<Key, T, HASH>::Entry>& HashMap<Key, T, HASH>::get_bucket(const Key& key) LinkedList<typename HashMap<Key, T, HASH>::Entry>& HashMap<Key, T, HASH>::get_bucket(const Key& key)
{ {
ASSERT(!m_buckets.empty()); return *get_bucket_iterator(key);
auto index = HASH()(key) % m_buckets.size();
return m_buckets[index];
} }
template<typename Key, typename T, typename HASH> template<typename Key, typename T, typename HASH>
const LinkedList<typename HashMap<Key, T, HASH>::Entry>& HashMap<Key, T, HASH>::get_bucket(const Key& key) const const LinkedList<typename HashMap<Key, T, HASH>::Entry>& HashMap<Key, T, HASH>::get_bucket(const Key& key) const
{
return *get_bucket_iterator(key);
}
template<typename Key, typename T, typename HASH>
Vector<LinkedList<typename HashMap<Key, T, HASH>::Entry>>::iterator HashMap<Key, T, HASH>::get_bucket_iterator(const Key& key)
{ {
ASSERT(!m_buckets.empty()); ASSERT(!m_buckets.empty());
auto index = HASH()(key) % m_buckets.size(); auto index = HASH()(key) % m_buckets.size();
return m_buckets[index]; return next(m_buckets.begin(), index);
}
template<typename Key, typename T, typename HASH>
Vector<LinkedList<typename HashMap<Key, T, HASH>::Entry>>::const_iterator HashMap<Key, T, HASH>::get_bucket_iterator(const Key& key) const
{
ASSERT(!m_buckets.empty());
auto index = HASH()(key) % m_buckets.size();
return next(m_buckets.begin(), index);
} }
} }

View File

@ -284,6 +284,14 @@ namespace BAN
} }
} }
IteratorDoubleGeneral(const OuterIterator& outer_end, const OuterIterator& outer_current, const InnerIterator& inner_current)
: m_outer_end(outer_end)
, m_outer_current(outer_current)
, m_inner_current(inner_current)
{
find_valid_or_end();
}
void find_valid_or_end() void find_valid_or_end()
{ {
while (m_inner_current == m_outer_current->end()) while (m_inner_current == m_outer_current->end())