Fix shrinking new unordered_set_map to save memory. No end-result change intended.
This commit is contained in:
parent
35654b5355
commit
ec82243ee6
|
|
@ -43,6 +43,7 @@
|
|||
#include "verilatedos.h"
|
||||
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// Abstract 'vl_hash' and 'vl_equal_to' templates.
|
||||
|
|
@ -112,6 +113,7 @@ public:
|
|||
// TYPES
|
||||
typedef std::list<Key> Bucket;
|
||||
typedef vluint64_t size_type;
|
||||
enum RehashType {GROW, SHRINK};
|
||||
|
||||
template <class KK, class VV,
|
||||
class HH, class EQ> friend class vl_unordered_map;
|
||||
|
|
@ -192,12 +194,16 @@ public:
|
|||
vl_unordered_set()
|
||||
: m_numElements(0)
|
||||
, m_log2Buckets(4)
|
||||
, m_bucketsp(NULL) { }
|
||||
, m_bucketsp(NULL)
|
||||
, m_hash()
|
||||
, m_equal() { }
|
||||
|
||||
vl_unordered_set(const vl_unordered_set& other)
|
||||
: m_numElements(other.m_numElements)
|
||||
, m_log2Buckets(other.m_log2Buckets)
|
||||
, m_bucketsp(NULL) {
|
||||
, m_bucketsp(NULL)
|
||||
, m_hash()
|
||||
, m_equal() {
|
||||
if (other.m_bucketsp) {
|
||||
m_bucketsp = new Bucket[numBuckets()];
|
||||
for (size_type i = 0; i < numBuckets(); i++) {
|
||||
|
|
@ -308,10 +314,9 @@ public:
|
|||
// if we don't rehash:
|
||||
iterator result_it(bucketIdx, m_bucketsp[bucketIdx].begin(), this);
|
||||
|
||||
if (needToRehash()) {
|
||||
rehash();
|
||||
// ... since we rehashed, do a lookup to get the
|
||||
// result iterator.
|
||||
if (needToRehash(GROW)) {
|
||||
rehash(GROW);
|
||||
// ... since we rehashed, do a lookup to get the result iterator.
|
||||
result_it = find(val);
|
||||
}
|
||||
|
||||
|
|
@ -331,6 +336,13 @@ public:
|
|||
if (it != end()) {
|
||||
m_bucketsp[bucketIdx].erase(it.bit());
|
||||
m_numElements--;
|
||||
// Rehashing to handle a shrinking data set is important
|
||||
// for the Scoreboard in V3Partition, which begins tracking
|
||||
// a huge number of vertices and then tracks a successively
|
||||
// smaller number over time.
|
||||
if (needToRehash(SHRINK)) {
|
||||
rehash(SHRINK);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -338,9 +350,8 @@ public:
|
|||
|
||||
void clear() {
|
||||
if (m_bucketsp) {
|
||||
for (size_type i = 0; i < numBuckets(); i++) {
|
||||
m_bucketsp[i].clear();
|
||||
}
|
||||
delete [] m_bucketsp;
|
||||
m_bucketsp = NULL;
|
||||
}
|
||||
m_numElements = 0;
|
||||
}
|
||||
|
|
@ -357,10 +368,28 @@ private:
|
|||
if (!m_bucketsp) m_bucketsp = new Bucket[numBuckets()];
|
||||
}
|
||||
|
||||
bool needToRehash() const { return ((4 * numBuckets()) < m_numElements); }
|
||||
bool needToRehash(RehashType rt) const {
|
||||
if (rt == GROW) {
|
||||
return ((4 * numBuckets()) < m_numElements);
|
||||
} else {
|
||||
return (numBuckets() > (4 * m_numElements));
|
||||
}
|
||||
}
|
||||
|
||||
void rehash(RehashType rt) {
|
||||
size_type new_log2Buckets;
|
||||
if (rt == GROW) {
|
||||
new_log2Buckets = m_log2Buckets + 2;
|
||||
} else {
|
||||
if (m_log2Buckets <= 4) {
|
||||
// On shrink, saturate m_log2Buckets at its
|
||||
// initial size of 2^4 == 16 buckets. Don't risk
|
||||
// underflowing!
|
||||
return;
|
||||
}
|
||||
new_log2Buckets = m_log2Buckets - 2;
|
||||
}
|
||||
|
||||
void rehash() {
|
||||
size_type new_log2Buckets = m_log2Buckets + 2;
|
||||
size_type new_num_buckets = VL_ULL(1) << new_log2Buckets;
|
||||
Bucket* new_bucketsp = new Bucket[new_num_buckets];
|
||||
|
||||
|
|
@ -475,7 +504,12 @@ template <class Key,
|
|||
// For the 'set', it's generally not safe to modify
|
||||
// the value after deref. For the 'map' though, we know
|
||||
// it's safe to modify the value field and we can allow it:
|
||||
return const_cast<Value&>(it->second);
|
||||
return it->second;
|
||||
}
|
||||
Value& at(const Key& k) {
|
||||
iterator it = find(k);
|
||||
if (it == end()) { throw std::out_of_range("sorry"); }
|
||||
return it->second;
|
||||
}
|
||||
void clear() { m_set.clear(); }
|
||||
size_type size() const { return m_set.size(); }
|
||||
|
|
|
|||
|
|
@ -158,10 +158,17 @@
|
|||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define VL_EQ_DELETE = delete
|
||||
# define vl_unique_ptr std::unique_ptr
|
||||
# define vl_unordered_map std::unordered_map
|
||||
# define vl_unordered_set std::unordered_set
|
||||
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
|
||||
# define VL_INCLUDE_UNORDERED_SET <unordered_set>
|
||||
// By default we use std:: types in C++11.
|
||||
// Define VL_USE_UNORDERED_TYPES to test these pre-C++11 classes
|
||||
# ifdef VL_USE_UNORDERED_TYPES
|
||||
# define VL_INCLUDE_UNORDERED_MAP "verilated_unordered_set_map.h"
|
||||
# define VL_INCLUDE_UNORDERED_SET "verilated_unordered_set_map.h"
|
||||
# else
|
||||
# define vl_unordered_map std::unordered_map
|
||||
# define vl_unordered_set std::unordered_set
|
||||
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
|
||||
# define VL_INCLUDE_UNORDERED_SET <unordered_set>
|
||||
# endif
|
||||
#else
|
||||
# define VL_EQ_DELETE
|
||||
# define vl_unique_ptr std::auto_ptr
|
||||
|
|
|
|||
Loading…
Reference in New Issue