/// <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);
 }