From 205187b561c3b31fa931e73e8f7263f0c4b1de41 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 15 Jun 2017 13:24:25 -0700 Subject: Rename `CoreLib::*` to `Slang` Getting rid of more namespace complexity and stripping things down to the basics. This also gets rid of some dead code in the "core" library. --- source/core/dictionary.h | 1703 +++++++++++++++++++++++----------------------- 1 file changed, 850 insertions(+), 853 deletions(-) (limited to 'source/core/dictionary.h') diff --git a/source/core/dictionary.h b/source/core/dictionary.h index 77f0df515..c052685fd 100644 --- a/source/core/dictionary.h +++ b/source/core/dictionary.h @@ -7,1012 +7,1009 @@ #include "slang-math.h" #include "hash.h" -namespace CoreLib +namespace Slang { - namespace Basic + template + class KeyValuePair { - template - class KeyValuePair + public: + TKey Key; + TValue Value; + KeyValuePair() + {} + KeyValuePair(const TKey & key, const TValue & value) { - public: - TKey Key; - TValue Value; - KeyValuePair() - {} - KeyValuePair(const TKey & key, const TValue & value) - { - Key = key; - Value = value; - } - KeyValuePair(TKey && key, TValue && value) - { - Key = _Move(key); - Value = _Move(value); - } - KeyValuePair(TKey && key, const TValue & value) - { - Key = _Move(key); - Value = value; - } - KeyValuePair(const KeyValuePair & _that) - { - Key = _that.Key; - Value = _that.Value; - } - KeyValuePair(KeyValuePair && _that) - { - operator=(_Move(_that)); - } - KeyValuePair & operator=(KeyValuePair && that) - { - Key = _Move(that.Key); - Value = _Move(that.Value); - return *this; - } - KeyValuePair & operator=(const KeyValuePair & that) - { - Key = that.Key; - Value = that.Value; - return *this; - } - int GetHashCode() - { - return GetHashCode(Key); - } - }; - - template - inline KeyValuePair KVPair(const TKey & k, const TValue & v) + Key = key; + Value = value; + } + KeyValuePair(TKey && key, TValue && value) + { + Key = _Move(key); + Value = _Move(value); + } + KeyValuePair(TKey && key, const TValue & value) + { + Key = _Move(key); + Value = value; + } + KeyValuePair(const KeyValuePair & _that) + { + Key = _that.Key; + Value = _that.Value; + } + KeyValuePair(KeyValuePair && _that) + { + operator=(_Move(_that)); + } + KeyValuePair & operator=(KeyValuePair && that) + { + Key = _Move(that.Key); + Value = _Move(that.Value); + return *this; + } + KeyValuePair & operator=(const KeyValuePair & that) + { + Key = that.Key; + Value = that.Value; + return *this; + } + int GetHashCode() { - return KeyValuePair(k, v); + return GetHashCode(Key); } + }; - const float MaxLoadFactor = 0.7f; + template + inline KeyValuePair KVPair(const TKey & k, const TValue & v) + { + return KeyValuePair(k, v); + } - template - class Dictionary + const float MaxLoadFactor = 0.7f; + + template + class Dictionary + { + friend class Iterator; + friend class ItemProxy; + private: + inline int GetProbeOffset(int /*probeId*/) const { - friend class Iterator; - friend class ItemProxy; - private: - inline int GetProbeOffset(int /*probeId*/) const - { - // quadratic probing - return 1; - } - private: - int bucketSizeMinusOne, shiftBits; - int _count; - IntSet marks; - KeyValuePair* hashMap; - void Free() - { - if (hashMap) - delete[] hashMap; - hashMap = 0; - } - inline bool IsDeleted(int pos) const - { - return marks.Contains((pos << 1) + 1); - } - inline bool IsEmpty(int pos) const - { - return !marks.Contains((pos << 1)); - } - inline void SetDeleted(int pos, bool val) + // quadratic probing + return 1; + } + private: + int bucketSizeMinusOne, shiftBits; + int _count; + IntSet marks; + KeyValuePair* hashMap; + void Free() + { + if (hashMap) + delete[] hashMap; + hashMap = 0; + } + inline bool IsDeleted(int pos) const + { + return marks.Contains((pos << 1) + 1); + } + inline bool IsEmpty(int pos) const + { + return !marks.Contains((pos << 1)); + } + inline void SetDeleted(int pos, bool val) + { + if (val) + marks.Add((pos << 1) + 1); + else + marks.Remove((pos << 1) + 1); + } + inline void SetEmpty(int pos, bool val) + { + if (val) + marks.Remove((pos << 1)); + else + marks.Add((pos << 1)); + } + struct FindPositionResult + { + int ObjectPosition; + int InsertionPosition; + FindPositionResult() { - if (val) - marks.Add((pos << 1) + 1); - else - marks.Remove((pos << 1) + 1); + ObjectPosition = -1; + InsertionPosition = -1; } - inline void SetEmpty(int pos, bool val) + FindPositionResult(int objPos, int insertPos) { - if (val) - marks.Remove((pos << 1)); - else - marks.Add((pos << 1)); + ObjectPosition = objPos; + InsertionPosition = insertPos; } - struct FindPositionResult - { - int ObjectPosition; - int InsertionPosition; - FindPositionResult() - { - ObjectPosition = -1; - InsertionPosition = -1; - } - FindPositionResult(int objPos, int insertPos) - { - ObjectPosition = objPos; - InsertionPosition = insertPos; - } - }; - template - inline int GetHashPos(T & key) const - { - return ((unsigned int)(GetHashCode(key) * 2654435761)) >> shiftBits; - } - template - FindPositionResult FindPosition(const T & key) const + }; + template + inline int GetHashPos(T & key) const + { + return ((unsigned int)(GetHashCode(key) * 2654435761)) >> shiftBits; + } + template + FindPositionResult FindPosition(const T & key) const + { + int hashPos = GetHashPos((T&)key); + int insertPos = -1; + int numProbes = 0; + while (numProbes <= bucketSizeMinusOne) { - int hashPos = GetHashPos((T&)key); - int insertPos = -1; - int numProbes = 0; - while (numProbes <= bucketSizeMinusOne) + if (IsEmpty(hashPos)) { - if (IsEmpty(hashPos)) - { - if (insertPos == -1) - return FindPositionResult(-1, hashPos); - else - return FindPositionResult(-1, insertPos); - } - else if (IsDeleted(hashPos)) - { - if (insertPos == -1) - insertPos = hashPos; - } - else if (hashMap[hashPos].Key == key) - { - return FindPositionResult(hashPos, -1); - } - numProbes++; - hashPos = (hashPos + GetProbeOffset(numProbes)) & bucketSizeMinusOne; + if (insertPos == -1) + return FindPositionResult(-1, hashPos); + else + return FindPositionResult(-1, insertPos); } - if (insertPos != -1) - return FindPositionResult(-1, insertPos); - throw InvalidOperationException("Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode."); - } - TValue & _Insert(KeyValuePair && kvPair, int pos) - { - hashMap[pos] = _Move(kvPair); - SetEmpty(pos, false); - SetDeleted(pos, false); - return hashMap[pos].Value; - } - void Rehash() - { - if (bucketSizeMinusOne == -1 || _count / (float)bucketSizeMinusOne >= MaxLoadFactor) + else if (IsDeleted(hashPos)) { - int newSize = (bucketSizeMinusOne + 1) * 2; - int newShiftBits = shiftBits - 1; - if (newSize == 0) - { - newSize = 16; - newShiftBits = 28; - } - Dictionary newDict; - newDict.shiftBits = newShiftBits; - newDict.bucketSizeMinusOne = newSize - 1; - newDict.hashMap = new KeyValuePair[newSize]; - newDict.marks.SetMax(newSize * 2); - if (hashMap) - { - for (auto & kvPair : *this) - { - newDict.Add(_Move(kvPair)); - } - } - *this = _Move(newDict); + if (insertPos == -1) + insertPos = hashPos; } - } - - bool AddIfNotExists(KeyValuePair && kvPair) - { - Rehash(); - auto pos = FindPosition(kvPair.Key); - if (pos.ObjectPosition != -1) - return false; - else if (pos.InsertionPosition != -1) + else if (hashMap[hashPos].Key == key) { - _count++; - _Insert(_Move(kvPair), pos.InsertionPosition); - return true; + return FindPositionResult(hashPos, -1); } - else - throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); - } - void Add(KeyValuePair && kvPair) - { - if (!AddIfNotExists(_Move(kvPair))) - throw KeyExistsException("The key already exists in Dictionary."); + numProbes++; + hashPos = (hashPos + GetProbeOffset(numProbes)) & bucketSizeMinusOne; } - TValue & Set(KeyValuePair && kvPair) - { - Rehash(); - auto pos = FindPosition(kvPair.Key); - if (pos.ObjectPosition != -1) - return _Insert(_Move(kvPair), pos.ObjectPosition); - else if (pos.InsertionPosition != -1) - { - _count++; - return _Insert(_Move(kvPair), pos.InsertionPosition); - } - else - throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); - } - public: - class Iterator + if (insertPos != -1) + return FindPositionResult(-1, insertPos); + throw InvalidOperationException("Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode."); + } + TValue & _Insert(KeyValuePair && kvPair, int pos) + { + hashMap[pos] = _Move(kvPair); + SetEmpty(pos, false); + SetDeleted(pos, false); + return hashMap[pos].Value; + } + void Rehash() + { + if (bucketSizeMinusOne == -1 || _count / (float)bucketSizeMinusOne >= MaxLoadFactor) { - private: - const Dictionary * dict; - int pos; - public: - KeyValuePair & operator *() const - { - return dict->hashMap[pos]; - } - KeyValuePair * operator ->() const + int newSize = (bucketSizeMinusOne + 1) * 2; + int newShiftBits = shiftBits - 1; + if (newSize == 0) { - return dict->hashMap + pos; + newSize = 16; + newShiftBits = 28; } - Iterator & operator ++() + Dictionary newDict; + newDict.shiftBits = newShiftBits; + newDict.bucketSizeMinusOne = newSize - 1; + newDict.hashMap = new KeyValuePair[newSize]; + newDict.marks.SetMax(newSize * 2); + if (hashMap) { - if (pos > dict->bucketSizeMinusOne) - return *this; - pos++; - while (pos <= dict->bucketSizeMinusOne && (dict->IsDeleted(pos) || dict->IsEmpty(pos))) + for (auto & kvPair : *this) { - pos++; + newDict.Add(_Move(kvPair)); } - return *this; - } - Iterator operator ++(int) - { - Iterator rs = *this; - operator++(); - return rs; - } - bool operator != (const Iterator & _that) const - { - return pos != _that.pos || dict != _that.dict; - } - bool operator == (const Iterator & _that) const - { - return pos == _that.pos && dict == _that.dict; - } - Iterator(const Dictionary * _dict, int _pos) - { - this->dict = _dict; - this->pos = _pos; - } - Iterator() - { - this->dict = 0; - this->pos = 0; - } - }; - - Iterator begin() const - { - int pos = 0; - while (pos < bucketSizeMinusOne + 1) - { - if (IsEmpty(pos) || IsDeleted(pos)) - pos++; - else - break; - } - return Iterator(this, pos); - } - Iterator end() const - { - return Iterator(this, bucketSizeMinusOne + 1); - } - public: - void Add(const TKey & key, const TValue & value) - { - Add(KeyValuePair(key, value)); - } - void Add(TKey && key, TValue && value) - { - Add(KeyValuePair(_Move(key), _Move(value))); - } - bool AddIfNotExists(const TKey & key, const TValue & value) - { - return AddIfNotExists(KeyValuePair(key, value)); - } - bool AddIfNotExists(TKey && key, TValue && value) - { - return AddIfNotExists(KeyValuePair(_Move(key), _Move(value))); - } - void Remove(const TKey & key) - { - if (_count == 0) - return; - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) - { - SetDeleted(pos.ObjectPosition, true); - _count--; } + *this = _Move(newDict); } - void Clear() - { - _count = 0; - - marks.Clear(); - } + } - template - bool ContainsKey(const T & key) const - { - if (bucketSizeMinusOne == -1) - return false; - auto pos = FindPosition(key); - return pos.ObjectPosition != -1; - } - template - bool TryGetValue(const T & key, TValue & value) const - { - if (bucketSizeMinusOne == -1) - return false; - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) - { - value = hashMap[pos.ObjectPosition].Value; - return true; - } + bool AddIfNotExists(KeyValuePair && kvPair) + { + Rehash(); + auto pos = FindPosition(kvPair.Key); + if (pos.ObjectPosition != -1) return false; - } - template - TValue * TryGetValue(const T & key) const - { - if (bucketSizeMinusOne == -1) - return nullptr; - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) - { - return &hashMap[pos.ObjectPosition].Value; - } - return nullptr; - } - class ItemProxy - { - private: - const Dictionary * dict; - TKey key; - public: - ItemProxy(const TKey & _key, const Dictionary * _dict) - { - this->dict = _dict; - this->key = _key; - } - ItemProxy(TKey && _key, const Dictionary * _dict) - { - this->dict = _dict; - this->key = _Move(_key); - } - TValue & GetValue() const - { - auto pos = dict->FindPosition(key); - if (pos.ObjectPosition != -1) - { - return dict->hashMap[pos.ObjectPosition].Value; - } - else - throw KeyNotFoundException("The key does not exists in dictionary."); - } - inline TValue & operator()() const - { - return GetValue(); - } - operator TValue&() const - { - return GetValue(); - } - TValue & operator = (const TValue & val) const - { - return ((Dictionary*)dict)->Set(KeyValuePair(_Move(key), val)); - } - TValue & operator = (TValue && val) const - { - return ((Dictionary*)dict)->Set(KeyValuePair(_Move(key), _Move(val))); - } - }; - ItemProxy operator [](const TKey & key) const + else if (pos.InsertionPosition != -1) { - return ItemProxy(key, this); + _count++; + _Insert(_Move(kvPair), pos.InsertionPosition); + return true; } - ItemProxy operator [](TKey && key) const - { - return ItemProxy(_Move(key), this); - } - int Count() const + else + throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); + } + void Add(KeyValuePair && kvPair) + { + if (!AddIfNotExists(_Move(kvPair))) + throw KeyExistsException("The key already exists in Dictionary."); + } + TValue & Set(KeyValuePair && kvPair) + { + Rehash(); + auto pos = FindPosition(kvPair.Key); + if (pos.ObjectPosition != -1) + return _Insert(_Move(kvPair), pos.ObjectPosition); + else if (pos.InsertionPosition != -1) { - return _count; + _count++; + return _Insert(_Move(kvPair), pos.InsertionPosition); } + else + throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); + } + public: + class Iterator + { private: - template - void Init(const KeyValuePair & kvPair, Args... args) - { - Add(kvPair); - Init(args...); - } + const Dictionary * dict; + int pos; public: - Dictionary() - { - bucketSizeMinusOne = -1; - shiftBits = 32; - _count = 0; - hashMap = 0; - } - template - Dictionary(Arg arg, Args... args) - { - Init(arg, args...); - } - Dictionary(const Dictionary & other) - : bucketSizeMinusOne(-1), _count(0), hashMap(0) + KeyValuePair & operator *() const { - *this = other; + return dict->hashMap[pos]; } - Dictionary(Dictionary && other) - : bucketSizeMinusOne(-1), _count(0), hashMap(0) + KeyValuePair * operator ->() const { - *this = (_Move(other)); + return dict->hashMap + pos; } - Dictionary & operator = (const Dictionary & other) + Iterator & operator ++() { - if (this == &other) + if (pos > dict->bucketSizeMinusOne) return *this; - Free(); - bucketSizeMinusOne = other.bucketSizeMinusOne; - _count = other._count; - shiftBits = other.shiftBits; - hashMap = new KeyValuePair[other.bucketSizeMinusOne + 1]; - marks = other.marks; - for (int i = 0; i <= bucketSizeMinusOne; i++) - hashMap[i] = other.hashMap[i]; - return *this; - } - Dictionary & operator = (Dictionary && other) - { - if (this == &other) - return *this; - Free(); - bucketSizeMinusOne = other.bucketSizeMinusOne; - _count = other._count; - hashMap = other.hashMap; - shiftBits = other.shiftBits; - marks = _Move(other.marks); - other.hashMap = 0; - other._count = 0; - other.bucketSizeMinusOne = -1; + pos++; + while (pos <= dict->bucketSizeMinusOne && (dict->IsDeleted(pos) || dict->IsEmpty(pos))) + { + pos++; + } return *this; } - ~Dictionary() + Iterator operator ++(int) { - Free(); + Iterator rs = *this; + operator++(); + return rs; } - }; - - template - class EnumerableDictionary - { - friend class Iterator; - friend class ItemProxy; - private: - inline int GetProbeOffset(int /*probeIdx*/) const + bool operator != (const Iterator & _that) const { - // quadratic probing - return 1; + return pos != _that.pos || dict != _that.dict; } - private: - int bucketSizeMinusOne, shiftBits; - int _count; - IntSet marks; - - // debug op - struct Op - { - TKey key; - int opType; - Op() - {} - Op(const TKey & key, int t) - { - this->key = key; - opType = t; - } - }; - LinkedList> kvPairs; - LinkedNode>** hashMap; - void Free() + bool operator == (const Iterator & _that) const { - if (hashMap) - delete[] hashMap; - hashMap = 0; - kvPairs.Clear(); + return pos == _that.pos && dict == _that.dict; } - inline bool IsDeleted(int pos) const + Iterator(const Dictionary * _dict, int _pos) { - return marks.Contains((pos << 1) + 1); + this->dict = _dict; + this->pos = _pos; } - inline bool IsEmpty(int pos) const + Iterator() { - return !marks.Contains((pos << 1)); + this->dict = 0; + this->pos = 0; } - inline void SetDeleted(int pos, bool val) + }; + + Iterator begin() const + { + int pos = 0; + while (pos < bucketSizeMinusOne + 1) { - if (val) - marks.Add((pos << 1) + 1); + if (IsEmpty(pos) || IsDeleted(pos)) + pos++; else - marks.Remove((pos << 1) + 1); + break; } - inline void SetEmpty(int pos, bool val) + return Iterator(this, pos); + } + Iterator end() const + { + return Iterator(this, bucketSizeMinusOne + 1); + } + public: + void Add(const TKey & key, const TValue & value) + { + Add(KeyValuePair(key, value)); + } + void Add(TKey && key, TValue && value) + { + Add(KeyValuePair(_Move(key), _Move(value))); + } + bool AddIfNotExists(const TKey & key, const TValue & value) + { + return AddIfNotExists(KeyValuePair(key, value)); + } + bool AddIfNotExists(TKey && key, TValue && value) + { + return AddIfNotExists(KeyValuePair(_Move(key), _Move(value))); + } + void Remove(const TKey & key) + { + if (_count == 0) + return; + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) { - if (val) - marks.Remove((pos << 1)); - else - marks.Add((pos << 1)); + SetDeleted(pos.ObjectPosition, true); + _count--; } - struct FindPositionResult - { - int ObjectPosition; - int InsertionPosition; - FindPositionResult() - { - ObjectPosition = -1; - InsertionPosition = -1; - } - FindPositionResult(int objPos, int insertPos) - { - ObjectPosition = objPos; - InsertionPosition = insertPos; - } + } + void Clear() + { + _count = 0; - }; - template - inline int GetHashPos(T & key) const - { - return ((unsigned int)(GetHashCode(key) * 2654435761)) >> shiftBits; - } - template - FindPositionResult FindPosition(const T & key) const - { - int hashPos = GetHashPos((T&)key); - int insertPos = -1; - int numProbes = 0; - while (numProbes <= bucketSizeMinusOne) - { - if (IsEmpty(hashPos)) - { - if (insertPos == -1) - return FindPositionResult(-1, hashPos); - else - return FindPositionResult(-1, insertPos); - } - else if (IsDeleted(hashPos)) - { - if (insertPos == -1) - insertPos = hashPos; - } - else if (hashMap[hashPos]->Value.Key == key) - { - return FindPositionResult(hashPos, -1); - } - numProbes++; - hashPos = (hashPos + GetProbeOffset(numProbes)) & bucketSizeMinusOne; - } - if (insertPos != -1) - return FindPositionResult(-1, insertPos); - throw InvalidOperationException("Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode."); - } - TValue & _Insert(KeyValuePair && kvPair, int pos) + marks.Clear(); + } + + template + bool ContainsKey(const T & key) const + { + if (bucketSizeMinusOne == -1) + return false; + auto pos = FindPosition(key); + return pos.ObjectPosition != -1; + } + template + bool TryGetValue(const T & key, TValue & value) const + { + if (bucketSizeMinusOne == -1) + return false; + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) { - auto node = kvPairs.AddLast(); - node->Value = _Move(kvPair); - hashMap[pos] = node; - SetEmpty(pos, false); - SetDeleted(pos, false); - return node->Value.Value; + value = hashMap[pos.ObjectPosition].Value; + return true; } - void Rehash() + return false; + } + template + TValue * TryGetValue(const T & key) const + { + if (bucketSizeMinusOne == -1) + return nullptr; + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) { - if (bucketSizeMinusOne == -1 || _count / (float)bucketSizeMinusOne >= MaxLoadFactor) - { - int newSize = (bucketSizeMinusOne + 1) * 2; - int newShiftBits = shiftBits - 1; - if (newSize == 0) - { - newSize = 16; - newShiftBits = 28; - } - EnumerableDictionary newDict; - newDict.shiftBits = newShiftBits; - newDict.bucketSizeMinusOne = newSize - 1; - newDict.hashMap = new LinkedNode>*[newSize]; - newDict.marks.SetMax(newSize * 2); - if (hashMap) - { - for (auto & kvPair : *this) - { - newDict.Add(_Move(kvPair)); - } - } - *this = _Move(newDict); - } + return &hashMap[pos.ObjectPosition].Value; } - - bool AddIfNotExists(KeyValuePair && kvPair) + return nullptr; + } + class ItemProxy + { + private: + const Dictionary * dict; + TKey key; + public: + ItemProxy(const TKey & _key, const Dictionary * _dict) { - Rehash(); - auto pos = FindPosition(kvPair.Key); - if (pos.ObjectPosition != -1) - return false; - else if (pos.InsertionPosition != -1) - { - _count++; - _Insert(_Move(kvPair), pos.InsertionPosition); - return true; - } - else - throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); + this->dict = _dict; + this->key = _key; } - void Add(KeyValuePair && kvPair) + ItemProxy(TKey && _key, const Dictionary * _dict) { - if (!AddIfNotExists(_Move(kvPair))) - throw KeyExistsException("The key already exists in Dictionary."); + this->dict = _dict; + this->key = _Move(_key); } - TValue & Set(KeyValuePair && kvPair) + TValue & GetValue() const { - Rehash(); - auto pos = FindPosition(kvPair.Key); + auto pos = dict->FindPosition(key); if (pos.ObjectPosition != -1) { - hashMap[pos.ObjectPosition]->Delete(); - return _Insert(_Move(kvPair), pos.ObjectPosition); - } - else if (pos.InsertionPosition != -1) - { - _count++; - return _Insert(_Move(kvPair), pos.InsertionPosition); + return dict->hashMap[pos.ObjectPosition].Value; } else - throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); - } - public: - typedef typename LinkedList>::Iterator Iterator; - - typename LinkedList>::Iterator begin() const - { - return kvPairs.begin(); - } - typename LinkedList>::Iterator end() const - { - return kvPairs.end(); + throw KeyNotFoundException("The key does not exists in dictionary."); } - public: - void Add(const TKey & key, const TValue & value) + inline TValue & operator()() const { - Add(KeyValuePair(key, value)); + return GetValue(); } - void Add(TKey && key, TValue && value) + operator TValue&() const { - Add(KeyValuePair(_Move(key), _Move(value))); + return GetValue(); } - bool AddIfNotExists(const TKey & key, const TValue & value) + TValue & operator = (const TValue & val) const { - return AddIfNotExists(KeyValuePair(key, value)); + return ((Dictionary*)dict)->Set(KeyValuePair(_Move(key), val)); } - bool AddIfNotExists(TKey && key, TValue && value) + TValue & operator = (TValue && val) const { - return AddIfNotExists(KeyValuePair(_Move(key), _Move(value))); + return ((Dictionary*)dict)->Set(KeyValuePair(_Move(key), _Move(val))); } - void Remove(const TKey & key) + }; + ItemProxy operator [](const TKey & key) const + { + return ItemProxy(key, this); + } + ItemProxy operator [](TKey && key) const + { + return ItemProxy(_Move(key), this); + } + int Count() const + { + return _count; + } + private: + template + void Init(const KeyValuePair & kvPair, Args... args) + { + Add(kvPair); + Init(args...); + } + public: + Dictionary() + { + bucketSizeMinusOne = -1; + shiftBits = 32; + _count = 0; + hashMap = 0; + } + template + Dictionary(Arg arg, Args... args) + { + Init(arg, args...); + } + Dictionary(const Dictionary & other) + : bucketSizeMinusOne(-1), _count(0), hashMap(0) + { + *this = other; + } + Dictionary(Dictionary && other) + : bucketSizeMinusOne(-1), _count(0), hashMap(0) + { + *this = (_Move(other)); + } + Dictionary & operator = (const Dictionary & other) + { + if (this == &other) + return *this; + Free(); + bucketSizeMinusOne = other.bucketSizeMinusOne; + _count = other._count; + shiftBits = other.shiftBits; + hashMap = new KeyValuePair[other.bucketSizeMinusOne + 1]; + marks = other.marks; + for (int i = 0; i <= bucketSizeMinusOne; i++) + hashMap[i] = other.hashMap[i]; + return *this; + } + Dictionary & operator = (Dictionary && other) + { + if (this == &other) + return *this; + Free(); + bucketSizeMinusOne = other.bucketSizeMinusOne; + _count = other._count; + hashMap = other.hashMap; + shiftBits = other.shiftBits; + marks = _Move(other.marks); + other.hashMap = 0; + other._count = 0; + other.bucketSizeMinusOne = -1; + return *this; + } + ~Dictionary() + { + Free(); + } + }; + + template + class EnumerableDictionary + { + friend class Iterator; + friend class ItemProxy; + private: + inline int GetProbeOffset(int /*probeIdx*/) const + { + // quadratic probing + return 1; + } + private: + int bucketSizeMinusOne, shiftBits; + int _count; + IntSet marks; + + // debug op + struct Op + { + TKey key; + int opType; + Op() + {} + Op(const TKey & key, int t) { - if (_count > 0) - { - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) - { - kvPairs.Delete(hashMap[pos.ObjectPosition]); - hashMap[pos.ObjectPosition] = 0; - SetDeleted(pos.ObjectPosition, true); - _count--; - } - } + this->key = key; + opType = t; } - void Clear() + }; + LinkedList> kvPairs; + LinkedNode>** hashMap; + void Free() + { + if (hashMap) + delete[] hashMap; + hashMap = 0; + kvPairs.Clear(); + } + inline bool IsDeleted(int pos) const + { + return marks.Contains((pos << 1) + 1); + } + inline bool IsEmpty(int pos) const + { + return !marks.Contains((pos << 1)); + } + inline void SetDeleted(int pos, bool val) + { + if (val) + marks.Add((pos << 1) + 1); + else + marks.Remove((pos << 1) + 1); + } + inline void SetEmpty(int pos, bool val) + { + if (val) + marks.Remove((pos << 1)); + else + marks.Add((pos << 1)); + } + struct FindPositionResult + { + int ObjectPosition; + int InsertionPosition; + FindPositionResult() { - _count = 0; - kvPairs.Clear(); - marks.Clear(); + ObjectPosition = -1; + InsertionPosition = -1; } - template - bool ContainsKey(const T & key) const + FindPositionResult(int objPos, int insertPos) { - if (bucketSizeMinusOne == -1) - return false; - auto pos = FindPosition(key); - return pos.ObjectPosition != -1; + ObjectPosition = objPos; + InsertionPosition = insertPos; } - template - TValue * TryGetValue(const T & key) const + + }; + template + inline int GetHashPos(T & key) const + { + return ((unsigned int)(GetHashCode(key) * 2654435761)) >> shiftBits; + } + template + FindPositionResult FindPosition(const T & key) const + { + int hashPos = GetHashPos((T&)key); + int insertPos = -1; + int numProbes = 0; + while (numProbes <= bucketSizeMinusOne) { - if (bucketSizeMinusOne == -1) - return nullptr; - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) + if (IsEmpty(hashPos)) { - return &(hashMap[pos.ObjectPosition]->Value.Value); + if (insertPos == -1) + return FindPositionResult(-1, hashPos); + else + return FindPositionResult(-1, insertPos); } - return nullptr; - } - template - bool TryGetValue(const T & key, TValue & value) const - { - if (bucketSizeMinusOne == -1) - return false; - auto pos = FindPosition(key); - if (pos.ObjectPosition != -1) + else if (IsDeleted(hashPos)) { - value = hashMap[pos.ObjectPosition]->Value.Value; - return true; + if (insertPos == -1) + insertPos = hashPos; } - return false; - } - class ItemProxy - { - private: - const EnumerableDictionary * dict; - TKey key; - public: - ItemProxy(const TKey & _key, const EnumerableDictionary * _dict) + else if (hashMap[hashPos]->Value.Key == key) { - this->dict = _dict; - this->key = _key; + return FindPositionResult(hashPos, -1); } - ItemProxy(TKey && _key, const EnumerableDictionary * _dict) + numProbes++; + hashPos = (hashPos + GetProbeOffset(numProbes)) & bucketSizeMinusOne; + } + if (insertPos != -1) + return FindPositionResult(-1, insertPos); + throw InvalidOperationException("Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode."); + } + TValue & _Insert(KeyValuePair && kvPair, int pos) + { + auto node = kvPairs.AddLast(); + node->Value = _Move(kvPair); + hashMap[pos] = node; + SetEmpty(pos, false); + SetDeleted(pos, false); + return node->Value.Value; + } + void Rehash() + { + if (bucketSizeMinusOne == -1 || _count / (float)bucketSizeMinusOne >= MaxLoadFactor) + { + int newSize = (bucketSizeMinusOne + 1) * 2; + int newShiftBits = shiftBits - 1; + if (newSize == 0) { - this->dict = _dict; - this->key = _Move(_key); + newSize = 16; + newShiftBits = 28; } - TValue & GetValue() const + EnumerableDictionary newDict; + newDict.shiftBits = newShiftBits; + newDict.bucketSizeMinusOne = newSize - 1; + newDict.hashMap = new LinkedNode>*[newSize]; + newDict.marks.SetMax(newSize * 2); + if (hashMap) { - auto pos = dict->FindPosition(key); - if (pos.ObjectPosition != -1) + for (auto & kvPair : *this) { - return dict->hashMap[pos.ObjectPosition]->Value.Value; + newDict.Add(_Move(kvPair)); } - else - { - throw KeyNotFoundException("The key does not exists in dictionary."); - } - } - inline TValue & operator()() const - { - return GetValue(); - } - operator TValue&() const - { - return GetValue(); - } - TValue & operator = (const TValue & val) - { - return ((EnumerableDictionary*)dict)->Set(KeyValuePair(_Move(key), val)); - } - TValue & operator = (TValue && val) - { - return ((EnumerableDictionary*)dict)->Set(KeyValuePair(_Move(key), _Move(val))); } - }; - ItemProxy operator [](const TKey & key) const + *this = _Move(newDict); + } + } + + bool AddIfNotExists(KeyValuePair && kvPair) + { + Rehash(); + auto pos = FindPosition(kvPair.Key); + if (pos.ObjectPosition != -1) + return false; + else if (pos.InsertionPosition != -1) { - return ItemProxy(key, this); + _count++; + _Insert(_Move(kvPair), pos.InsertionPosition); + return true; } - ItemProxy operator [](TKey && key) const + else + throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); + } + void Add(KeyValuePair && kvPair) + { + if (!AddIfNotExists(_Move(kvPair))) + throw KeyExistsException("The key already exists in Dictionary."); + } + TValue & Set(KeyValuePair && kvPair) + { + Rehash(); + auto pos = FindPosition(kvPair.Key); + if (pos.ObjectPosition != -1) { - return ItemProxy(_Move(key), this); + hashMap[pos.ObjectPosition]->Delete(); + return _Insert(_Move(kvPair), pos.ObjectPosition); } - int Count() const + else if (pos.InsertionPosition != -1) { - return _count; + _count++; + return _Insert(_Move(kvPair), pos.InsertionPosition); } - KeyValuePair & First() const + else + throw InvalidOperationException("Inconsistent find result returned. This is a bug in Dictionary implementation."); + } + public: + typedef typename LinkedList>::Iterator Iterator; + + typename LinkedList>::Iterator begin() const + { + return kvPairs.begin(); + } + typename LinkedList>::Iterator end() const + { + return kvPairs.end(); + } + public: + void Add(const TKey & key, const TValue & value) + { + Add(KeyValuePair(key, value)); + } + void Add(TKey && key, TValue && value) + { + Add(KeyValuePair(_Move(key), _Move(value))); + } + bool AddIfNotExists(const TKey & key, const TValue & value) + { + return AddIfNotExists(KeyValuePair(key, value)); + } + bool AddIfNotExists(TKey && key, TValue && value) + { + return AddIfNotExists(KeyValuePair(_Move(key), _Move(value))); + } + void Remove(const TKey & key) + { + if (_count > 0) { - return kvPairs.First(); + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) + { + kvPairs.Delete(hashMap[pos.ObjectPosition]); + hashMap[pos.ObjectPosition] = 0; + SetDeleted(pos.ObjectPosition, true); + _count--; + } } - KeyValuePair & Last() const + } + void Clear() + { + _count = 0; + kvPairs.Clear(); + marks.Clear(); + } + template + bool ContainsKey(const T & key) const + { + if (bucketSizeMinusOne == -1) + return false; + auto pos = FindPosition(key); + return pos.ObjectPosition != -1; + } + template + TValue * TryGetValue(const T & key) const + { + if (bucketSizeMinusOne == -1) + return nullptr; + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) { - return kvPairs.Last(); + return &(hashMap[pos.ObjectPosition]->Value.Value); } - private: - template - void Init(const KeyValuePair & kvPair, Args... args) + return nullptr; + } + template + bool TryGetValue(const T & key, TValue & value) const + { + if (bucketSizeMinusOne == -1) + return false; + auto pos = FindPosition(key); + if (pos.ObjectPosition != -1) { - Add(kvPair); - Init(args...); + value = hashMap[pos.ObjectPosition]->Value.Value; + return true; } + return false; + } + class ItemProxy + { + private: + const EnumerableDictionary * dict; + TKey key; public: - EnumerableDictionary() + ItemProxy(const TKey & _key, const EnumerableDictionary * _dict) { - bucketSizeMinusOne = -1; - shiftBits = 32; - _count = 0; - hashMap = 0; + this->dict = _dict; + this->key = _key; } - template - EnumerableDictionary(Arg arg, Args... args) + ItemProxy(TKey && _key, const EnumerableDictionary * _dict) { - Init(arg, args...); + this->dict = _dict; + this->key = _Move(_key); } - EnumerableDictionary(const EnumerableDictionary & other) - : bucketSizeMinusOne(-1), _count(0), hashMap(0) + TValue & GetValue() const { - *this = other; + auto pos = dict->FindPosition(key); + if (pos.ObjectPosition != -1) + { + return dict->hashMap[pos.ObjectPosition]->Value.Value; + } + else + { + throw KeyNotFoundException("The key does not exists in dictionary."); + } } - EnumerableDictionary(EnumerableDictionary && other) - : bucketSizeMinusOne(-1), _count(0), hashMap(0) + inline TValue & operator()() const { - *this = (_Move(other)); + return GetValue(); } - EnumerableDictionary & operator = (const EnumerableDictionary & other) + operator TValue&() const { - if (this == &other) - return *this; - Clear(); - for (auto & item : other) - Add(item.Key, item.Value); - return *this; + return GetValue(); } - EnumerableDictionary & operator = (EnumerableDictionary && other) + TValue & operator = (const TValue & val) { - if (this == &other) - return *this; - Free(); - bucketSizeMinusOne = other.bucketSizeMinusOne; - _count = other._count; - hashMap = other.hashMap; - shiftBits = other.shiftBits; - marks = _Move(other.marks); - other.hashMap = 0; - other._count = 0; - other.bucketSizeMinusOne = -1; - kvPairs = _Move(other.kvPairs); - return *this; + return ((EnumerableDictionary*)dict)->Set(KeyValuePair(_Move(key), val)); } - ~EnumerableDictionary() + TValue & operator = (TValue && val) { - Free(); + return ((EnumerableDictionary*)dict)->Set(KeyValuePair(_Move(key), _Move(val))); } }; + ItemProxy operator [](const TKey & key) const + { + return ItemProxy(key, this); + } + ItemProxy operator [](TKey && key) const + { + return ItemProxy(_Move(key), this); + } + int Count() const + { + return _count; + } + KeyValuePair & First() const + { + return kvPairs.First(); + } + KeyValuePair & Last() const + { + return kvPairs.Last(); + } + private: + template + void Init(const KeyValuePair & kvPair, Args... args) + { + Add(kvPair); + Init(args...); + } + public: + EnumerableDictionary() + { + bucketSizeMinusOne = -1; + shiftBits = 32; + _count = 0; + hashMap = 0; + } + template + EnumerableDictionary(Arg arg, Args... args) + { + Init(arg, args...); + } + EnumerableDictionary(const EnumerableDictionary & other) + : bucketSizeMinusOne(-1), _count(0), hashMap(0) + { + *this = other; + } + EnumerableDictionary(EnumerableDictionary && other) + : bucketSizeMinusOne(-1), _count(0), hashMap(0) + { + *this = (_Move(other)); + } + EnumerableDictionary & operator = (const EnumerableDictionary & other) + { + if (this == &other) + return *this; + Clear(); + for (auto & item : other) + Add(item.Key, item.Value); + return *this; + } + EnumerableDictionary & operator = (EnumerableDictionary && other) + { + if (this == &other) + return *this; + Free(); + bucketSizeMinusOne = other.bucketSizeMinusOne; + _count = other._count; + hashMap = other.hashMap; + shiftBits = other.shiftBits; + marks = _Move(other.marks); + other.hashMap = 0; + other._count = 0; + other.bucketSizeMinusOne = -1; + kvPairs = _Move(other.kvPairs); + return *this; + } + ~EnumerableDictionary() + { + Free(); + } + }; - class _DummyClass - {}; + class _DummyClass + {}; - template - class HashSetBase + template + class HashSetBase + { + protected: + DictionaryType dict; + private: + template + void Init(const T & v, Args... args) + { + Add(v); + Init(args...); + } + public: + HashSetBase() + {} + template + HashSetBase(Arg arg, Args... args) + { + Init(arg, args...); + } + HashSetBase(const HashSetBase & set) + { + operator=(set); + } + HashSetBase(HashSetBase && set) + { + operator=(_Move(set)); + } + HashSetBase & operator = (const HashSetBase & set) + { + dict = set.dict; + return *this; + } + HashSetBase & operator = (HashSetBase && set) + { + dict = _Move(set.dict); + return *this; + } + public: + class Iterator { - protected: - DictionaryType dict; private: - template - void Init(const T & v, Args... args) - { - Add(v); - Init(args...); - } + typename DictionaryType::Iterator iter; public: - HashSetBase() - {} - template - HashSetBase(Arg arg, Args... args) - { - Init(arg, args...); - } - HashSetBase(const HashSetBase & set) + Iterator() = default; + T & operator *() const { - operator=(set); + return (*iter).Key; } - HashSetBase(HashSetBase && set) + T * operator ->() const { - operator=(_Move(set)); + return &(*iter).Key; } - HashSetBase & operator = (const HashSetBase & set) + Iterator & operator ++() { - dict = set.dict; + ++iter; return *this; } - HashSetBase & operator = (HashSetBase && set) - { - dict = _Move(set.dict); - return *this; - } - public: - class Iterator - { - private: - typename DictionaryType::Iterator iter; - public: - Iterator() = default; - T & operator *() const - { - return (*iter).Key; - } - T * operator ->() const - { - return &(*iter).Key; - } - Iterator & operator ++() - { - ++iter; - return *this; - } - Iterator operator ++(int) - { - Iterator rs = *this; - operator++(); - return rs; - } - bool operator != (const Iterator & _that) const - { - return iter != _that.iter; - } - bool operator == (const Iterator & _that) const - { - return iter == _that.iter; - } - Iterator(const typename DictionaryType::Iterator & _iter) - { - this->iter = _iter; - } - }; - Iterator begin() const - { - return Iterator(dict.begin()); - } - Iterator end() const - { - return Iterator(dict.end()); - } - public: - int Count() const - { - return dict.Count(); - } - void Clear() - { - dict.Clear(); - } - bool Add(const T& obj) + Iterator operator ++(int) { - return dict.AddIfNotExists(obj, _DummyClass()); + Iterator rs = *this; + operator++(); + return rs; } - bool Add(T && obj) + bool operator != (const Iterator & _that) const { - return dict.AddIfNotExists(_Move(obj), _DummyClass()); + return iter != _that.iter; } - void Remove(const T & obj) + bool operator == (const Iterator & _that) const { - dict.Remove(obj); + return iter == _that.iter; } - bool Contains(const T & obj) const + Iterator(const typename DictionaryType::Iterator & _iter) { - return dict.ContainsKey(obj); + this->iter = _iter; } }; - template - class HashSet : public HashSetBase> - {}; + Iterator begin() const + { + return Iterator(dict.begin()); + } + Iterator end() const + { + return Iterator(dict.end()); + } + public: + int Count() const + { + return dict.Count(); + } + void Clear() + { + dict.Clear(); + } + bool Add(const T& obj) + { + return dict.AddIfNotExists(obj, _DummyClass()); + } + bool Add(T && obj) + { + return dict.AddIfNotExists(_Move(obj), _DummyClass()); + } + void Remove(const T & obj) + { + dict.Remove(obj); + } + bool Contains(const T & obj) const + { + return dict.ContainsKey(obj); + } + }; + template + class HashSet : public HashSetBase> + {}; - template - class EnumerableHashSet : public HashSetBase> + template + class EnumerableHashSet : public HashSetBase> + { + public: + T & First() const { - public: - T & First() const - { - return this->dict.First().Key; - } - T & Last() const - { - return this->dict.Last().Key; - } - }; - } + return this->dict.First().Key; + } + T & Last() const + { + return this->dict.Last().Key; + } + }; } #endif -- cgit v1.2.3