Example #1
0
        /// <summary>
        /// 拆分结点
        /// </summary>
        /// <param name="node">要被拆分的结点</param>
        /// <param name="offset">拆分偏移量</param>
        /// <param name="after">前拆将会将offset之前的元素作为返回结点,后拆分则会将offset之后的元素作为返回结点</param>
        /// <returns>拆分出的结点</returns>
        private QuickListNode SplitNode(QuickListNode node, int offset, bool after)
        {
            var newNode = CreateNode();

            newNode.List.Init(node.List.Split(offset, after));
            return(newNode);
        }
Example #2
0
 /// <summary>
 /// 快速列表结点是否允许插入
 /// </summary>
 /// <param name="node">结点</param>
 /// <returns>是否可以插入</returns>
 private bool AllowInsert(QuickListNode node)
 {
     if (node == null)
     {
         return(false);
     }
     return(node.List.Count < fill);
 }
Example #3
0
 /// <summary>
 /// 清空
 /// </summary>
 public void Clear()
 {
     header  = null;
     tail    = null;
     version = 0;
     Count   = 0;
     Length  = 0;
 }
Example #4
0
        /// <summary>
        /// 是否允许进行合并
        /// </summary>
        /// <param name="a">结点</param>
        /// <param name="b">结点</param>
        /// <returns>是否可以合并</returns>
        private bool AllowMerge(QuickListNode a, QuickListNode b)
        {
            if (a == null || b == null)
            {
                return(false);
            }

            return(a.List.Count + b.List.Count < (fill * MERGE_PRO));
        }
Example #5
0
 /// <summary>
 /// 构造一个迭代器
 /// </summary>
 /// <param name="quickList"></param>
 /// <param name="forward"></param>
 internal Enumerator(QuickList <TElement> quickList, bool forward)
 {
     this.quickList = quickList;
     this.forward   = forward;
     version        = quickList.version;
     current        = default(TElement);
     node           = forward ? quickList.header : quickList.tail;
     index          = 0;
 }
Example #6
0
        /// <summary>
        /// 列表弹出数据
        /// </summary>
        /// <param name="node">结点</param>
        /// <param name="head">是否是头部</param>
        private TElement ListPop(QuickListNode node, bool head)
        {
            var ele = head ? node.List.Shift() : node.List.Pop();

            if (node.List.Count <= 0)
            {
                DeleteNode(node);
            }
            --Count;
            ++version;
            return(ele);
        }
Example #7
0
        /// <summary>
        /// 尝试合并结点
        /// </summary>
        /// <param name="node">发起合并的结点</param>
        private void AttemptMergeNode(QuickListNode node)
        {
            if (node == null)
            {
                return;
            }

            QuickListNode backward, backwardBackward, forward, forwardForward;

            backward = backwardBackward = forward = forwardForward = null;

            if (node.Backward != null)
            {
                backward = node.Backward;
                if (backward.Backward != null)
                {
                    backwardBackward = backward.Backward;
                }
            }

            if (node.Forward != null)
            {
                forward = node.Forward;
                if (forward.Forward != null)
                {
                    forwardForward = forward.Forward;
                }
            }

            if (AllowMerge(backward, backwardBackward))
            {
                MergeNode(backward, backwardBackward, false);
                backward = backwardBackward = null;
            }

            if (AllowMerge(forward, forwardForward))
            {
                MergeNode(forward, forwardForward, true);
                forward = forwardForward = null;
            }

            if (AllowMerge(node, node.Backward))
            {
                MergeNode(node, node.Backward, false);
            }

            if (AllowMerge(node, node.Forward))
            {
                MergeNode(node, node.Forward, true);
            }
        }
Example #8
0
 /// <summary>
 /// 插入结点
 /// </summary>
 /// <param name="oldNode">旧的结点</param>
 /// <param name="newNode">新的结点</param>
 /// <param name="after">在旧的结点之前还是之后</param>
 private void InsertNode(QuickListNode oldNode, QuickListNode newNode, bool after)
 {
     if (after)
     {
         newNode.Backward = oldNode;
         if (oldNode != null)
         {
             newNode.Forward = oldNode.Forward;
             if (oldNode.Forward != null)
             {
                 oldNode.Forward.Backward = newNode;
             }
             oldNode.Forward = newNode;
         }
         if (tail == oldNode)
         {
             tail = newNode;
         }
     }
     else
     {
         newNode.Forward = oldNode;
         if (oldNode != null)
         {
             newNode.Backward = oldNode.Backward;
             if (oldNode.Backward != null)
             {
                 oldNode.Backward.Forward = newNode;
             }
             oldNode.Backward = newNode;
         }
         if (header == oldNode)
         {
             header = newNode;
         }
     }
     if (Length == 0)
     {
         header = tail = newNode;
     }
     ++Length;
 }
Example #9
0
        /// <summary>
        /// 列表弹出数据
        /// </summary>
        /// <param name="node">结点</param>
        /// <param name="head">是否是头部</param>
        private TElement ListPop(QuickListNode node, bool head)
        {
            TElement ele;

            if (head)
            {
                ele = node.List.Shift();
            }
            else
            {
                ele = node.List.Pop();
            }
            if (node.List.Count <= 0)
            {
                DeleteNode(node);
            }
            --Count;
            ++version;
            return(ele);
        }
