示例#1
0
        private SkipListNode <TKey, TValue>[] FindRightMostNodes(TKey key)
        {
            SkipListNode <TKey, TValue>[] rightNodes = new SkipListNode <TKey, TValue> [maxLevelToUse];

            // Start at the top list header node
            SkipListNode <TKey, TValue> currentNode = headNodes[currentLevel];

            for (int 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>
        /// 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>();
            headNodes[0].Right = tail;

            for (int i = 1; i < maxLevel; i++)
            {
                headNodes[i]      = new SkipListNode <TKey, TValue>();
                headNodes[i].Down = headNodes[i - 1];
                //headNodes[i - 1].Up = headNodes[i];
                headNodes[i].Right = tail;
            }
        }
示例#3
0
        /// <summary>
        /// Gets or sets the value in the node with the specified key.
        /// </summary>
        /// <value></value>
        public TValue this[TKey key] {
            get
            {
                SkipListNode <TKey, TValue> node = Find(key);

                if (node == null)
                {
                    throw new ArgumentOutOfRangeException(Resources.KeyDoesNotExist);
                }
                else
                {
                    return(node.Value);
                }
            }
            set
            {
                SkipListNode <TKey, TValue> node = Find(key);

                if (node == null)
                {
                    throw new ArgumentOutOfRangeException(Resources.KeyDoesNotExist);
                }
                else
                {
                    node.Value = value;
                }
            }
        }
示例#4
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));
            }
        }
示例#5
0
        /// <summary>
        /// Tries to get the value with the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>A value indiciating whether the node with the specified key was found in the tree.</returns>
        public bool TryGetValue(TKey key, out TValue value)
        {
            SkipListNode <TKey, TValue> node = Find(key);

            if (node == null)
            {
                value = default(TValue);
                return(false);
            }
            else
            {
                value = node.Value;
                return(true);
            }
        }
示例#6
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)
        {
            SkipListNode <TKey, TValue>[] 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);
            }
            else
            {
                int newLevel = PickRandomLevel();

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

                    currentLevel = newLevel;
                }

                SkipListNode <TKey, TValue> previousNode = null;
                SkipListNode <TKey, TValue> newNode      = new SkipListNode <TKey, TValue>(key, value);;

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

                // And now insert the node in the rest of the levels, making sure
                // to update the the links
                for (int i = 1; i <= currentLevel; i++)
                {
                    previousNode = newNode;
                    newNode      = new SkipListNode <TKey, TValue>(key, value);

                    newNode.Right       = rightNodes[i].Right;
                    rightNodes[i].Right = newNode;

                    newNode.Down = previousNode;
                }
            }

            itemsCount++;
        }
示例#7
0
        /// <summary>
        /// Determines whether [contains] [the specified item].
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>
        ///     <c>true</c> if [contains] [the specified item]; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(KeyValuePair <TKey, TValue> item)
        {
            SkipListNode <TKey, TValue> node = Find(item.Key);

            if (node == null)
            {
                return(false);
            }
            else
            {
                if (node.Value.Equals(item.Value))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
示例#8
0
        private SkipListNode <TKey, TValue> Find(TKey key)
        {
            if (this.Count == 0)
            {
                return(null);
            }
            else
            {
                // Start at the top list header node
                SkipListNode <TKey, TValue> currentNode = headNodes[currentLevel];

                while (true)
                {
                    while ((currentNode.Right != tail) && (comparerToUse.Compare(currentNode.Right.Key, key) < 0))
                    {
                        currentNode = currentNode.Right;
                    }

                    // Check if there is a next level, and if there is move down.
                    if (currentNode.Down == null)
                    {
                        break;
                    }
                    else
                    {
                        currentNode = currentNode.Down;
                    }
                }

                // Do one final comparison to see if the key to the right equals this key.
                // If it doesn't match, it would be bigger than this key.
                if (comparerToUse.Compare(currentNode.Right.Key, key) == 0)
                {
                    return(currentNode.Right);
                }
                else
                {
                    return(null);
                }
            }
        }
示例#9
0
        /// <summary>
        /// Accepts the specified visitor.
        /// </summary>
        /// <param name="visitor">The visitor.</param>
        public void Accept(IVisitor <KeyValuePair <TKey, TValue> > visitor)
        {
            if (visitor == null)
            {
                throw new ArgumentNullException("visitor");
            }

            // Start at the bottom level and add all the keys to the return array.
            SkipListNode <TKey, TValue> startNode = headNodes[0];

            for (int i = 0; i < this.Count; i++)
            {
                startNode = startNode.Right;
                visitor.Visit(new KeyValuePair <TKey, TValue>(startNode.Key, startNode.Value));

                if (visitor.HasCompleted)
                {
                    break;
                }
            }
        }