/// <summary> /// Merge current node with <paramref name="newNext"/>, the nodes between this and <paramref name="newNext"/> are abandoned. /// 合并当前结点与<paramref name="newNext"/>, 之间的结点将会被抛弃 /// </summary> /// <param name="newNext">需要被合并的结点,请保证它是当前结点的后继</param> /// <param name="startIndex">合并的结点开始合并的数据位置</param> public void Merge(UnrolledLinkedListNode <TData> newNext, int startIndex) { Contract.Requires <ArgumentNullException>(newNext != null); Contract.Requires <ArgumentOutOfRangeException>(startIndex >= 0 && startIndex <= Count); Contract.Ensures(Contract.OldValue(newNext.Next) == Next); if (newNext == this) { return; } if (newNext.Count > 0) { var copycount = newNext.Count - startIndex; Array.Copy(newNext._items, startIndex, _items, Count, copycount); if (_rmref) { Array.Clear(newNext._items, 0, startIndex); } Count += copycount; } Next = newNext.Next; Update(); }
public BackEnumerator(UnrolledLinkedList <TNode, TData> list) { this.list = list; cnode = null; current = default(TData); index = 0; version = list.Version; }
public void Clear() { head = _new(blocksize); head.Next = head; Count = 0; _hotindex = 0; _hotnode = null; Version++; }
public void Reset() { if (version != list.Version) { throw new InvalidOperationException("在枚举过程中集合被修改过"); } current = default(TData); cnode = null; }
public UnrolledLinkedList(Func <int, TNode> newNode, int capacity) { Contract.Requires <ArgumentNullException>(newNode != null); Contract.Requires <ArgumentException>(capacity >= 0); if (capacity < _minCapacity) { capacity = _minCapacity; } _new = newNode; blocksize = (int)Math.Ceiling(_splitFactor * Math.Sqrt(capacity)); head = _new(blocksize); head.Next = head; }
public bool MoveNext() { if (version != list.Version) { throw new InvalidOperationException("在枚举过程中集合被修改过"); } if (cnode == null) { cnode = list.head.Previous; index = cnode.Count - 1; if (list.Count == 0) { return(false); } current = cnode._items[index--]; return(true); } else { if (index >= 0) { current = cnode._items[index--]; return(true); } else { if (cnode == list.head) { return(false); } cnode = cnode.Previous; index = cnode.Count - 1; current = cnode._items[index--]; return(true); } } }
private void FixNode(UnrolledLinkedListNode <TData> node) { if (node.Count < node.Capacity * MergeFactor) { if (node.Next != head && node.Count + node.Next.Count <= node.Capacity) { if (node.Next == _hotnode) // update hot { _hotindex -= node.Count; _hotnode = node; } node.Merge(node.Next); } if (node != head && node.Count + node.Previous.Count <= node.Previous.Capacity) { if (node == _hotnode) // update hot { _hotnode = node.Previous; _hotindex -= _hotnode.Count; } node.Previous.Merge(node); } } }
private UnrolledLinkedListNode <TData> Find(ref int index) { if (index < _hotindex) { if (index < _hotindex - index) // front -> hotindex { _hotindex = index; _hotnode = head; while (index >= _hotnode.Count) { index -= _hotnode.Count; _hotnode = _hotnode.Next; } _hotindex -= index; return(_hotnode); } else // hotindex -> front { var temp = index; _hotnode = _hotnode.Previous; index = _hotindex - index; while (index > _hotnode.Count) { index -= _hotnode.Count; _hotnode = _hotnode.Previous; } index = _hotnode.Count - index; _hotindex = temp - index; return(_hotnode); } } else { if (index - _hotindex < Count - index) // hotindex -> end { var temp = index; if (_hotnode == null) { _hotnode = head; } index -= _hotindex; while (index >= _hotnode.Count) { index -= _hotnode.Count; _hotnode = _hotnode.Next; } _hotindex = temp - index; return(_hotnode); } else // end -> hotindex { _hotindex = index; _hotnode = head.Previous; index = Count - index; while (index > _hotnode.Count) { index -= _hotnode.Count; _hotnode = _hotnode.Previous; } index = _hotnode.Count - index; _hotindex -= index; return(_hotnode); } } }
public void Merge(UnrolledLinkedListNode <TData> newNext) { Contract.Requires <ArgumentNullException>(newNext != null); Contract.Ensures(Contract.OldValue(newNext.Next) == Next); Merge(newNext, 0); }