3 * Copyright (C) 2009 Didier Villevalois
4 * Copyright (C) 2012 Maciej Piechotka
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
25 * Relaxed fibonacci heap priority queue implementation of the {@link Queue}.
27 * The elements of the priority queue are ordered according to their natural
28 * ordering, or by a compare_func provided at queue construction time. A
29 * priority queue does not permit null elements and does not have bounded
32 * This implementation provides O(1) time for offer and peek methods, and
33 * O(log n) for poll method. It is based on the algorithms described by
34 * Boyapati Chandra Sekhar in:
36 * "Worst Case Efficient Data Structures
37 * for Priority Queues and Deques with Heap Order"
38 * Boyapati Chandra Sekhar (under the guidance of Prof. C. Pandu Rangan)
39 * Department of Computer Science and Engineering
40 * Indian Institute of Technology, Madras
43 public class Gee.PriorityQueue<G> : Gee.AbstractQueue<G> {
46 * The elements' comparator function.
48 [CCode (notify = false)]
49 public CompareDataFunc<G> compare_func { private set; get; }
51 private int _size = 0;
52 private int _stamp = 0;
53 private Type1Node<G>? _r = null;
54 private Type2Node<G>? _r_prime = null;
55 private Type2Node<G>? _lm_head = null;
56 private Type2Node<G>? _lm_tail = null;
57 private Type1Node<G>? _p = null;
59 private Type1Node<G>?[] _a = new Type1Node<G>?[0];
61 private Type1Node<G>?[] _a = new Type1Node<G>[0];
63 private NodePair<G>? _lp_head = null;
64 private unowned NodePair<G>? _lp_tail = null;
65 private bool[] _b = new bool[0];
66 private Type1Node<G>? _ll_head = null;
67 private Type1Node<G>? _ll_tail = null;
68 private unowned Node<G> _iter_head = null;
69 private unowned Node<G> _iter_tail = null;
72 * Constructs a new, empty priority queue.
74 * If not provided, the function parameter is requested to the
75 * {@link Functions} function factory methods.
77 * @param compare_func an optional element comparator function
79 public PriorityQueue (owned CompareDataFunc<G>? compare_func = null) {
80 if (compare_func == null) {
81 compare_func = Functions.get_compare_func_for (typeof (G));
83 this.compare_func = compare_func;
89 public override int capacity {
90 get { return UNBOUNDED_CAPACITY; }
96 public override int remaining_capacity {
97 get { return UNBOUNDED_CAPACITY; }
103 public override bool is_full {
104 get { return false; }
110 public override bool read_only {
111 get { return false; }
117 public bool offer (G element) {
119 _dump ("Start offer: %s".printf ((string)element));
122 _r = new Type1Node<G> (element, ref _iter_head, ref _iter_tail);
124 } else if (_r_prime == null) {
125 _r_prime = new Type2Node<G> (element, ref _iter_head, ref _iter_tail);
126 _r_prime.parent = _r;
127 _r.type2_child = _r_prime;
128 if (_compare (_r_prime, _r) < 0)
129 _swap_data (_r_prime, _r);
131 // Form a tree with a single node N of type I consisting of element e
132 Type1Node<G> node = new Type1Node<G> (element, ref _iter_head, ref _iter_tail);
141 _dump ("End offer: %s".printf ((string)element));
149 public override G? peek () {
159 public override G? poll () {
161 _dump ("Start poll:");
164 // 1a. M inElement <- R.element
169 _r.pending_drop = false;
173 // 1b. R.element = R'.element
174 if (_r_prime == null) {
175 if (_r.iter_next != null) {
176 _r.iter_next.iter_prev = _r.iter_prev;
178 if (_r.iter_prev != null) {
179 _r.iter_prev.iter_next = _r.iter_next;
181 if (_iter_head == _r) {
182 _iter_head = _r.iter_next;
184 if (_iter_tail == _r) {
185 _iter_tail = _r.iter_prev;
191 _move_data (_r, _r_prime);
194 // 1c. R'' <- The child of R' containing the minimum element among the children of R'
195 if (_r_prime.type1_children_head == null) {
196 _remove_type2_node (_r_prime, true);
200 Type1Node<G>? r_second = null;
201 Type1Node<G> node = _r_prime.type1_children_head;
202 while (node != null) {
203 if (r_second == null || _compare (node, r_second) < 0) {
206 node = node.brothers_next;
209 // 1d. R'.element <- R''.element
210 _move_data (_r_prime, r_second);
212 // 2a. Delete the subtree rooted at R'' from Q
213 _remove_type1_node (r_second, true);
215 // 2b. For all children N of type I of R'' do make N a child of R' of Q
216 node = r_second.type1_children_head;
217 while (node != null) {
218 Type1Node<G> next = node.brothers_next;
219 _remove_type1_node (node, false);
220 _add_in_r_prime (node);
224 // For now we can't have type2 node other than R' (left for reference)
226 // 3a. If R'' has no child of type II then goto Step 4.
227 if (r_second.type2_child != null) {
228 // 3b. Let M' be the child of type II of R''. Insert(Q, M'.element)
229 Type2Node<G> m_prime = r_second.type2_child;
230 _remove_type2_node (m_prime);
231 offer (m_prime.data);
233 // 3c. For all children N of M do make N a child of R' of Q
234 node = m_prime.type1_children_head;
235 while (node != null) {
236 Type1Node<G> next = node.brothers_next;
237 _remove_type1_node (node);
238 _add_in_r_prime (node);
244 // 4. Adjust(Q, P, P)
247 // For now we can't have type2 node other than R' (left for reference)
249 // 5a. if LM is empty then goto Step 6
250 if (_lm_head != null) {
251 // 5b. M <- Head(LM); LM <- Tail(LM)
252 Type2Node<G> m = _lm_head;
254 // 5c. Delete M from Q
255 _remove_type2_node (m);
257 // 5d. I nsert(Q, M.element)
260 // 5e. For all children N of M do make M a child of R' of Q
261 node = m.type1_children_head;
262 while (node != null) {
263 Type1Node<G> next = node.brothers_next;
264 _remove_type1_node (node);
265 _add_in_r_prime (node);
271 // 6. While among the children of R' there exist any two different nodes Ri and Rj
272 // such that Ri.degree = Rj.degree do Link(Q, Ri, Rj)
273 while (_check_linkable ()) {}
275 // 7. Return MinElement
282 public int drain (Collection<G> recipient, int amount = -1) {
286 for (int i = 0; i < amount; i++) {
287 if (this._size == 0) {
290 recipient.add (poll ());
298 public override int size {
299 get { return _size; }
305 public override bool contains (G item) {
306 foreach (G an_item in this) {
307 if (compare_func (item, an_item) == 0) {
317 public override bool add (G item) {
324 public override bool remove (G item) {
326 _dump ("Start remove: %s".printf ((string) item));
329 Iterator<G> iterator = new Iterator<G> (this);
330 while (iterator.next ()) {
331 G an_item = iterator.get ();
332 if (compare_func (item, an_item) == 0) {
343 public override void clear () {
351 _a = new Type1Node<G>?[0];
353 _a = new Type1Node<G>[0];
367 public override Gee.Iterator<G> iterator () {
368 return new Iterator<G> (this);
371 private inline int _compare (Node<G> node1, Node<G> node2) {
372 // Assume there can't be two nodes pending drop
373 if (node1.pending_drop) {
375 } else if (node2.pending_drop) {
378 return compare_func (node1.data, node2.data);
382 private inline void _swap_data (Node<G> node1, Node<G> node2) {
384 _dump ("Before swap: %p(%s) %p(%s)".printf(node1, (string)node1.data, node2, (string)node2.data));
386 G temp_data = (owned) node1.data;
387 bool temp_pending_drop = node1.pending_drop;
388 node1.data = (owned) node2.data;
389 node1.pending_drop = node2.pending_drop;
390 node2.data = (owned) temp_data;
391 node2.pending_drop = temp_pending_drop;
393 if (node1.iter_next == node2) { // Before swap: N1 N2
394 unowned Node<G> temp_iter_prev = node1.iter_prev;
395 unowned Node<G> temp_iter_next = node2.iter_next;
397 node1.iter_prev = node2;
398 node1.iter_next = temp_iter_next;
399 node2.iter_prev = temp_iter_prev;
400 node2.iter_next = node1;
401 } else if (node1.iter_prev == node2) { // Before swap: N2 N1
402 unowned Node<G> temp_iter_prev = node2.iter_prev;
403 unowned Node<G> temp_iter_next = node1.iter_next;
405 node1.iter_prev = temp_iter_prev;
406 node1.iter_next = node2;
407 node2.iter_prev = node1;
408 node2.iter_next = temp_iter_next;
410 unowned Node<G> temp_iter_prev = node1.iter_prev;
411 unowned Node<G> temp_iter_next = node1.iter_next;
413 node1.iter_prev = node2.iter_prev;
414 node1.iter_next = node2.iter_next;
415 node2.iter_prev = temp_iter_prev;
416 node2.iter_next = temp_iter_next;
419 if (node2 == _iter_head) {
421 } else if (node1 == _iter_head) {
424 if (node2 == _iter_tail) {
426 } else if (node1 == _iter_tail) {
430 if (node1.iter_prev != null) {
431 node1.iter_prev.iter_next = node1;
433 if (node1.iter_next != null) {
434 node1.iter_next.iter_prev = node1;
436 if (node2.iter_prev != null) {
437 node2.iter_prev.iter_next = node2;
439 if (node2.iter_next != null) {
440 node2.iter_next.iter_prev = node2;
444 _dump ("After swap: %p(%s) %p(%s)".printf(node1, (string)node1.data, node2, (string)node2.data));
448 private inline void _move_data (Node<G> target, Node<G> source) {
450 _dump ("Before move: %p(%s) <- %p(%s)".printf(target, (string)target.data, source, (string)source.data));
453 if (target.iter_next != null) {
454 target.iter_next.iter_prev = target.iter_prev;
455 } else if (_iter_tail == target) {
456 _iter_tail = target.iter_prev;
458 if (target.iter_prev != null) {
459 target.iter_prev.iter_next = target.iter_next;
460 } else if (_iter_head == target) {
461 _iter_head = target.iter_next;
464 target.data = source.data;
465 target.pending_drop = source.pending_drop;
466 target.iter_next = source.iter_next;
467 target.iter_prev = source.iter_prev;
468 source.iter_next = null;
469 source.iter_prev = null;
471 if (target.iter_next != null) {
472 target.iter_next.iter_prev = target;
473 } else if (_iter_tail == source) {
476 if (target.iter_prev != null) {
477 target.iter_prev.iter_next = target;
478 } else if (_iter_head == source) {
482 _dump ("After move:");
486 private void _link (owned Type1Node<G> ri, owned Type1Node<G> rj) {
487 assert (ri.degree () == rj.degree ());
489 // Delete the subtrees rooted at Ri and Rj from Q
490 _remove_type1_node (ri, false);
491 _remove_type1_node (rj, false);
493 // If Ri.element > Rj.element then Swap(Ri,Rj)
494 if (_compare (ri, rj) > 0) {
495 Type1Node<G> temp = ri;
500 // Make Rj the last child of Ri
503 // Make Ri (whose degree now = d+1) a child of R' of Q
504 _add_in_r_prime (ri);
507 private void _add (Type1Node<G> n) {
508 // Make N a child of R' of Q
511 // If N.element < R'.element then Swap(N.element, R'.element)
512 if (_compare (n, _r_prime) < 0) {
513 _swap_data (n, _r_prime);
516 // If R'.element < R.element then Swap(R'.element, R.element)
517 if (_compare (_r_prime, _r) < 0) {
518 _swap_data (_r_prime, _r);
521 // If among the children of R' there exist any two different nodes Ri and Rj
522 // such that Ri.degree = Rj.degree then Link(Q, Ri, Rj)
526 _dump ("End _add: %p(%s)".printf (n, (string) n.data));
530 private bool _check_linkable () {
532 _dump ("Start _check_linkable:");
535 if (_lp_head != null) {
536 unowned NodePair<G> pair = _lp_head;
537 _link (pair.node1, pair.node2);
543 private Node<G> _re_insert (owned Type1Node<G> n) {
547 _dump ("Start _re_insert: %p(%s)".printf (n, (string) n.data));
551 Node<G> parent = n.parent;
553 // Delete the subtree rooted at N from Q
554 _remove_type1_node (n, false);
563 private void _adjust (Type1Node<G> p1, Type1Node<G> p2) {
564 // If M.lost <= 1 for all nodes M in Q then return
565 if (_ll_head == null) {
570 _dump ("Start _adjust: %p(%s), %p(%s)".printf (p1, (string) p1.data, p2, (string) p2.data));
573 // If P1.lost > P2.lost then M <- P1 else M <- P2
575 if (p1.lost > p2.lost) {
581 // If M.lost <= 1 then M <- M' for some node M' in Q such that M'.lost > 1
584 if (_ll_head.ll_next != null) {
585 _ll_head.ll_next.ll_prev = null;
587 _ll_head = _ll_head.ll_next;
590 // P <- ReInsert(Q, M)
591 _p = (Type1Node<G>) _re_insert (m);
594 _dump ("End _adjust: %p(%s), %p(%s)".printf (p1, (string) p1.data, p2, (string) p2.data));
598 private void _delete (Node<G> n) {
599 // DecreaseKey(Q, N, infinite)
606 private void _decrease_key (Node<G> n) {
608 _dump ("Start _decrease_key: %p(%s)".printf (n, (string) n.data));
611 if (n == _r || _r_prime == null) {
615 n.pending_drop = true;
617 // If (N = R or R') and (R'.element < R.element) then
618 // Swap(R'.element, R.element); return
619 if (n == _r_prime && _compare (_r_prime, _r) < 0) {
620 _swap_data (_r_prime, _r);
624 // For now we can't have type2 node other than R' (left for reference)
626 // If (N is of type II) and (N.element < N.parent.element) then
627 // Swap(N.element, N.parent.element); N <- N.parent
628 if (n is Type2Node && _compare (n, n.parent) < 0) {
629 _swap_data (n, n.parent);
634 // Can't occur as we made n be the most little (left for reference)
636 // If N.element >= N.parent.element then return
637 if (n.parent != null && _compare (n, n.parent) >= 0) {
642 // P' <- ReInsert(Q, N)
643 Node<G> p_prime = _re_insert ((Type1Node<G>) n);
645 if (p_prime is Type2Node) {
650 _adjust (_p, (Type1Node<G>) p_prime);
654 private void _add_to (Type1Node<G> node, Type1Node<G> parent) {
659 private void _add_in_r_prime (Type1Node<G> node) {
661 _dump ("Start _add_in_r_prime: %p(%s)".printf (node, (string) node.data));
664 int degree = node.degree ();
666 Type1Node<G>? insertion_point = null;
667 if (degree < _a.length) {
668 insertion_point = _a[degree];
671 if (insertion_point == null) {
672 if (_r_prime.type1_children_tail != null) {
673 node.brothers_prev = _r_prime.type1_children_tail;
674 _r_prime.type1_children_tail.brothers_next = node;
676 _r_prime.type1_children_head = node;
678 _r_prime.type1_children_tail = node;
680 if (insertion_point.brothers_prev != null) {
681 insertion_point.brothers_prev.brothers_next = node;
682 node.brothers_prev = insertion_point.brothers_prev;
684 _r_prime.type1_children_head = node;
686 node.brothers_next = insertion_point;
687 insertion_point.brothers_prev = node;
689 node.parent = _r_prime;
691 // Maintain A, B and LP
692 if (degree >= _a.length) {
693 _a.resize (degree + 1);
694 _b.resize (degree + 1);
697 // If there is already a child of such degree
698 if (_a[degree] == null) {
701 // Else if there is an odd number of child of such degree
704 NodePair<G> pair = new NodePair<G> (node, node.brothers_next);
705 node.brothers_next.pair = pair;
707 if (_lp_head == null) {
709 _lp_head = (owned)pair;
711 pair.lp_prev = _lp_tail;
712 _lp_tail.lp_next = (owned)pair;
713 _lp_tail = _lp_tail.lp_next;
715 // There is now an even number of child of such degree
724 _dump ("End _add_in_r_prime: %p(%s)".printf (node, (string) node.data));
728 private void _remove_type1_node (Type1Node<G> node, bool with_iteration) {
730 _dump ("Start _remove_type1_node: %p(%s)".printf (node, (string) node.data));
733 if (node.parent == _r_prime) {
734 _updated_degree (node, false);
737 if (node.ll_prev != null) {
738 node.ll_prev.ll_next = node.ll_next;
739 } else if (_ll_head == node) {
740 _ll_head = node.ll_next;
742 if (node.ll_next != null) {
743 node.ll_next.ll_prev = node.ll_prev;
744 } else if (_ll_tail == node) {
745 _ll_tail = node.ll_prev;
748 if (node.parent != null) {
749 if (node.parent.parent == _r_prime) {
750 _updated_degree ((Type1Node<G>) node.parent, true);
751 } else if (node.parent.parent != null) {
752 Type1Node<G> parent = (Type1Node<G>) node.parent;
754 // Increment parent's lost count
757 // And add it to LL if needed
758 if (parent.lost > 1) {
759 if (_ll_tail != null) {
760 parent.ll_prev = _ll_tail;
761 _ll_tail.ll_next = parent;
771 // Check whether removed node is P
776 // Maintain brothers list
779 // Maintain iteration
780 if (with_iteration) {
781 if (node.iter_prev != null) {
782 node.iter_prev.iter_next = node.iter_next;
783 } else if (_iter_head == node) {
784 _iter_head = node.iter_next;
786 if (node.iter_next != null) {
787 node.iter_next.iter_prev = node.iter_prev;
788 } else if (_iter_tail == node) {
789 _iter_tail = node.iter_prev;
793 _dump ("End _remove_type1_node: %p(%s)".printf (node, (string) node.data));
797 private void _updated_degree (Type1Node<G> node, bool child_removed) {
798 int degree = node.degree ();
800 // Ensure proper sizes of A and B
801 if (degree >= _a.length) {
802 _a.resize (degree + 1);
803 _b.resize (degree + 1);
807 if (child_removed && _a[degree - 1] == null) {
808 _a[degree - 1] = node;
809 _b[degree - 1] = ! _b[degree - 1];
812 _b[degree] = ! _b[degree];
813 if (_a[degree] == node) {
814 Type1Node<G> next = node.brothers_next;
815 if (next != null && next.degree () == degree) {
820 int i = _a.length - 1;
821 while (i >= 0 && _a[i] == null) {
830 if (node.pair != null) {
831 unowned NodePair<G> pair = node.pair;
832 Type1Node<G> other = (pair.node1 == node ? pair.node2 : pair.node1);
835 if (pair.lp_next != null) {
836 pair.lp_next.lp_prev = pair.lp_prev;
838 _lp_tail = pair.lp_prev;
840 if (pair.lp_prev != null) {
841 pair.lp_prev.lp_next = (owned)pair.lp_next;
843 _lp_head = (owned)pair.lp_next;
848 private void _remove_type2_node (Type2Node<G> node, bool with_iteration) {
850 _dump ("Start _remove_type2_node: %p(%s)".printf (node, (string) node.data));
852 ((Type1Node<G>) node.parent).type2_child = null;
855 // For now we can't have type2 node other than R' (left for reference)
858 if (node != _r_prime) {
859 if (node.lm_prev != null) {
860 node.lm_prev.lm_next = node.lm_next;
861 } else if (_lm_head == node) {
862 _lm_head = node.lm_next;
864 if (node.lm_next != null) {
865 node.lm_next.lm_prev = node.lm_prev;
866 } else if (_lm_tail == node) {
867 _lm_tail = node.lm_prev;
874 // Maintain iteration
875 if (with_iteration) {
876 if (node.iter_prev != null) {
877 node.iter_prev.iter_next = node.iter_next;
878 } else if (_iter_head == node) {
879 _iter_head = node.iter_next;
881 if (node.iter_next != null) {
882 node.iter_next.iter_prev = node.iter_prev;
883 } else if (_iter_tail == node) {
884 _iter_tail = node.iter_prev;
888 _dump ("End _remove_type2_node: %p(%s)".printf (node, (string) node.data));
893 public void _dump (string message) {
894 stdout.printf (">>>> %s\n", message);
896 stdout.printf ("A.length = %d:", _a.length);
897 foreach (Node<G>? node in _a) {
898 stdout.printf (" %p(%s);", node, node != null ? (string) node.data : null);
900 stdout.printf ("\n");
902 stdout.printf ("B.length = %d:", _b.length);
903 foreach (bool even in _b) {
904 stdout.printf (" %s;", even.to_string ());
906 stdout.printf ("\n");
908 stdout.printf ("LP:");
909 unowned NodePair<G>? pair = _lp_head;
910 while (pair != null) {
911 stdout.printf (" (%p(%s),%p(%s));", pair.node1, (string) pair.node1.data, pair.node2, (string) pair.node2.data);
914 stdout.printf ("\n");
916 stdout.printf ("LL:");
917 unowned Type1Node<G>? node = _ll_head;
918 while (node != null) {
919 stdout.printf (" %p(%s);", node, (string) node.data);
922 stdout.printf ("\n");
924 stdout.printf ("ITER:");
925 unowned Node<G>? inode_prev = null;
926 unowned Node<G>? inode = _iter_head;
927 while (inode != null) {
928 stdout.printf (" %p(%s);", inode, (string) inode.data);
929 assert (inode.iter_prev == inode_prev);
931 inode = inode.iter_next;
933 stdout.printf ("\n");
935 stdout.printf ("%s\n", _r != null ? _r.to_string () : null);
937 stdout.printf ("\n");
941 private abstract class Node<G> {
943 public weak Node<G>? parent = null;
945 public int type1_children_count;
946 public Type1Node<G>? type1_children_head = null;
947 public Type1Node<G>? type1_children_tail = null;
949 public unowned Node<G>? iter_prev;
950 public unowned Node<G>? iter_next = null;
952 public bool pending_drop;
954 protected Node (G data, ref unowned Node<G>? head, ref unowned Node<G>? tail) {
958 if (iter_prev != null) {
959 iter_prev.iter_next = this;
966 public inline int degree () {
967 return type1_children_count;
971 public string children_to_string (int level = 0) {
972 StringBuilder builder = new StringBuilder ();
974 Type1Node<G> child = type1_children_head;
975 while (child != null) {
977 builder.append (",\n");
980 builder.append (child.to_string (level));
981 child = child.brothers_next;
986 public abstract string to_string (int level = 0);
990 private class Type1Node<G> : Node<G> {
992 public weak Type1Node<G>? brothers_prev = null;
993 public Type1Node<G>? brothers_next = null;
994 public Type2Node<G>? type2_child = null;
995 public weak Type1Node<G>? ll_prev = null;
996 public Type1Node<G>? ll_next = null;
997 public weak NodePair<G>? pair = null;
999 public Type1Node (G data, ref unowned Node<G>? head, ref unowned Node<G>? tail) {
1000 base (data, ref head, ref tail);
1003 public inline void add (Type1Node<G> node) {
1005 if (type1_children_head == null) {
1006 type1_children_head = node;
1008 node.brothers_prev = type1_children_tail;
1010 if (type1_children_tail != null) {
1011 type1_children_tail.brothers_next = node;
1013 type1_children_tail = node;
1014 type1_children_count++;
1017 public inline void remove () {
1018 if (brothers_prev == null) {
1019 parent.type1_children_head = brothers_next;
1021 brothers_prev.brothers_next = brothers_next;
1023 if (brothers_next == null) {
1024 parent.type1_children_tail = brothers_prev;
1026 brothers_next.brothers_prev = brothers_prev;
1028 parent.type1_children_count--;
1030 brothers_prev = null;
1031 brothers_next = null;
1035 public override string to_string (int level = 0) {
1036 StringBuilder builder = new StringBuilder ();
1037 builder.append (string.nfill (level, '\t'));
1038 builder.append ("(");
1039 builder.append_printf("%p(%s)/%u", this, (string)data, lost);
1040 if (type1_children_head != null || type2_child != null) {
1041 builder.append (":\n");
1043 if (type1_children_head != null) {
1044 builder.append (children_to_string (level + 1));
1046 if (type1_children_head != null && type2_child != null) {
1047 builder.append (",\n");
1049 if (type2_child != null) {
1050 builder.append (type2_child.to_string (level + 1));
1052 if (type1_children_head != null || type2_child != null) {
1053 builder.append ("\n");
1054 builder.append (string.nfill (level, '\t'));
1056 builder.append (")");
1062 private class Type2Node<G> : Node<G> {
1063 // For now we can't have type2 node other than R' (left for reference)
1065 public weak Type2Node<G>? lm_prev = null;
1066 public Type2Node<G>? lm_next = null;
1069 public Type2Node (G data, ref unowned Node<G>? head, ref unowned Node<G>? tail) {
1070 base (data, ref head, ref tail);
1074 public override string to_string (int level = 0) {
1075 StringBuilder builder = new StringBuilder ();
1076 builder.append (string.nfill (level, '\t'));
1077 builder.append_printf ("[%p(%s)", this, (string)data);
1078 if (type1_children_head != null) {
1079 builder.append (":\n");
1080 builder.append (children_to_string (level + 1));
1081 builder.append ("\n");
1082 builder.append (string.nfill (level, '\t'));
1084 builder.append ("]");
1090 private class DummyNode<G> : Node<G> {
1091 public DummyNode (ref unowned Node<G>? prev_next, ref unowned Node<G>? next_prev, Node<G>? iter_prev, Node<G>? iter_next) {
1093 base ("<<dummy>>", ref prev_next, ref next_prev);
1095 base (null, ref prev_next, ref next_prev);
1097 this.iter_prev = iter_prev;
1098 this.iter_next = iter_next;
1099 prev_next = next_prev = this;
1103 public override string to_string (int level = 0) {
1104 StringBuilder builder = new StringBuilder ();
1105 builder.append (string.nfill (level, '\t'));
1106 builder.append ("%p<<dummy>>".printf(this));
1113 private class NodePair<G> {
1114 public unowned NodePair<G>? lp_prev = null;
1115 public NodePair<G>? lp_next = null;
1116 public unowned Type1Node<G> node1 = null;
1117 public unowned Type1Node<G> node2 = null;
1119 public NodePair (Type1Node<G> node1, Type1Node<G> node2) {
1125 private class Iterator<G> : Object, Traversable<G>, Gee.Iterator<G> {
1126 private PriorityQueue<G> queue;
1127 private unowned Node<G>? position;
1128 private unowned Node<G>? previous;
1131 public Iterator (PriorityQueue<G> queue) {
1133 this.position = null;
1134 this.previous = null;
1135 this.stamp = queue._stamp;
1138 public bool next () {
1139 unowned Node<G>? next = _get_next_node ();
1141 previous = position;
1144 return next != null;
1147 public bool has_next () {
1148 return _get_next_node () != null;
1151 private inline unowned Node<G>? _get_next_node () {
1152 if (position != null) {
1153 return position.iter_next;
1155 return (previous != null) ? previous.iter_next : queue._iter_head;
1159 public new G get () {
1160 assert (stamp == queue._stamp);
1161 assert (position != null);
1162 return position.data;
1165 public void remove () {
1166 assert (stamp == queue._stamp);
1167 assert (position != null);
1169 if (previous != null) {
1170 dn = new DummyNode<G> (ref previous.iter_next, ref position.iter_prev, previous, position);
1172 dn = new DummyNode<G> (ref queue._iter_head, ref position.iter_prev, null, position);
1174 queue._delete (position);
1176 if (previous != null) {
1177 previous.iter_next = dn.iter_next;
1179 if (dn == queue._iter_head) {
1180 queue._iter_head = dn.iter_next;
1182 if (dn.iter_next != null) {
1183 dn.iter_next.iter_prev = previous;
1185 if (dn == queue._iter_tail) {
1186 queue._iter_tail = previous;
1189 assert (stamp == queue._stamp);
1192 public bool read_only { get { return false; } }
1194 public bool valid { get { return position != null; } }
1196 public bool foreach (ForallFunc<G> f) {
1197 if (position == null) {
1198 position = (previous != null) ? previous.iter_next : queue._iter_head;
1200 if (position == null) {
1203 if (!f (position.data)) {
1206 while (position.iter_next != null) {
1207 previous = position;
1208 position = position.iter_next;
1209 if (!f (position.data)) {