797 |
|
} |
798 |
|
|
799 |
|
/** A customized variant of Spliterators.IteratorSpliterator */ |
800 |
< |
static final class LBQSpliterator<E> implements Spliterator<E> { |
800 |
> |
final class LBQSpliterator implements Spliterator<E> { |
801 |
|
static final int MAX_BATCH = 1 << 25; // max batch array size; |
802 |
– |
final LinkedBlockingQueue<E> queue; |
802 |
|
Node<E> current; // current node; null until initialized |
803 |
|
int batch; // batch size for splits |
804 |
|
boolean exhausted; // true when no more nodes |
805 |
|
long est; // size estimate |
806 |
< |
LBQSpliterator(LinkedBlockingQueue<E> queue) { |
807 |
< |
this.queue = queue; |
809 |
< |
this.est = queue.size(); |
810 |
< |
} |
806 |
> |
|
807 |
> |
LBQSpliterator() { this.est = size(); } |
808 |
|
|
809 |
|
public long estimateSize() { return est; } |
810 |
|
|
811 |
|
public Spliterator<E> trySplit() { |
812 |
|
Node<E> h; |
816 |
– |
final LinkedBlockingQueue<E> q = this.queue; |
813 |
|
int b = batch; |
814 |
|
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1; |
815 |
|
if (!exhausted && |
816 |
< |
((h = current) != null || (h = q.head.next) != null) && |
816 |
> |
((h = current) != null || (h = head.next) != null) && |
817 |
|
h.next != null) { |
818 |
|
Object[] a = new Object[n]; |
819 |
|
int i = 0; |
820 |
|
Node<E> p = current; |
821 |
< |
q.fullyLock(); |
821 |
> |
fullyLock(); |
822 |
|
try { |
823 |
< |
if (p != null || (p = q.head.next) != null) { |
823 |
> |
if (p != null || (p = head.next) != null) { |
824 |
|
do { |
825 |
|
if ((a[i] = p.item) != null) |
826 |
|
++i; |
827 |
|
} while ((p = p.next) != null && i < n); |
828 |
|
} |
829 |
|
} finally { |
830 |
< |
q.fullyUnlock(); |
830 |
> |
fullyUnlock(); |
831 |
|
} |
832 |
|
if ((current = p) == null) { |
833 |
|
est = 0L; |
848 |
|
|
849 |
|
public void forEachRemaining(Consumer<? super E> action) { |
850 |
|
if (action == null) throw new NullPointerException(); |
855 |
– |
final LinkedBlockingQueue<E> q = this.queue; |
851 |
|
if (!exhausted) { |
852 |
|
exhausted = true; |
853 |
|
Node<E> p = current; |
854 |
|
do { |
855 |
|
E e = null; |
856 |
< |
q.fullyLock(); |
856 |
> |
fullyLock(); |
857 |
|
try { |
858 |
|
if (p == null) |
859 |
< |
p = q.head.next; |
859 |
> |
p = head.next; |
860 |
|
while (p != null) { |
861 |
|
e = p.item; |
862 |
|
p = p.next; |
864 |
|
break; |
865 |
|
} |
866 |
|
} finally { |
867 |
< |
q.fullyUnlock(); |
867 |
> |
fullyUnlock(); |
868 |
|
} |
869 |
|
if (e != null) |
870 |
|
action.accept(e); |
874 |
|
|
875 |
|
public boolean tryAdvance(Consumer<? super E> action) { |
876 |
|
if (action == null) throw new NullPointerException(); |
882 |
– |
final LinkedBlockingQueue<E> q = this.queue; |
877 |
|
if (!exhausted) { |
878 |
|
E e = null; |
879 |
< |
q.fullyLock(); |
879 |
> |
fullyLock(); |
880 |
|
try { |
881 |
|
if (current == null) |
882 |
< |
current = q.head.next; |
882 |
> |
current = head.next; |
883 |
|
while (current != null) { |
884 |
|
e = current.item; |
885 |
|
current = current.next; |
887 |
|
break; |
888 |
|
} |
889 |
|
} finally { |
890 |
< |
q.fullyUnlock(); |
890 |
> |
fullyUnlock(); |
891 |
|
} |
892 |
|
if (current == null) |
893 |
|
exhausted = true; |
922 |
|
* @since 1.8 |
923 |
|
*/ |
924 |
|
public Spliterator<E> spliterator() { |
925 |
< |
return new LBQSpliterator<E>(this); |
925 |
> |
return new LBQSpliterator(); |
926 |
|
} |
927 |
|
|
928 |
|
/** |