summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-03-07 15:48:04 +0000
committerMaxime Coste <mawww@kakoune.org>2017-03-07 15:48:04 +0000
commita1a566e921677acbae084d53c0f7aac59e8130ce (patch)
treed53d3ca2ebeb11df34991293f71dc28b608c824f /src
parentba02498576b634883bb9a0e48377f7383bc86289 (diff)
Cleanup hash_map code
Diffstat (limited to 'src')
-rw-r--r--src/hash_map.hh35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/hash_map.hh b/src/hash_map.hh
index ab7b5e75..b3ed49a9 100644
--- a/src/hash_map.hh
+++ b/src/hash_map.hh
@@ -17,11 +17,11 @@ struct HashIndex
int index;
};
- void grow()
+ void resize(size_t new_size)
{
+ kak_assert(new_size > m_entries.size());
Vector<Entry, domain> old_entries = std::move(m_entries);
- constexpr size_t init_size = 4;
- m_entries.resize(old_entries.empty() ? init_size : old_entries.size() * 2, {0,-1});
+ m_entries.resize(new_size, {0,-1});
for (auto& entry : old_entries)
{
if (entry.index >= 0)
@@ -29,12 +29,19 @@ struct HashIndex
}
}
- void add(size_t hash, int index)
+ void reserve(size_t count)
{
- ++m_count;
- if ((float)m_count / m_entries.size() > m_max_fill_rate)
- grow();
+ constexpr float max_fill_rate = 0.5f;
+ const size_t min_size = (size_t)(count / max_fill_rate) + 1;
+ size_t new_size = m_entries.empty() ? 4 : m_entries.size();
+ while (new_size < min_size)
+ new_size *= 2;
+ if (new_size > m_entries.size())
+ resize(new_size);
+ }
+ void add(size_t hash, int index)
+ {
Entry entry{hash, index};
while (true)
{
@@ -55,14 +62,13 @@ struct HashIndex
target_slot = candidate_slot;
}
}
- // no free entries found, grow, try again
- grow();
+ // no free entries found, resize, try again
+ resize(m_entries.size() * 2);
}
}
void remove(size_t hash, int index)
{
- --m_count;
for (auto slot = compute_slot(hash); slot < m_entries.size(); ++slot)
{
kak_assert(m_entries[slot].index >= 0);
@@ -110,14 +116,12 @@ struct HashIndex
size_t compute_slot(size_t hash) const
{
// We assume entries.size() is power of 2
- return m_entries.empty() ? 0 : hash & (m_entries.size()-1);
+ return hash & (m_entries.size()-1);
}
void clear() { m_entries.clear(); }
private:
- size_t m_count = 0;
- static constexpr float m_max_fill_rate = 0.9f;
Vector<Entry, domain> m_entries;
};
@@ -137,12 +141,14 @@ struct HashMap
HashMap(std::initializer_list<Item> val) : m_items{val}
{
+ m_index.reserve(val.size());
for (int i = 0; i < m_items.size(); ++i)
m_index.add(hash_value(m_items[i].key), i);
}
Value& insert(Item item)
{
+ m_index.reserve(m_items.size()+1);
m_index.add(hash_value(item.key), (int)m_items.size());
m_items.push_back(std::move(item));
return m_items.back().value;
@@ -181,6 +187,7 @@ struct HashMap
if (index >= 0)
return m_items[index].value;
+ m_index.reserve(m_items.size()+1);
m_index.add(hash, (int)m_items.size());
m_items.push_back({Key{std::forward<KeyType>(key)}, {}});
return m_items.back().value;
@@ -257,7 +264,7 @@ struct HashMap
void reserve(size_t size)
{
m_items.reserve(size);
- // TODO: Reserve in the index as well
+ m_index.reserve(size);
}
// Equality is taking the order of insertion into account