/// <summary> /// Tries to get the element with the given key. /// </summary> public bool TryGetValue(TKey key, out TValue value) { var hash = CalculateHash(key, (int)_hashedPointers.Length); var pointer = _hashedPointers[hash]; if (pointer == 0) { // ok, there is no data here. value = default(TValue); return(false); } else { // ok, search for the key. var keyHash = this.CalculateFullHash(key); var count = _keyValueList[pointer]; for (var p = pointer + 1; p < pointer + (count * ENTRY_SIZE) + 1; p += ENTRY_SIZE) { if (_keyValueList[p + 1] == keyHash) { // only check keys if also their full hashes match. var existingKey = _keys.Get(_keyValueList[p + 0]); if (_keysEqual(existingKey, key)) { // key found! value = _values.Get(_keyValueList[p + 2]); return(true); } } } value = default(TValue); return(false); } }
/// <summary> /// Adds an element with the provided key and value /// </summary> public void Add(TKey key, TValue value) { var hash = CalculateHash(key, (int)_hashedPointers.Length); var pointer = _hashedPointers[hash]; if (pointer == 0) { // ok, there is no data yet here. _hashedPointers[hash] = (uint)_keyValueList.Count; _keyValueList.Add(1); _keyValueList.Add((uint)_keys.Add(key)); _keyValueList.Add(this.CalculateFullHash(key)); _keyValueList.Add((uint)_values.Add(value)); _keyValueList.AddDontCare((_minimumKeyCount - 1) * 3); } else { // ok, add at the end of the linked-list. var keyHash = this.CalculateFullHash(key); var count = _keyValueList[(int)pointer]; if (count > (_minimumKeyCount / 2) && (count & (count - 1)) == 0) { // a power of two, copy to the end and check duplicate keys. _hashedPointers[hash] = (uint)_keyValueList.Count; _keyValueList.Add(count + 1); for (var p = pointer + 1; p < pointer + (count * ENTRY_SIZE) + 1; p += ENTRY_SIZE) { if (_verifyUniqueKeys) { if (_keyValueList[p + 1] == keyHash) { // only check if the key full hashes match. var existingKey = _keys.Get(_keyValueList[p + 0]); if (_keysEqual(existingKey, key)) { throw new ArgumentException("Key already exists."); } } } _keyValueList.Add(_keyValueList[p]); _keyValueList.Add(_keyValueList[p + 1]); _keyValueList.Add(_keyValueList[p + 2]); } _keyValueList.Add((uint)_keys.Add(key)); _keyValueList.Add(this.CalculateFullHash(key)); _keyValueList.Add((uint)_values.Add(value)); _keyValueList.AddDontCare((int)(count - 1) * 3); } else { if (_verifyUniqueKeys) { for (var p = pointer + 1; p < pointer + (count * ENTRY_SIZE) + 1; p += ENTRY_SIZE) { if (_keyValueList[p + 1] == keyHash) { // only check if the key full hashes match. var existingKey = _keys.Get(_keyValueList[p + 0]); if (_keysEqual(existingKey, key)) { throw new ArgumentException("Key already exists."); } } } } _keyValueList[pointer] = _keyValueList[pointer] + 1; _keyValueList[pointer + 1 + (count * ENTRY_SIZE) + 0] = (uint)_keys.Add(key); _keyValueList[pointer + 1 + (count * ENTRY_SIZE) + 1] = this.CalculateFullHash(key); _keyValueList[pointer + 1 + (count * ENTRY_SIZE) + 2] = (uint)_values.Add(value); } } _count++; }