Beispiel #1
0
        /// <summary>
        /// Removes the data at the specified key location.
        /// </summary>
        /// <param name="key">The key.</param>
        public void Remove(TKey key)
        {
            try
            {
                writeLock.Enter();


                HashtableNode <TKey, TData>[] table = array;
                var initialHash = Math.Abs(GetHashCode_HashTable <TKey> .GetHashCode(key)) % table.Length;
                var hash        = initialHash;

                do
                {
                    HashtableNode <TKey, TData> n = table[hash];
                    if (n.Token == HashtableToken.Empty)
                    {
                        return;
                    }
                    if (n.Token == HashtableToken.Deleted || !KeyComparer.Equals(key, n.Key))
                    {
                        hash = (hash + 1) % table.Length;
                    }
                    else
                    {
                        table[hash] = DeletedNode;
                    }
                } while (hash != initialHash);      // MartinG@DigitalRune: Stop when all entries are checked!
            }
            finally
            {
                writeLock.Exit();
            }
        }
Beispiel #2
0
        private bool Find(TKey key, out HashtableNode <TKey, TData> node)
        {
            node = new HashtableNode <TKey, TData>();
            var table       = array;
            var initialHash = Math.Abs(GetHashCode_HashTable <TKey> .GetHashCode(key)) % table.Length;
            var hash        = initialHash;

            do
            {
                HashtableNode <TKey, TData> n = table[hash];
                if (n.Token == HashtableToken.Empty)
                {
                    return(false);
                }
                if (n.Token == HashtableToken.Deleted || !KeyComparer.Equals(key, n.Key))
                {
                    hash = (hash + 1) % table.Length;
                }
                else
                {
                    node = n;
                    return(true);
                }
            } while (hash != initialHash);

            return(false);
        }
Beispiel #3
0
        private bool Insert(HashtableNode <TKey, TData>[] table, TKey key, TData data)
        {
            var  initialHash = Math.Abs(GetHashCode_HashTable <TKey> .GetHashCode(key)) % table.Length;
            var  hash        = initialHash;
            bool inserted    = false;

            do
            {
                var node = table[hash];
                // if node is empty, or marked with a tombstone
                if (node.Token == HashtableToken.Empty || node.Token == HashtableToken.Deleted || KeyComparer.Equals(key, node.Key))
                {
                    table[hash] = new HashtableNode <TKey, TData>()
                    {
                        Key   = key,
                        Data  = data,
                        Token = HashtableToken.Used
                    };
                    inserted = true;
                    break;
                }
                else
                {
                    hash = (hash + 1) % table.Length;
                }
            } while (hash != initialHash);

            return(inserted);
        }
Beispiel #4
0
        /// <summary>
        /// Sets the value of the item at the specified key location.
        /// This is only guaranteed to work correctly if no other thread is modifying the same key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The new value.</param>
        public void UnsafeSet(TKey key, TData value)
        {
            HashtableNode <TKey, TData>[] table;
            bool inserted = false;

            do
            {
                table = array;
                var initialHash = Math.Abs(GetHashCode_HashTable <TKey> .GetHashCode(key)) % table.Length;
                var hash        = initialHash;

                do
                {
                    var node = table[hash];
                    if (KeyComparer.Equals(key, node.Key))
                    {
                        table[hash] = new HashtableNode <TKey, TData>()
                        {
                            Key   = key,
                            Data  = value,
                            Token = HashtableToken.Used
                        };
                        inserted = true;
                        break;
                    }
                    else
                    {
                        hash = (hash + 1) % table.Length;
                    }
                } while (hash != initialHash);
            } while (table != array);

            // MartinG@DigitalRune: I have moved the Add() outside the loop because it uses a
            // write-lock and the loop above should run without locks.
            if (!inserted)
            {
                Add(key, value);
            }
        }