Ejemplo n.º 1
0
        private SkipListNode <TKey, TValue>[] FindRightMostNodes(TKey key)
        {
            var rightNodes = new SkipListNode <TKey, TValue> [maximumLevelToUse];

            // Start at the top list header node
            var currentNode = headNodes[CurrentListLevel];

            for (var i = CurrentListLevel; 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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds the item to the collection.
        /// </summary>
        /// <param name="key">The key of the item.</param>
        /// <param name="value">The value to add to the colleciton.</param>
        /// <remarks>
        ///     <b>Notes to Inheritors: </b>
        /// Derived classes can override this method to change the behavior of the <see cref="Add(TKey,TValue)"/> method.
        /// </remarks>
        protected virtual void AddItem(TKey key, TValue value)
        {
            var rightNodes = FindRightMostNodes(key);

            // Check if the item already 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("The item is already in the list.", "key");
            }

            var newLevel = PickRandomLevel();

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

                CurrentListLevel = 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 <= CurrentListLevel; i++)
            {
                var previousNode = newNode;
                newNode = new SkipListNode <TKey, TValue>(key, value)
                {
                    Right = rightNodes[i].Right
                };

                rightNodes[i].Right = newNode;

                newNode.Down = previousNode;
            }
            Count++;
        }
Ejemplo n.º 3
0
        /// <param name="maximumLevel">The maximum level.</param>
        /// <param name="probability">The probability.</param>
        /// <param name="comparer">The comparer.</param>
        /// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="maximumLevel"/> is less than 1.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="probability"/> is less than 0.1.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="probability"/> is greater than 0.9.</exception>
        public SkipList(int maximumLevel, double probability, IComparer <TKey> comparer)
        {
            #region Validation

            if (maximumLevel < 1)
            {
                throw new ArgumentOutOfRangeException("maximumLevel", "The maximum level must be bigger than 0.");
            }

            Guard.ArgumentNotNull(comparer, "comparer");

            if ((probability > 0.9) || (probability < 0.1))
            {
                throw new ArgumentOutOfRangeException("probability", "The probability must be between 0.1 and 0.9");
            }

            #endregion

            comparerToUse     = comparer;
            maximumLevelToUse = maximumLevel;
            probabilityToUse  = probability;

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

            headNodes[0] = new SkipListNode <TKey, TValue> {
                Right = tail
            };

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