Example #10
0
 /// <summary>
 /// 删除结点
 /// </summary>
 /// <param name="node">结点</param>
 private void DeleteNode(QuickListNode node)
 {
     if (node.Forward != null)
     {
         node.Forward.Backward = node.Backward;
     }
     if (node.Backward != null)
     {
         node.Backward.Forward = node.Forward;
     }
     if (node == tail)
     {
         tail = node.Backward;
     }
     if (node == header)
     {
         header = node.Forward;
     }
     Count -= node.List.Count;
     --Length;
     node.List.IsDelete = true;
 }
Example #11
0
            /// <summary>
            /// 移动到下一个节点
            /// </summary>
            /// <returns>下一个节点是否存在</returns>
            public bool MoveNext()
            {
                if (node == null)
                {
                    return(false);
                }

                if (version != quickList.version)
                {
                    throw new InvalidOperationException("Can not modify data when iterates again.");
                }

                if (forward)
                {
                    do
                    {
                        if (index < node.List.Count)
                        {
                            current = node.List[index++];
                            return(true);
                        }
                        index = 0;
                        node  = node.Forward;
                    } while (node != null);
                    return(false);
                }

                do
                {
                    if (index < node.List.Count)
                    {
                        current = node.List[node.List.Count - ++index];
                        return(true);
                    }
                    index = 0;
                    node  = node.Backward;
                } while (node != null);
                return(false);
            }
Example #12
0
 /// <summary>
 /// 将从结点合并进主节点
 /// </summary>
 /// <param name="master">主结点</param>
 /// <param name="slave">从结点</param>
 /// <param name="after">从结点将怎么合并</param>
 private void MergeNode(QuickListNode master, QuickListNode slave, bool after)
 {
     master.List.Merge(slave.List, after);
     DeleteNode(slave);
 }
Example #13
0
        /// <summary>
        /// 插入元素
        /// </summary>
        /// <param name="insert">被插入的元素</param>
        /// <param name="after">是否在被查找的元素之后插入</param>
        /// <param name="node">需要插入的结点</param>
        /// <param name="offset">结点相对偏移量</param>
        private void Insert(TElement insert, QuickListNode node, int offset, bool after)
        {
            bool full, fullNext, fullBackward, atTail, atHead;

            full = fullNext = fullBackward = atTail = atHead = false;
            QuickListNode newNode;

            if (node == null)
            {
                newNode = CreateNode();
                newNode.List.InsertAt(insert, 0);
                InsertNode(null, newNode, after);
                ++Count;
                ++version;
                return;
            }

            //如果结点不能插入那么标记为满
            if (!AllowInsert(node))
            {
                full = true;
            }

            if (after && (offset + 1) == node.List.Count)
            {
                //标记为尾部的元素
                atTail = true;
                //同时如果后面的结点也不能插入那么标记后置结点已满
                if (!AllowInsert(node.Forward))
                {
                    fullNext = true;
                }
            }

            if (!after && (offset == 0))
            {
                //标记为头部元素
                atHead = true;
                //同时如果之前的结点也不能插入那么标记前置结点已满
                if (!AllowInsert(node.Backward))
                {
                    fullBackward = true;
                }
            }

            //如果结点没有满,且是后插式插入
            if (!full && after)
            {
                if (offset + 1 < node.List.Count)
                {
                    //如果偏移量的位置之后还存在元素
                    node.List.InsertAt(insert, offset + 1);
                }
                else
                {
                    //如果之后没有元素那么直接推入
                    node.List.Push(insert);
                }
            }
            else if (!full)
            {
                //结点没有满,且是前插式
                node.List.InsertAt(insert, offset);
            }
            else if (atTail && node.Forward != null && !fullNext && after)
            {
                //如果当前结点满了,且是后插入尾部元素,并且下一个结点存在而且不是满的
                //那么就会插入到下一个结点中的头部
                newNode = node.Forward;
                newNode.List.UnShift(insert);
            }
            else if (atHead && node.Backward != null && !fullBackward && !after)
            {
                //如果当前结点满了,且是前插入头部元素,并且上一个结点存在而且不是满的
                //那么就会插入到上一个结点中的尾部
                newNode = node.Backward;
                newNode.List.Push(insert);
            }
            else if (((atTail && node.Forward != null && fullNext && after) ||
                      (atHead && node.Backward != null && fullBackward && !after)))
            {
                //如果当前结点是满的,且前置结点和后置结点都是满的那么
                //就新建一个结点,插入在2个结点之间
                newNode = CreateNode();
                newNode.List.InsertAt(insert, 0);
                InsertNode(node, newNode, after);
            }
            else
            {
                //如果当前结点是满的,且插入的元素不处于头部或者尾部的位置
                //那么拆分数据
                newNode = SplitNode(node, offset, after);
                if (after)
                {
                    newNode.List.UnShift(insert);
                }
                else
                {
                    newNode.List.Push(insert);
                }
                InsertNode(node, newNode, after);
                AttemptMergeNode(node);
            }

            ++Count;
            ++version;
        }
Example #14
0
 /// <summary>
 /// 重置迭代器
 /// </summary>
 void IEnumerator.Reset()
 {
     current = default(TElement);
     node    = forward ? quickList.header : quickList.tail;
     index   = 0;
 }
Example #15
0
 /// <summary>
 /// 快速列表结点是否允许插入
 /// </summary>
 /// <param name="node">结点</param>
 /// <returns>是否可以插入</returns>
 private bool AllowInsert(QuickListNode node)
 {
     return(node?.List.Count < fill);
 }