예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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++;
        }