693 * Returns the predecessor of p, or the last node if p.prev has been |
693 * Returns the predecessor of p, or the last node if p.prev has been |
694 * linked to self, which will only be true if traversing with a |
694 * linked to self, which will only be true if traversing with a |
695 * stale pointer that is now off the list. |
695 * stale pointer that is now off the list. |
696 */ |
696 */ |
697 final Node<E> pred(Node<E> p) { |
697 final Node<E> pred(Node<E> p) { |
698 Node<E> q = p.prev; |
698 if (p == (p = p.prev)) |
699 return (p == q) ? last() : q; |
699 p = last(); |
|
700 return p; |
700 } |
701 } |
701 |
702 |
702 /** |
703 /** |
703 * Returns the first node, the unique node p for which: |
704 * Returns the first node, the unique node p for which: |
704 * p.prev == null && p.next != p |
705 * p.prev == null && p.next != p |
865 return true; |
866 return true; |
866 } |
867 } |
867 |
868 |
868 public E peekFirst() { |
869 public E peekFirst() { |
869 restart: for (;;) { |
870 restart: for (;;) { |
870 for (Node<E> first = first(), p = first;;) { |
871 E item; |
871 final E item; |
872 Node<E> first = first(), p = first; |
872 if ((item = p.item) != null) { |
873 while ((item = p.item) == null) { |
873 // recheck for linearizability |
874 if (p == (p = p.next)) continue restart; |
874 if (first.prev != null) continue restart; |
875 if (p == null) |
875 return item; |
876 break; |
876 } |
877 } |
877 if ((p = succ(p)) == null) |
878 // recheck for linearizability |
878 return null; |
879 if (first.prev != null) continue restart; |
879 } |
880 return item; |
880 } |
881 } |
881 } |
882 } |
882 |
883 |
883 public E peekLast() { |
884 public E peekLast() { |
884 restart: for (;;) { |
885 restart: for (;;) { |
885 for (Node<E> last = last(), p = last;;) { |
886 E item; |
886 final E item; |
887 Node<E> last = last(), p = last; |
887 if ((item = p.item) != null) { |
888 while ((item = p.item) == null) { |
888 // recheck for linearizability |
889 if (p == (p = p.prev)) continue restart; |
889 if (last.next != null) continue restart; |
890 if (p == null) |
890 return item; |
891 break; |
891 } |
892 } |
892 if ((p = pred(p)) == null) |
893 // recheck for linearizability |
893 return null; |
894 if (last.next != null) continue restart; |
894 } |
895 return item; |
895 } |
896 } |
896 } |
897 } |
897 |
898 |
898 /** |
899 /** |
899 * @throws NoSuchElementException {@inheritDoc} |
900 * @throws NoSuchElementException {@inheritDoc} |