private static SkipListNode InsertNewNode(TKey key, TValue value, SkipListNode nodeBefore, SkipListNode belowForNewNode) { var newNode = InsertNewNode(key, value, nodeBefore); newNode.Below = belowForNewNode; return(newNode); }
public bool Contains(T item) { SkipListNode <T> cur = _head; for (int i = _levels - 1; i >= 0; i--) { while (cur.Next[i] != null) { int cmp = cur.Next[i].Value.CompareTo(item); if (cmp > 0) { // the value is too large, so go down one level // and take smaller steps. break; } if (cmp == 0) { // found return(true); } cur = cur.Next[i]; } } return(false); }
private SkipListNode AddRecursive(TKey key, TValue value, SkipListNode currentNode) { bool isEqual; var closestNodeAtThisLevel = SearchForwardLessThanEqual(key, currentNode, out isEqual); if (isEqual) { throw new InvalidOperationException(string.Format("Key {0} already in collection", key)); } if (closestNodeAtThisLevel.Below != null) { var newNodeBelow = AddRecursive(key, value, closestNodeAtThisLevel.Below); if (newNodeBelow != null && ShouldPromoteToNextLevel()) { return(InsertNewNode(key, value, closestNodeAtThisLevel, newNodeBelow)); } } else { return(InsertNewNode(key, value, closestNodeAtThisLevel)); } return(null); }
public bool MoveNext() { Debug.Assert(m_node != null); m_node = m_node[0]; return(m_node != null); }
/// <summary> /// Remove an entry in the map matching the specified key. /// </summary> /// <param name="key">The IComparable key to search for. If found the /// matching entry is removed from the map.</param> /// <returns>a bool indicating whether the specified key was found in /// the map and the entry removed</returns> public bool Remove(TKey key) { bool found = Search(key, out var position); if (!found) { return(false); } else { var old = position; do { old.Back.Forward = old.Forward; if (old.Forward != null) { old.Forward.Back = old.Back; } old = old.Up; } while (old != null); count--; // Clean up rows with only a head remaining. while (head.Forward == null) { head = head.Down; } return(true); } }
/// <summary> /// This is an alternative (to indexing) interface to add and modify /// existing values in the map. /// </summary> /// <param name="key">The IComparable key</param> /// <param name="value">The new value</param> public void Add(TKey key, TValue value) { // Duh, we have to be able to tell when no key is found from when one is found // and if none is found have a reference to the last place searched.... return // a bool and use an out value? bool found = Search(key, out var position); if (found) { position.Value = value; } else { // In this scenario position, rather than the value we searched // for is the value immediately previous to where it should be inserted. var newEntry = new SkipListNode <TKey, TValue>((TKey)key, value); count++; newEntry.Back = position; if (position.Forward != null) { newEntry.Forward = position.Forward; } position.Forward = newEntry; Promote(newEntry); } }
/// <summary> /// Removes all the empty levels leftover in the Skip List /// </summary> protected void clearEmptyLevels() { if (this.levels > 1) //more than one level, don't want to remove bottom level { SkipListNode <T> currentNode = this.topLeft; while (currentNode != this.bottomLeft) //do not remove the bottom level { if (currentNode.IsHeader() && currentNode.Next.IsFooter()) { SkipListNode <T> belowNode = currentNode.Below; //Remove the empty level //Update pointers topLeft = currentNode.Below; //Remove links currentNode.Next.Dispose(); currentNode.Dispose(); //Update counters this.levels--; currentNode = belowNode; //scan down } else { break; //a single non-emtpy level means the rest of the levels are not empty } } } }
private void Init2LevelsThreeNodesForTests() { SkipListNode <int> third = new SkipListNode <int>(1, 100); SkipListNode <int> second = new SkipListNode <int>(2, 75) { Next = new SkipListNode <int>[] { third, null, } }; SkipListNode <int> first = new SkipListNode <int>(1, 50) { Next = new SkipListNode <int>[] { second } }; this.TwoLevelsThreeNodes = new SkipList <int>() { Count = 3, Levels = 2, Head = new SkipListNode <int>(2, 0) { Next = new SkipListNode <int>[] { first, second } } }; }
public void Remove(T t) { SkipListNode[] needUpdates = new SkipListNode[this.levelCount]; SkipListNode temp = this.head; // 查找边界点: // A[i] < t,A[i+1]>= t,即找到A[i]之后 // 需要进一步判断就是否为要删除的值 for (int i = this.levelCount - 1; i >= 0; i--) { while (temp != null && temp.GetForward(i) != null && temp.GetForward(i).item.CompareTo(t) < 0) { temp = temp.levels[i].forward; } needUpdates[i] = temp; } // 源链表中的节点,如果该值与要删除的不相等,说明要删除的元素在跳表中不存在 var node = temp.GetForward(0); if (node != null && node.item.CompareTo(t) == 0) { // A->B->C,更新为:A->C,其中B为要删除的结点 for (int i = 0; i < this.levelCount; i++) { SkipListNode forward = needUpdates[i].levels[i].forward; if (forward.item.CompareTo(t) == 0) { needUpdates[i].levels[i].forward = forward.levels != null ? forward.levels[i].forward : null; } } } }
/// <summary> /// Returns the first node whose value matches the input value /// </summary> public virtual SkipListNode <T> Find(T value) { SkipListNode <T> foundNode = this.topLeft; //Look for the highest-level node with an element value matching the parameter value while (foundNode != null && foundNode.Next != null) { if (!foundNode.Next.IsFooter() && foundNode.Next.Value.CompareTo(value) < 0) //next node's value is still smaller { foundNode = foundNode.Next; //keep scanning across } else { if (!foundNode.Next.IsFooter() && foundNode.Next.Value.Equals(value)) //value found { foundNode = foundNode.Next; break; } else { foundNode = foundNode.Below; //element not in this level, scan down } } } return(foundNode); }
/// <summary> /// Remove an entry in the map matching the specified key. /// </summary> /// <param name="key">The IComparable key to search for. If found the /// matching entry is removed from the map.</param> /// <returns>a bool indicating whether the specified key was found in /// the map and the entry removed</returns> public bool Remove(TKey key) { SkipListNode <TKey, TValue> position; bool found = Search(key, out position); if (!found) { return(false); } else { SkipListNode <TKey, TValue> old = position; do { old.back.forward = old.forward; if (old.forward != null) { old.forward.back = old.back; } old = old.up; } while (old != null); count--; // Clean up rows with only a head remaining. while (head.forward == null) { head = head.down; } return(true); } }
public void Add(T item) { int level = PickRandomLevel(); SkipListNode <T> newNode = new SkipListNode <T>(item, level + 1); SkipListNode <T> current = _head; for (int i = _levels - 1; i >= 0; i++) { while (current.Next[i] != null) { if (current.Next[i].Value.CompareTo(item) > 0) { break; } current = current.Next[i]; } if (i <= level) { // Adding "c" to the list: a -> b -> d -> e. //Current is node b and current.Next[i] is d. // 1. Link the new node (c) to the existing node (d): //c.Next = d newNode.Next[i] = current.Next[i]; // Insert c into the list after b // b.Next = c current.Next[i] = newNode; } } _count++; }
private SkipListNode RemoveRecursive(TKey key, SkipListNode currentNode) { var closestNodeAtThisLevel = SearchForwardLessThan(key, currentNode); var nodeToRemove = closestNodeAtThisLevel.Next; if (closestNodeAtThisLevel.Below != null) { var removedNodeBelow = RemoveRecursive(key, closestNodeAtThisLevel.Below); if (removedNodeBelow != null && nodeToRemove != null && nodeToRemove.Below == removedNodeBelow) { RemoveNode(nodeToRemove, closestNodeAtThisLevel); return(nodeToRemove); } } else if (nodeToRemove != null && MatchesKey(key, nodeToRemove)) { RemoveNode(nodeToRemove, closestNodeAtThisLevel); return(nodeToRemove); } return(null); }
internal Enumerator(SkipList <TKey, TValue> list) { _list = list; _version = list._version; _node = list._head.Next; _current = EmptyKeyValuePair; _index = -1; }
public SkipList() { topLeft = getEmptyLevel(); //create an empty level bottomLeft = topLeft; levels = 1; //update the level count size = 0; //no elements added random = new Random(); //used for adding new values }
public void Dispose() { value = default(T); next = null; previous = null; above = null; previous = null; }
public SkipList(IComparer <TKey> comparer) { _head = new SkipListNode(MaxLevel); Initialize(); _version = 0; _comparer = comparer ?? Comparer <TKey> .Default; _valueComparer = EqualityComparer <TValue> .Default; _random = new Random(); }
private static SkipListNode InsertNewNode(TKey key, TValue value, SkipListNode nodeBefore) { SkipListNode newNode = new SkipListNode(key, value); newNode.Next = nodeBefore.Next; nodeBefore.Next = newNode; return(newNode); }
public SkipList() { _currentLevel = 0; _maxLevel = 32; _rand = new Random(); _comparer = Comparer <TKey> .Default; _topLeft = new HeaderSkipListNode(); _bottomLeft = _topLeft; }
public SkipListNode <T> Init(long v, T o, SkipListNode <T> r, SkipListNode <T> d) { Right = r; Down = d; Value = v; Obj = o; return(this); }
public IEnumerator <T> GetEnumerator() { SkipListNode <T> cur = _head.Next[0]; while (cur != null) { yield return(cur.Value); } }
public void Remove(TKey key) { SkipListNode removedNode = RemoveRecursive(key, _topLeft); if (removedNode != null && _topLeft.Next == null && _topLeft.Below != null) { _topLeft = _topLeft.Below; } }
public void Add(TK key, TV value){ SkipListNode<TK, TV> position; bool found = search(key, out position); if(found) position.value = value; else{ SkipListNode<TK, TV> newEntry = new SkipListNode<TK, TV>(key, value); count++;
public void Insert_IntoEmpty() { SkipListNode <int> node = new SkipListNode <int>(1, 50); this.Empty.Insert(node); Assert.AreEqual <int>(50, this.Empty.Head.Next[0].Value); Assert.AreEqual <int>(1, this.Empty.Levels); Assert.AreEqual <int>(1, this.Empty.Count); }
public void Reset() { if (_version != _list._version) { throw new InvalidOperationException(); } _current = EmptyKeyValuePair; _node = _list._head.Next; _index = -1; }
public TValue Get(TKey key) { SkipListNode <TKey, TValue> position = search(key); if (position == null || position.isFront) { throw new KeyNotFoundException("Unable to find entry"); } return(position.value); }
public void Insert_1LevelOneNode_AtEnd() { SkipListNode <int> node = new SkipListNode <int>(1, 75); this.OneLevelOneNode.Insert(node); Assert.AreEqual <int>(50, this.OneLevelOneNode.Head.Next[0].Value); Assert.AreEqual <int>(75, this.OneLevelOneNode.Head.Next[0].Next[0].Value); Assert.AreEqual <int>(1, this.OneLevelOneNode.Levels); Assert.AreEqual <int>(2, this.OneLevelOneNode.Count); }
/// <summary> /// Add an item to the list. /// </summary> /// <param name="key">Key for later retrieval. /// Must implement IComparable.</param> /// <param name="val">The value to store</param> /// <exception cref="ArgumentException">Thrown if the same key is added twice</exception> /// <exception cref="ArgumentNullException">Thrown if key is null</exception> public void Add(object key, object val) { if (key == null) { throw new ArgumentNullException("key"); } SkipListNode update = new SkipListNode(m_max_level); SkipListNode n = m_header; SkipListNode next; for (int i = m_header.Level - 1; i >= 0; i--) { next = n[i]; while ((next != null) && (m_comparator.Compare(next.Key, key) < 0)) { n = next; next = n[i]; } update[i] = n; } if ((n.Level > 0) && (n[0] != null) && (m_comparator.Compare(n[0].Key, key) == 0)) { // already here //n.Value = val; throw new ArgumentException("Can't add the same key twice", "key"); } else { // need to insert int level = RandomLevel(); int s = m_header.Level; if (level > s) { // this shouldn't happen any more. //Debug.Assert(false); m_header.Level = level; for (int i = s; i < level; i++) { update[i] = m_header; } } n = new SkipListNode(level, key, val); for (int i = 0; i < level; i++) { n[i] = update[i][i]; update[i][i] = n; } m_count++; } }
public void CreateSkipListNode() { using (ShimsContext.Create()) { ShimSkipList <int> .AllInstances.RandomLevel = (sl) => { return(33); }; SkipList <int> skipList = new SkipList <int>(); SkipListNode <int> node = skipList.CreateSkipListNode(50); Assert.AreEqual(50, node.Value); Assert.AreEqual(33, node.Next.Length); } }
public void Insert_1LevelTwoNodes_AtMiddle() { SkipListNode <int> node = new SkipListNode <int>(1, 75); this.OneLevelTwoNodes.Insert(node); Assert.AreEqual <int>(50, this.OneLevelTwoNodes.Head.Next[0].Value); Assert.AreEqual <int>(75, this.OneLevelTwoNodes.Head.Next[0].Next[0].Value); Assert.AreEqual <int>(100, this.OneLevelTwoNodes.Head.Next[0].Next[0].Next[0].Value); Assert.AreEqual <int>(1, this.OneLevelTwoNodes.Levels); Assert.AreEqual <int>(3, this.OneLevelTwoNodes.Count); }
private void Init2LevelsThreeNodesForTests() { SkipListNode<int> third = new SkipListNode<int>(1, 100); SkipListNode<int> second = new SkipListNode<int>(2, 75) { Next = new SkipListNode<int>[] { third, null, } }; SkipListNode<int> first = new SkipListNode<int>(1, 50) { Next = new SkipListNode<int>[] { second } }; this.TwoLevelsThreeNodes = new SkipList<int>() { Count = 3, Levels = 2, Head = new SkipListNode<int>(2, 0) { Next = new SkipListNode<int>[] { first, second } } }; }
public void Reset() { m_node = m_list.m_header; }
/// <summary> /// Create a skiplist. /// </summary> /// <param name="probability">Probability of adding a new level</param> /// <param name="maxLevel">Highest level in the list</param> public SkipList(float probability, int maxLevel) { m_probability = probability; m_max_level = maxLevel; m_header = new SkipListNode(1, new Ali(), null); }
public SkipListEnumerator(SkipList list) { m_list = list; m_node = m_list.m_header; }
public bool MoveNext() { Debug.Assert(m_node != null); m_node = m_node[0]; return m_node != null; }
/// <summary> /// Remove all of the items from the list. /// </summary> public void Clear() { m_header = new SkipListNode(1, new Ali(), null); m_count = 0; }
/// <summary> /// Removes the item associated with this key from the list. /// </summary> /// <param name="key">Object that implements IComparable</param> public void Remove(object key) { if (key == null) throw new ArgumentNullException("key"); SkipListNode update = new SkipListNode(m_max_level); SkipListNode n = m_header; SkipListNode next; for (int i=m_header.Level-1; i>=0; i--) { next = n[i]; while ((next != null) && (m_comparator.Compare(next.Key, key) < 0)) { n = next; next = n[i]; } update[i] = n; } if (n.Level == 0) return; // or assert n = n[0]; if ((n == null) || (m_comparator.Compare(n.Key, key) != 0)) { // not found return; // or assert } for (int i=0; i<m_header.Level; i++) { if (update[i][i] != n) break; update[i][i] = n[i]; } // TODO: reset m_header level m_count--; }
/// <summary> /// Add an item to the list. /// </summary> /// <param name="key">Key for later retrieval. /// Must implement IComparable.</param> /// <param name="val">The value to store</param> /// <exception cref="ArgumentException">Thrown if the same key is added twice</exception> /// <exception cref="ArgumentNullException">Thrown if key is null</exception> public void Add(object key, object val) { if (key == null) throw new ArgumentNullException("key"); SkipListNode update = new SkipListNode(m_max_level); SkipListNode n = m_header; SkipListNode next; for (int i=m_header.Level-1; i>=0; i--) { next = n[i]; while ((next != null) && (m_comparator.Compare(next.Key, key) < 0)) { n = next; next = n[i]; } update[i] = n; } if ((n.Level > 0) && (n[0] != null) && (m_comparator.Compare(n[0].Key, key) == 0)) { // already here //n.Value = val; throw new ArgumentException("Can't add the same key twice", "key"); } else { // need to insert int level = RandomLevel(); int s = m_header.Level; if (level > s) { // this shouldn't happen any more. //Debug.Assert(false); m_header.Level = level; for (int i=s; i<level; i++) { update[i] = m_header; } } n = new SkipListNode(level, key, val); for (int i=0; i<level; i++) { n[i] = update[i][i]; update[i][i] = n; } m_count++; } }
public void Insert_1LevelTwoNodes_AtMiddle() { SkipListNode<int> node = new SkipListNode<int>(1, 75); this.OneLevelTwoNodes.Insert(node); Assert.AreEqual<int>(50, this.OneLevelTwoNodes.Head.Next[0].Value); Assert.AreEqual<int>(75, this.OneLevelTwoNodes.Head.Next[0].Next[0].Value); Assert.AreEqual<int>(100, this.OneLevelTwoNodes.Head.Next[0].Next[0].Next[0].Value); Assert.AreEqual<int>(1, this.OneLevelTwoNodes.Levels); Assert.AreEqual<int>(3, this.OneLevelTwoNodes.Count); }
public void Insert_IntoEmpty() { SkipListNode<int> node = new SkipListNode<int>(1, 50); this.Empty.Insert(node); Assert.AreEqual<int>(50, this.Empty.Head.Next[0].Value); Assert.AreEqual<int>(1, this.Empty.Levels); Assert.AreEqual<int>(1, this.Empty.Count); }
public void Insert_1LevelTwoNodes_2ndLevel_AtStart() { SkipListNode<int> node = new SkipListNode<int>(2, 25); this.OneLevelTwoNodes.Insert(node); Assert.AreEqual<int>(25, this.OneLevelTwoNodes.Head.Next[0].Value); Assert.AreEqual<int>(50, this.OneLevelTwoNodes.Head.Next[0].Next[0].Value); Assert.AreEqual<int>(100, this.OneLevelTwoNodes.Head.Next[0].Next[0].Next[0].Value); Assert.AreEqual<int>(25, this.OneLevelTwoNodes.Head.Next[1].Value); Assert.AreEqual<int>(2, this.OneLevelTwoNodes.Levels); Assert.AreEqual<int>(3, this.OneLevelTwoNodes.Count); }
public void Insert_1LevelOneNode_AtStart() { SkipListNode<int> node = new SkipListNode<int>(1, 25); this.OneLevelOneNode.Insert(node); Assert.AreEqual<int>(25, this.OneLevelOneNode.Head.Next[0].Value); Assert.AreEqual<int>(50, this.OneLevelOneNode.Head.Next[0].Next[0].Value); Assert.AreEqual<int>(1, this.OneLevelOneNode.Levels); Assert.AreEqual<int>(2, this.OneLevelOneNode.Count); }