32#define AGX_DECLARE_HASHSET_TYPES(type) \
33typedef agx::HashSet<type ## Ref> type ## RefSet; \
34typedef agx::HashSet<type ## Observer> type ## ObserverSet; \
35typedef agx::HashSet<type *> type ## PtrSet
39# pragma warning(disable: 6011)
48 template <
typename KeyT,
typename HashT = HashFn<KeyT>,
typename AllocatorT = ByteAllocator>
63 #define AGX_HASH_SET_MIN_SIZE 1
65 #define AGX_HASH_SET_GROW_THRESHOLD 0.8
66 #define AGX_HASH_SET_SHRINK_THRESHOLD 0.25
67 #define AGX_HASH_SET_GROW_FACTOR 2.0
68 #define AGX_HASH_SET_SHRINK_FACTOR 0.5
69 #define AGX_HASH_SET_SMOOTHING_FACTOR 0.8
70 #define AGX_HASH_SET_MAX_PROBE_LENGTH 10
80 typedef typename std::iterator_traits<T>::value_type
value_type;
82 typedef typename std::iterator_traits<T>::reference
reference;
83 typedef typename std::iterator_traits<T>::pointer
pointer;
90 { this->gotoNextElement(); }
96 constIt.m_hashSet = m_hashSet;
97 constIt.m_currentIndex = m_currentIndex;
103 this->gotoNextElement();
109 size_t oldIndex = m_currentIndex;
110 this->gotoNextElement();
118 this->gotoPreviousElement();
124 size_t oldIndex = m_currentIndex;
125 this->gotoPreviousElement();
131 {
return this->m_currentIndex == rhs.m_currentIndex && this->m_hashSet == rhs.m_hashSet; }
134 {
return this->m_currentIndex != rhs.m_currentIndex || this->m_hashSet != rhs.m_hashSet; }
139 agxAssert1(m_hashSet && m_currentIndex != m_hashSet->numBuckets(),
"Can not dereference an invalid bucket!");
140 return m_hashSet->buckets()[m_currentIndex].key;
149 m_hashSet = copy.m_hashSet;
150 m_currentIndex = copy.m_currentIndex;
158 while (m_currentIndex < m_hashSet->
numBuckets() && !m_hashSet->buckets()[m_currentIndex].isValid())
164 if (m_currentIndex > 0) {
166 while (m_currentIndex > 0 && !m_hashSet->buckets()[m_currentIndex].isValid())
173 size_t m_currentIndex;
209 { m_allocator.setContainer(
this); }
220 if (
this == &other ) {
224 m_allocator = other.m_allocator;
225 m_allocator.setContainer(
this);
252 UInt32 hashValue = m_hashFunctor(key);
270 targetBucket = bucket;
275 if (!bucket->
isValid() && !targetBucket)
276 targetBucket = bucket;
279 if (targetBucket && offset >= m_maxProbeLength)
295 if (offset > m_maxProbeLength)
296 m_maxProbeLength = (
UInt16)offset;
298 targetBucket->
key = key;
301 bool overwrite = targetBucket->
isValid();
393 return iterator(
this, it.m_currentIndex);
417 m_smoothingAverage = 0.0;
449 m_maxProbeLength = 0;
489 const AllocatorT&
allocator()
const {
return m_allocator; }
515 {
return state >= ACTIVE; }
518 {
return state == VALID; }
545 const size_t desiredNumBytes = desiredNumBuckets *
sizeof(
Bucket);
547 m_buffer = m_allocator.allocateBytes(desiredNumBytes);
548 for (
size_t i = 0; i < desiredNumBuckets; ++i)
553 m_maxProbeLength = 0;
555 for (
size_t i = 0; i < oldNumBuckets; i++)
557 Bucket& bucket = oldBuckets[i];
563 for (
size_t i = 0; i < oldNumBuckets; ++i)
566 m_allocator.deallocateBytes((
void *)oldBuckets, oldNumBuckets *
sizeof(
Bucket));
570 template <
typename T2>
576 UInt32 hashValue = m_hashFunctor(key);
585 for (
size_t offset = 1; bucket->
isActive() && offset <= m_maxProbeLength; offset++)
587 index = (hashValue + offset * offset) %
numBuckets();
623 Real32 m_smoothingAverage;
625 AllocatorT m_allocator;
668 template <
typename KeyT,
typename HashT = HashFn<KeyT>,
typename AllocatorT = ByteAllocator>
678 template <
typename KeyT,
typename HashT,
typename AllocatorT>
#define AGX_HASH_SET_SHRINK_THRESHOLD
#define AGX_HASH_SET_SMOOTHING_FACTOR
#define AGX_HASH_SET_MIN_SIZE
#define AGX_HASH_SET_MAX_PROBE_LENGTH
#define AGX_HASH_SET_SHRINK_FACTOR
#define AGX_HASH_SET_GROW_FACTOR
#define AGX_HASH_SET_GROW_THRESHOLD
The Container is the base class for several of the container classes proided by AGX,...
ClearPolicy
agxData::Values from this enumeration is passed to the subclasses' 'clear' method in order to control...
@ SHRINK_BUFFER
Buffer is deallocated and replaced by an newly allocated empty buffer.
@ MAINTAIN_BUFFER
Buffer is maintained (normal stl behavior).
@ SHRINK_BUFFER_AVERAGED
Buffer is shrunk if a smoothing average (which is updated each clear call) goes below a threshold.
insert_iterator(HashSetT *hashSet, size_t startIndex, bool overwrite)
bool didOverwrite() const
iterator::HashSetT HashSetT
bool operator==(const template_iterator< T > &rhs)
template_iterator()
Constructors.
template_iterator< T > operator--()
template_iterator< T > & operator=(const template_iterator< T > ©)
std::iterator_traits< T >::difference_type difference_type
std::iterator_traits< T >::iterator_category iterator_category
template_iterator< T > operator--(int)
template_iterator(T *hashSet, size_t startIndex=0)
std::iterator_traits< T >::reference reference
std::iterator_traits< T >::pointer pointer
std::iterator_traits< T >::value_type value_type
KeyT * operator->() const
bool operator!=(const template_iterator< T > &rhs)
template_iterator< T > & operator++()
template_iterator< T > operator++(int)
Same as hash table, but only containing keys, not key-value pairs.
const_iterator end() const
const_iterator find(const KeyT &key) const
size_t findBucket(const T2 &key) const
HashSetImplementation(const HashSetImplementation< KeyT, HashT, AllocatorT > &other)
Copy constructor.
void purge(T purger)
Purge the hash set.
iterator begin()
Iterator to first element in hash set.
~HashSetImplementation()
Destructor.
void rebuild(size_t size)
Rebuild, and optionally resize hash set.
const AllocatorT & allocator() const
const_iterator begin() const
HashSetImplementation(const AllocatorT &allocator=AllocatorT())
Constructor.
HashSetImplementation< KeyT, HashT, AllocatorT > & operator=(const HashSetImplementation< KeyT, HashT, AllocatorT > &other)
Assignment operator.
template_iterator< HashSetImplementation< KeyT, HashT, AllocatorT > > iterator
Iterators.
void reserve(size_t size)
Reserve capacity in the hash set.
iterator erase(const iterator &it)
Erase an element using an iterator.
std::bidirectional_iterator_tag iterator_category
bool eraseBucket(size_t index)
const KeyT & operator[](const KeyT &key) const
iterator find(const KeyT &key)
Find an element.
const KeyT * const_pointer
iterator end()
Iterator marking end of hash set.
KeyT & operator[](const KeyT &key)
Index operator for accessing elements in the hash, inserting it if not found.
bool erase(const KeyT &key)
Erase an element from the hash set.
size_t numBuckets() const
const KeyT & const_reference
bool contains(const KeyT &key) const
Boolean query to test existence of an element.
template_iterator< const HashSetImplementation< KeyT, HashT, AllocatorT > > const_iterator
insert_iterator insert(const KeyT &key)
Insert an element, overwriting if key already exists.
void clear(ClearPolicy policy=SHRINK_BUFFER_AVERAGED)
Remove all elements.
const_iterator find(const KeyT *key) const
iterator find(const KeyT *key)
bool contains(const KeyT *key) const
Implementation::iterator iterator
bool erase(const KeyT *key)
HashSet(const AllocatorT &allocator=AllocatorT())
HashSetImplementation< agx::ref_ptr< KeyT >, HashT, AllocatorT > Implementation
Implementation::const_iterator const_iterator
Inheritance with partial specialization due to bug with ref_ptr containers.
HashSet(const AllocatorT &allocator=AllocatorT())
HashSetImplementation< KeyT, HashT, AllocatorT > Implementation
Smart pointer for handling referenced counted objects.
#define agxAssert1(expr, msg)
#define DOXYGEN_END_INTERNAL_BLOCK()
#define DOXYGEN_START_INTERNAL_BLOCK()
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
AGXCORE_EXPORT int nextPrime(int n)
bool hashKeyEqual(const T1 &key1, const T2 &key2)