예제 #1
0
        private SkipListNode <TKey, TValue>[] FindRightMostNodes(TKey key)
        {
            var rightNodes = new SkipListNode <TKey, TValue> [_maxLevelToUse];

            // Start at the top list header node
            var currentNode = _headNodes[_currentLevel];

            for (var i = _currentLevel; i >= 0; i--)
            {
                while ((currentNode.Right != _tail) && (_comparerToUse.Compare(currentNode.Right.Key, key) < 0))
                {
                    currentNode = currentNode.Right;
                }

                // Store this node - the new node will be to the right of it.
                rightNodes[i] = currentNode;

                // Check if there is a next level, and if there is move down.
                if (i > 0)
                {
                    currentNode = currentNode.Down;
                }
            }
            return(rightNodes);
        }
예제 #2
0
        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        /// <returns>An enumerator for enumerating though the collection.</returns>
        public IEnumerator <KeyValuePair <TKey, TValue> > GetEnumerator()
        {
            // Start at the bottom level and add all the keys to the return array.
            SkipListNode <TKey, TValue> startNode = _headNodes[0];

            while (startNode.Right != _tail)
            {
                startNode = startNode.Right;
                yield return(new KeyValuePair <TKey, TValue>(startNode.Key, startNode.Value));
            }
        }
예제 #3
0
        /// <summary>
        /// Adds the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void Add(TKey key, TValue value)
        {
            var rightNodes = FindRightMostNodes(key);

            // Check if the item allready exists in the list.  If it does, throw an exception -
            // we will not allow duplicate items here.
            if ((rightNodes[0].Right != _tail) && (_comparerToUse.Compare(rightNodes[0].Right.Key, key) == 0))
            {
                throw new ArgumentException(Resources.ItemAlreadyInList);
            }
            var newLevel = PickRandomLevel();

            if (newLevel > _currentLevel)
            {
                for (var i = _currentLevel + 1; i <= newLevel; i++)
                {
                    rightNodes[i] = _headNodes[i];
                }

                _currentLevel = newLevel;
            }

            var newNode = new SkipListNode <TKey, TValue>(key, value)
            {
                Right = rightNodes[0].Right
            };

            // Insert the item in the first level
            rightNodes[0].Right = newNode;

            // And now insert the node in the rest of the levels, making sure
            // to update the the links
            for (var i = 1; i <= _currentLevel; i++)
            {
                var previousNode = newNode;
                newNode = new SkipListNode <TKey, TValue>(key, value)
                {
                    Right = rightNodes[i].Right
                };

                rightNodes[i].Right = newNode;

                newNode.Down = previousNode;
            }

            _itemsCount++;
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SkipList&lt;TKey, TValue&gt;"/> class.
        /// </summary>
        /// <param name="maxLevel">The max level.</param>
        /// <param name="probability">The probability.</param>
        /// <param name="comparer">The comparer.</param>
        public SkipList(int maxLevel, double probability, IComparer <TKey> comparer)
        {
            if (maxLevel < 1)
            {
                throw new ArgumentOutOfRangeException("maxLevel", maxLevel, Resources.MaximumLevelBiggerThan0);
            }

            if (comparer == null)
            {
                throw new ArgumentNullException("comparer");
            }

            if ((probability > 0.9) || (probability < 0.1))
            {
                throw new ArgumentOutOfRangeException("probability", probability, Resources.InvalidProbability);
            }

            _comparerToUse    = comparer;
            _maxLevelToUse    = maxLevel;
            _probabilityToUse = probability;

            // Initialise the skip list to empty nodes, and link the heads and the tails
            _headNodes = new SkipListNode <TKey, TValue> [maxLevel];

            _headNodes[0] = new SkipListNode <TKey, TValue>
            {
                Right = _tail
            };

            for (var i = 1; i < maxLevel; i++)
            {
                _headNodes[i] = new SkipListNode <TKey, TValue>
                {
                    Down = _headNodes[i - 1], Right = _tail
                };
                //headNodes[i - 1].Up = headNodes[i];
            }
        }