// l + r private R connectEmpty() { synchronized (root) { Connector<T, R> l = left, r = right; if (l == null) { return pushRight(none(), none()); } left = right = null; l.rhs = null; T laright = l.right; l.right = none(); if (l.acc == NONE) { if (r == null) l.drain(); else { if (l.lhs != null) { l.lhs.right = r; r.lhs = l.lhs; } } return none(); } if (r == null) { return l.drainLeft(); } r.lhs = null; if (r.acc == NONE) { if (r.rhs != null) { r.rhs.left = l; l.rhs = r.rhs; l.right = laright; } return none(); } T raleft = r.left; r.left = none(); if (mergeable.test(laright, raleft)) { R acc = combiner.apply(l.acc, r.acc); if (l.left == NONE && r.right == NONE) { l.drain(); r.drain(); return acc; } l.acc = acc; l.right = r.right; if (r.rhs != null) { r.rhs.left = l; l.rhs = r.rhs; } return none(); } if (l.left == NONE) { if (r.right == NONE) right = new Connector<>(this, r.drain(), null); return l.drain(); } return r.drainRight(); } }
// l + <first|acc|last> + r private R connectOne(T first, R acc, T last) { synchronized (root) { Connector<T, R> l = left; if (l == null) { return pushRight(acc, last); } if (l.acc == NONE) { l.acc = acc; l.left = first; l.right = last; return connectEmpty(); } T laright = l.right; if (mergeable.test(laright, first)) { l.acc = combiner.apply(l.acc, acc); l.right = last; return connectEmpty(); } left = null; l.rhs = null; l.right = none(); if (l.left != NONE) { return pushRight(acc, last); } acc = pushRight(acc, last); if (acc != NONE) left = new Connector<>(null, acc, this); return l.drain(); } }
private CollapseSpliterator( CollapseSpliterator<T, R> root, Spliterator<T> source, Connector<T, R> left, Connector<T, R> right) { this.source = source; this.root = root; this.mergeable = root.mergeable; this.mapper = root.mapper; this.accumulator = root.accumulator; this.combiner = root.combiner; this.left = left; this.right = right; if (left != null) left.rhs = this; right.lhs = this; }
// l + <first|acc|?> private R pushLeft(T first, R acc) { synchronized (root) { Connector<T, R> l = left; if (l == null) return acc; left = null; l.rhs = null; T laright = l.right; l.right = none(); if (l.acc == NONE) { l.acc = acc; l.left = first; return none(); } if (this.mergeable.test(laright, first)) { l.acc = this.combiner.apply(l.acc, acc); return l.drainLeft(); } if (l.left == NONE) { left = new Connector<>(null, acc, this); return l.drain(); } } return acc; }