示例#1
0
        public void Add(IterableLinkedListNode <T> node)
        {
            if (_start == null)
            {
                Debug.Assert(_end == null);
                _start = node;
                _end   = _start;
            }
            else
            {
                foreach (var cursor in _cursorsWaiting)
                {
                    node.CursorsIncoming.Add(cursor);
                    cursor._next = node;
                }

                _end.Next = node;
                node.Prev = _end;
                _end      = node;
            }
            if (!_lookup.ContainsKey(node.Value))
            {
                _lookup.Add(node.Value, node);
            }
        }
示例#2
0
        private void SetNext(IterableLinkedListNode <T> next)
        {
            // remove from old CursorsIncoming
            if (_next != null)
            {
                Debug.Assert(_next.CursorsIncoming.Contains(this));
                _next.CursorsIncoming.Remove(this);
            }

            // Add to new CursorsIncoming
            if (next != null)
            {
                next.CursorsIncoming.Add(this);
            }

            // Cursor is now waiting for more
            if (next == null && !_waitingList.Contains(this))
            {
                _waitingList.Add(this);
            }

            // Cursor was waiting and now has something to read
            if (next != null && _waitingList.Contains(this))
            {
                _waitingList.Remove(this);
            }

            _next = next;
        }
示例#3
0
 public IterableLinkedList()
 {
     _lookup         = new Dictionary <T, IterableLinkedListNode <T> >();
     _start          = null;
     _end            = null;
     _cursorsWaiting = new HashSet <IterableLinkedListCursor <T> >();
 }
示例#4
0
        public IterableLinkedListCursor(IterableLinkedListNode <T> node, HashSet <IterableLinkedListCursor <T> > waitingList)
        {
            _node        = null;
            _waitingList = waitingList;

            SetNext(node);
        }
示例#5
0
        /// <summary>
        ///     Must call this first before GetCurrent
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (_next == null)
            {
                return(false);
            }
            _node = _next;

            SetNext(_node.Next);
            return(true);
        }
示例#6
0
        /// <summary>
        ///     Move to the end of the list. This means this node will get picked by all cursors, including the ones who read it
        ///     before
        /// </summary>
        public void Promote(IterableLinkedListNode <T> node)
        {
            if (node == null)
            {
                throw new ArgumentNullException();
            }
            var value = node.Value;

            if (!_lookup.ContainsKey(value))
            {
                throw new ArgumentOutOfRangeException();
            }

            if (_end == node) // tell all cursors to read this again
            {
                foreach (var curosr in _cursorsWaiting)
                {
                    node.CursorsIncoming.Add(curosr);
                    curosr._next = node;
                }
                return;
            }

            Debug.Assert(node.Next != null); // since we exclude last nodes

            var prev = node.Prev;
            var next = node.Next;
            var last = _end;

            // fix cursors
            foreach (var cursor in node.CursorsIncoming)
            {
                node.Next.CursorsIncoming.Add(cursor);
                cursor._next = node.Next;
            }
            node.CursorsIncoming.Clear();

            // take out
            node.Next = null;
            node.Prev = null;
            if (prev != null)
            {
                prev.Next = next;
            }
            else // this must be start node !
            {
                Debug.Assert(node == _start);
                _start = next;
            }
            next.Prev = prev;

            // attach to end
            Add(node);
        }