libluna: Implement hash table iteration
All checks were successful
Build and test / build (push) Successful in 1m47s
All checks were successful
Build and test / build (push) Successful in 1m47s
This commit is contained in:
parent
903dcfa52c
commit
7345a952ca
@ -154,6 +154,16 @@ template <typename K, typename V> struct HashMap
|
|||||||
m_table.clear();
|
m_table.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HashTable<HashPair<K, V>>::HashTableIterator begin()
|
||||||
|
{
|
||||||
|
return m_table.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const HashTable<HashPair<K, V>>::HashTableIterator end()
|
||||||
|
{
|
||||||
|
return m_table.end();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HashTable<HashPair<K, V>> m_table;
|
HashTable<HashPair<K, V>> m_table;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <luna/Heap.h>
|
#include <luna/Heap.h>
|
||||||
#include <luna/Option.h>
|
#include <luna/Option.h>
|
||||||
|
|
||||||
|
template <typename K, typename V> class HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A table of values with best-case constant time lookup.
|
* @brief A table of values with best-case constant time lookup.
|
||||||
*
|
*
|
||||||
@ -181,6 +183,77 @@ template <typename T> class HashTable
|
|||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HashTableIterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HashTableIterator(usize index, HashTable<T>& table) : m_table(table)
|
||||||
|
{
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
m_index = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (usize i = 0; i < m_table.m_capacity; i++)
|
||||||
|
{
|
||||||
|
auto& opt = m_table.m_buckets[i];
|
||||||
|
if (opt.has_value())
|
||||||
|
{
|
||||||
|
m_index = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_index = m_table.m_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable usize m_index;
|
||||||
|
HashTable<T>& m_table;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T& operator*()
|
||||||
|
{
|
||||||
|
return *m_table.m_buckets[m_index].value_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const
|
||||||
|
{
|
||||||
|
return *m_table.m_buckets[m_index].value_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator++() const
|
||||||
|
{
|
||||||
|
for (usize i = m_index + 1; i < m_table.m_capacity; i++)
|
||||||
|
{
|
||||||
|
auto& opt = m_table.m_buckets[i];
|
||||||
|
if (opt.has_value())
|
||||||
|
{
|
||||||
|
m_index = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_index = m_table.m_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(HashTableIterator& other) const
|
||||||
|
{
|
||||||
|
return m_index != other.m_index || &m_table != &other.m_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class HashTable<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HashTableIterator begin()
|
||||||
|
{
|
||||||
|
return { (usize)-1, *this };
|
||||||
|
}
|
||||||
|
|
||||||
|
const HashTableIterator end()
|
||||||
|
{
|
||||||
|
return { m_capacity, *this };
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool should_grow()
|
bool should_grow()
|
||||||
{
|
{
|
||||||
@ -223,4 +296,6 @@ template <typename T> class HashTable
|
|||||||
usize m_size { 0 };
|
usize m_size { 0 };
|
||||||
// FIXME: Randomize this to protect against hash table attacks.
|
// FIXME: Randomize this to protect against hash table attacks.
|
||||||
u64 m_salt { 0 };
|
u64 m_salt { 0 };
|
||||||
|
|
||||||
|
friend class HashTableIterator;
|
||||||
};
|
};
|
||||||
|
@ -80,6 +80,24 @@ TestResult test_hash_map_set_and_get()
|
|||||||
test_success;
|
test_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestResult test_hash_table_iteration()
|
||||||
|
{
|
||||||
|
HashTable<int> table;
|
||||||
|
|
||||||
|
validate(TRY(table.try_set(1)));
|
||||||
|
validate(TRY(table.try_set(2)));
|
||||||
|
validate(TRY(table.try_set(3)));
|
||||||
|
validate(TRY(table.try_set(4)));
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
for (const int& value : table) { sum += value; }
|
||||||
|
|
||||||
|
validate(sum == 10);
|
||||||
|
|
||||||
|
test_success;
|
||||||
|
}
|
||||||
|
|
||||||
Result<void> test_main()
|
Result<void> test_main()
|
||||||
{
|
{
|
||||||
test_prelude;
|
test_prelude;
|
||||||
@ -89,6 +107,7 @@ Result<void> test_main()
|
|||||||
run_test(test_hash_table_remove);
|
run_test(test_hash_table_remove);
|
||||||
run_test(test_hash_table_duplicates);
|
run_test(test_hash_table_duplicates);
|
||||||
run_test(test_hash_map_set_and_get);
|
run_test(test_hash_map_set_and_get);
|
||||||
|
run_test(test_hash_table_iteration);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user