Modifs in Map and Set containers

This commit is contained in:
Daniel Chappuis 2019-03-25 07:35:40 +01:00
parent dcc07447a8
commit 703f91b4d3
2 changed files with 37 additions and 32 deletions

View File

@ -43,7 +43,7 @@ namespace reactphysics3d {
* This class represents a simple generic associative map. This map is * This class represents a simple generic associative map. This map is
* implemented with a hash table. * implemented with a hash table.
*/ */
template<typename K, typename V> template<typename K, typename V, class Hash = std::hash<K>, class KeyEqual = std::equal_to<K>>
class Map { class Map {
private: private:
@ -207,11 +207,12 @@ class Map {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashCode = std::hash<K>()(key); const size_t hashCode = Hash()(key);
int bucket = hashCode % mCapacity; int bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
if (mEntries[i].hashCode == hashCode && mEntries[i].keyValue->first == key) { if (mEntries[i].hashCode == hashCode && keyEqual(mEntries[i].keyValue->first, key)) {
return i; return i;
} }
} }
@ -428,16 +429,18 @@ class Map {
} }
// Compute the hash code of the key // Compute the hash code of the key
size_t hashCode = std::hash<K>()(keyValue.first); const size_t hashCode = Hash()(keyValue.first);
// Compute the corresponding bucket index // Compute the corresponding bucket index
int bucket = hashCode % mCapacity; int bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
// Check if the item is already in the map // Check if the item is already in the map
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
// If there is already an item with the same key in the map // If there is already an item with the same key in the map
if (mEntries[i].hashCode == hashCode && mEntries[i].keyValue->first == keyValue.first) { if (mEntries[i].hashCode == hashCode && keyEqual(mEntries[i].keyValue->first, keyValue.first)) {
if (insertIfAlreadyPresent) { if (insertIfAlreadyPresent) {
@ -505,12 +508,14 @@ class Map {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashcode = std::hash<K>()(key); const size_t hashcode = Hash()(key);
int bucket = hashcode % mCapacity; int bucket = hashcode % mCapacity;
int last = -1; int last = -1;
auto keyEqual = KeyEqual();
for (int i = mBuckets[bucket]; i >= 0; last = i, i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; last = i, i = mEntries[i].next) {
if (mEntries[i].hashCode == hashcode && mEntries[i].keyValue->first == key) { if (mEntries[i].hashCode == hashcode && keyEqual(mEntries[i].keyValue->first, key)) {
if (last < 0 ) { if (last < 0 ) {
mBuckets[bucket] = mEntries[i].next; mBuckets[bucket] = mEntries[i].next;
@ -612,11 +617,13 @@ class Map {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashCode = std::hash<K>()(key); const size_t hashCode = Hash()(key);
bucket = hashCode % mCapacity; bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
if (mEntries[i].hashCode == hashCode && mEntries[i].keyValue->first == key) { if (mEntries[i].hashCode == hashCode && keyEqual(mEntries[i].keyValue->first, key)) {
entry = i; entry = i;
break; break;
} }
@ -767,15 +774,15 @@ class Map {
} }
}; };
template<typename K, typename V> template<typename K, typename V, class Hash, class KeyEqual>
const int Map<K,V>::PRIMES[NB_PRIMES] = {3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, const int Map<K,V, Hash, KeyEqual>::PRIMES[NB_PRIMES] = {3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559}; 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559};
template<typename K, typename V> template<typename K, typename V, class Hash, class KeyEqual>
int Map<K,V>::LARGEST_PRIME = -1; int Map<K,V, Hash, KeyEqual>::LARGEST_PRIME = -1;
} }

View File

@ -94,12 +94,6 @@ class Set {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Object with hash operator
const Hash mHash;
/// Object with equality operator
const KeyEqual mEqual;
/// Current number of used entries in the set /// Current number of used entries in the set
int mNbUsedEntries; int mNbUsedEntries;
@ -212,11 +206,12 @@ class Set {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashCode = mHash(value); size_t hashCode = Hash()(value);
int bucket = hashCode % mCapacity; int bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
if (mEntries[i].hashCode == hashCode && mEqual(*mEntries[i].value, value)) { if (mEntries[i].hashCode == hashCode && keyEqual(*mEntries[i].value, value)) {
return i; return i;
} }
} }
@ -332,7 +327,7 @@ class Set {
} }
/// Pre increment (++it) /// Pre increment (++it)
Iterator operator++(int number) { Iterator operator++(int) {
Iterator tmp = *this; Iterator tmp = *this;
advance(); advance();
return tmp; return tmp;
@ -353,9 +348,8 @@ class Set {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Set(MemoryAllocator& allocator, size_t capacity = 0, const Hash& hash = Hash(), Set(MemoryAllocator& allocator, size_t capacity = 0)
const KeyEqual& equal = KeyEqual()) : mNbUsedEntries(0), mNbFreeEntries(0), mCapacity(0), mBuckets(nullptr),
: mHash(hash), mEqual(equal), mNbUsedEntries(0), mNbFreeEntries(0), mCapacity(0), mBuckets(nullptr),
mEntries(nullptr), mAllocator(allocator), mFreeIndex(-1) { mEntries(nullptr), mAllocator(allocator), mFreeIndex(-1) {
// If the largest prime has not been computed yet // If the largest prime has not been computed yet
@ -373,7 +367,7 @@ class Set {
/// Copy constructor /// Copy constructor
Set(const Set<V, Hash, KeyEqual>& set) Set(const Set<V, Hash, KeyEqual>& set)
:mHash(set.mHash), mEqual(set.mEqual), mNbUsedEntries(set.mNbUsedEntries), mNbFreeEntries(set.mNbFreeEntries), mCapacity(set.mCapacity), :mNbUsedEntries(set.mNbUsedEntries), mNbFreeEntries(set.mNbFreeEntries), mCapacity(set.mCapacity),
mBuckets(nullptr), mEntries(nullptr), mAllocator(set.mAllocator), mFreeIndex(set.mFreeIndex) { mBuckets(nullptr), mEntries(nullptr), mAllocator(set.mAllocator), mFreeIndex(set.mFreeIndex) {
if (mCapacity > 0) { if (mCapacity > 0) {
@ -435,16 +429,18 @@ class Set {
} }
// Compute the hash code of the value // Compute the hash code of the value
size_t hashCode = mHash(value); size_t hashCode = Hash()(value);
// Compute the corresponding bucket index // Compute the corresponding bucket index
int bucket = hashCode % mCapacity; int bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
// Check if the item is already in the set // Check if the item is already in the set
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
// If there is already an item with the same value in the set // If there is already an item with the same value in the set
if (mEntries[i].hashCode == hashCode && mEqual(*mEntries[i].value, value)) { if (mEntries[i].hashCode == hashCode && keyEqual(*mEntries[i].value, value)) {
return false; return false;
} }
@ -501,12 +497,13 @@ class Set {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashcode = mHash(value); size_t hashcode = Hash()(value);
auto keyEqual = KeyEqual();
int bucket = hashcode % mCapacity; int bucket = hashcode % mCapacity;
int last = -1; int last = -1;
for (int i = mBuckets[bucket]; i >= 0; last = i, i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; last = i, i = mEntries[i].next) {
if (mEntries[i].hashCode == hashcode && mEqual(*mEntries[i].value, value)) { if (mEntries[i].hashCode == hashcode && keyEqual(*mEntries[i].value, value)) {
if (last < 0 ) { if (last < 0 ) {
mBuckets[bucket] = mEntries[i].next; mBuckets[bucket] = mEntries[i].next;
@ -604,11 +601,12 @@ class Set {
if (mCapacity > 0) { if (mCapacity > 0) {
size_t hashCode = mHash(value); size_t hashCode = Hash()(value);
bucket = hashCode % mCapacity; bucket = hashCode % mCapacity;
auto keyEqual = KeyEqual();
for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) { for (int i = mBuckets[bucket]; i >= 0; i = mEntries[i].next) {
if (mEntries[i].hashCode == hashCode && mEqual(*(mEntries[i].value), value)) { if (mEntries[i].hashCode == hashCode && keyEqual(*(mEntries[i].value), value)) {
entry = i; entry = i;
break; break;
} }