From 062cbe18a424751764d568fc1ea4d08b9f2172d4 Mon Sep 17 00:00:00 2001 From: Jessica James Date: Sun, 18 Dec 2016 03:01:13 -0500 Subject: [PATCH] Added Bucket::erase(), optimized assignment operators --- Jupiter/Hash_Table.h | 9 +++- Jupiter/Hash_Table_Imp.h | 97 +++++++++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 23 deletions(-) diff --git a/Jupiter/Hash_Table.h b/Jupiter/Hash_Table.h index c307d1f..5eb97f5 100644 --- a/Jupiter/Hash_Table.h +++ b/Jupiter/Hash_Table.h @@ -87,6 +87,13 @@ namespace Jupiter */ ValueT *remove(const InKeyT &in_key); + /** + * @brief Erases all entries from the bucket + * + * @return Number of entries erased + */ + size_t erase(); + /** * @brief Copy assignment operator * @@ -227,7 +234,7 @@ namespace Jupiter * @param in_buckets Array of buckets to copy entries into * @param in_buckets_size Number of buckets in in_buckets */ - void copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size); + void copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const; Bucket *m_buckets; /** Array of Buckets */ size_t m_buckets_size; /** Number of buckets */ diff --git a/Jupiter/Hash_Table_Imp.h b/Jupiter/Hash_Table_Imp.h index 8b49045..51d426f 100644 --- a/Jupiter/Hash_Table_Imp.h +++ b/Jupiter/Hash_Table_Imp.h @@ -114,6 +114,15 @@ ValueT *Jupiter::Hash_Table::Bucket::remo return nullptr; } +template +size_t Jupiter::Hash_Table::Bucket::erase() +{ + size_t length = m_pairs.size(); + m_pairs.eraseAndDelete(); + + return length; +} + template typename Jupiter::Hash_Table::Bucket &Jupiter::Hash_Table::Bucket::operator=(const Bucket &in_bucket) { @@ -209,15 +218,49 @@ void Jupiter::Hash_Table::shrink() template typename Jupiter::Hash_Table &Jupiter::Hash_Table::operator=(const Hash_Table &in_table) { - // TODO: Optimize; can overwrite data instead of deleting and allocationg again if m_buckets_size > in.m_buckets_size - delete[] m_buckets; + if (m_buckets_size >= in_table.m_buckets_size && m_buckets_size <= in_table.m_buckets_size * 2) + { + // We're larger than what we're copying, but not drastically (2x) larger. Just erase our current data and copy their entries. - m_length = in_table.m_length; - m_buckets_size = in_table.m_buckets_size; - m_buckets = new Bucket[m_buckets_size]; + if (m_length == 0) // we don't need to erase any data + in_table.copy_to_buckets(m_buckets, m_buckets_size); + else + { + // we need to erase data; slightly modified version of copy_to_buckets() + Jupiter::SLList::Node *node; - for (size_t index = 0; index != m_buckets_size; ++index) - m_buckets[index] = in_table.m_buckets[index]; + size_t index = 0; + while (index != in_table.m_buckets_size) + { + in_table.m_buckets[index].m_pairs.eraseAndDelete(); + + for (node = in_table.m_buckets[index].m_pairs.getHead(); node != nullptr; node = node->next) + m_buckets[HashF(node->data->key) % m_buckets_size].set(node->data->key, node->data->value); + + ++index; + } + + while (index != m_buckets_size) + { + in_table.m_buckets[index].m_pairs.eraseAndDelete(); + ++index; + } + } + } + else + { + // m_buckets is either too small to copy the data, or it'd be too wasteful + + delete[] m_buckets; + + m_buckets_size = in_table.m_buckets_size; + m_buckets = new Bucket[m_buckets_size]; + + for (size_t index = 0; index != m_buckets_size; ++index) + m_buckets[index] = in_table.m_buckets[index]; + } + + m_length = in_table.m_length; return *this; } @@ -225,16 +268,32 @@ typename Jupiter::Hash_Table &Jupiter::Ha template typename Jupiter::Hash_Table &Jupiter::Hash_Table::operator=(Hash_Table &&in_table) { - // TODO: Optimize; can swap empty array instead of always deleting - delete[] m_buckets; + if (m_length == 0) + { + Bucket *old_buckets = m_buckets; + size_t old_buckets_size = m_buckets_size; - m_buckets = in_table.m_buckets; - m_buckets_size = in_table.m_buckets_size; - m_length = in_table.m_length; + m_buckets = in_table.m_buckets; + m_buckets_size = in_table.m_buckets_size; + m_length = in_table.m_length; + + in_table.m_buckets = old_buckets; + in_table.m_buckets_size = old_buckets_size; + } + else + { + delete[] m_buckets; + + m_buckets = in_table.m_buckets; + m_buckets_size = in_table.m_buckets_size; + m_length = in_table.m_length; + + in_table.m_buckets = new Bucket[1]; + in_table.m_buckets_size = 1; + } - in_table.m_buckets = new Bucket[1]; - in_table.m_buckets_size = 1; in_table.m_length = 0; + return *this; } @@ -299,19 +358,13 @@ void Jupiter::Hash_Table::expand() } template -void Jupiter::Hash_Table::copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) +void Jupiter::Hash_Table::copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const { Jupiter::SLList::Node *node; + for (size_t index = 0; index != m_buckets_size; ++index) - { for (node = m_buckets[index].m_pairs.getHead(); node != nullptr; node = node->next) in_buckets[HashF(node->data->key) % in_buckets_size].set(node->data->key, node->data->value); - } } -/* -template -Jupiter::Hash_Table -*/ - #endif // _HASH_TABLE_IMP_H_HEADER \ No newline at end of file