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); } }
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; }
public IterableLinkedList() { _lookup = new Dictionary <T, IterableLinkedListNode <T> >(); _start = null; _end = null; _cursorsWaiting = new HashSet <IterableLinkedListCursor <T> >(); }
public IterableLinkedListCursor(IterableLinkedListNode <T> node, HashSet <IterableLinkedListCursor <T> > waitingList) { _node = null; _waitingList = waitingList; SetNext(node); }
/// <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); }
/// <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); }