public static void RunTests() { LinkedNode a = new LinkedNode(3, new LinkedNode(5, new LinkedNode(7, null))); Console.WriteLine("a = " + Print(a)); LinkedNode b = new LinkedNode(1, new LinkedNode(2, new LinkedNode(5, new LinkedNode(8, null)))); Console.WriteLine("b = " + Print(b)); LinkedNode c = Merge(a, b); Console.WriteLine("c = " + Print(c)); DoublyLinkedNode d = new DoublyLinkedNode(3, new DoublyLinkedNode(5, new DoublyLinkedNode(7, null))); Console.WriteLine("d = " + Print(d)); DoublyLinkedNode e = new DoublyLinkedNode(1, new DoublyLinkedNode(2, new DoublyLinkedNode(5, new DoublyLinkedNode(8, null)))); Console.WriteLine("e = " + Print(e)); DoublyLinkedNode f = Merge(d, e); Console.WriteLine("f = " + Print(f)); }
/// <summary> /// Permanently transitions this lifetime to be either dead or immortal. /// No effect if already transitioned to the desired state. /// Invalid operation if already transitioned to another state. /// </summary> public void TransitionPermanently(Phase newPhase) { if (newPhase == Phase.Mortal) throw new ArgumentOutOfRangeException("newPhase"); Action[] callbacks; lock (this) { // transition if (Phase == newPhase) return; if (Phase != Phase.Mortal) throw new InvalidOperationException(String.Format("Can't transition from {0} to {1}", Phase, newPhase)); Phase = newPhase; // callbacks callbacks = _callbacks == null ? null : _callbacks.EnumerateOthers().ToArray(); _callbacks = null; } if (callbacks != null) foreach (var callback in callbacks) callback.Invoke(); }
private static DoublyLinkedNode Merge(DoublyLinkedNode l1, DoublyLinkedNode l2) { DoublyLinkedNode head = null; DoublyLinkedNode l1p = l1, l2p = l2; if (l1.data < l2.data) { head = l1; l1p = l1.next; l1.prev = head; } else { head = l2; l2p = l2.next; l2.prev = head; } head.prev = null; DoublyLinkedNode cur = head; while (l1p != null && l2p != null) { if (l1p.data < l2p.data) { cur.next = l1p; l1p.prev = cur; l1p = l1p.next; } else { cur.next = l2p; l2p.prev = cur; l2p = l2p.next; } cur = cur.next; } cur.next = (l1p != null ? l1p : l2p); if (cur.next != null) { cur.next.prev = cur; } return head; }
/// <summary> /// Registers the given action to perform when this lifetime is either immortal or dead. /// The returned action will remove the registration (of the given action) if invoked before this lifetime becomes immortal or dead. /// Runs the given action synchronously if this lifetime is already immortal or dead. /// </summary> public RegistrationRemover Register(Action action) { // hold a weak reference to the node, to ensure it can be collected after the this soul becomes non-mortal WeakReference weakNode; lock (this) { // safe check for already finished if (Phase != Phase.Mortal) { action(); return Soul.EmptyRemover; } // add callback for when finished if (_callbacks == null) _callbacks = DoublyLinkedNode<Action>.CreateEmptyCycle(); weakNode = new WeakReference(_callbacks.Prepend(action)); } // cleanup action that removes the registration return () => { var n = (DoublyLinkedNode<Action>)weakNode.Target; if (n == null) return; lock (this) n.Unlink(); }; }
internal DoublyLinkedNode(T value) { Value = value; Prev = null; Next = null; }
private DoublyLinkedNode <Point> MinimumNode(DoublyLinkedNode <Point> parent, DoublyLinkedNode <Point> left, DoublyLinkedNode <Point> right, Dimension dimension) { var minimum = parent; if (left != null && (dimension == Dimension.X && left.Item.X < minimum.Item.X || dimension == Dimension.Y && left.Item.Y < minimum.Item.Y)) { minimum = left; } if (right != null && (dimension == Dimension.X && right.Item.X < minimum.Item.X || dimension == Dimension.Y && right.Item.Y < minimum.Item.Y)) { minimum = right; } return(minimum); }
public DoublyLinkedNode(int data, DoublyLinkedNode next) { this.data = data; this.next = next; if (next != null) { this.next.prev = this; } }
private static string Print(DoublyLinkedNode p) { string o = "f: " + p.data.ToString(); while (p.next != null) { o += " -> " + p.next.data; p = p.next; } o += ',' + " b: " + p.data.ToString(); while (p.prev != null) { o += " -> " + p.prev.data; p = p.prev; } return o; }