mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8343426: ConcurrentSkipListMap.spliterator() can no longer split the stream
Co-authored-by: Doug Lea <dl@openjdk.org> Reviewed-by: vklang
This commit is contained in:
parent
a8152bdb9a
commit
2b57f402c4
2 changed files with 40 additions and 9 deletions
|
@ -3221,14 +3221,14 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
// factory method for KeySpliterator
|
||||
final KeySpliterator<K,V> keySpliterator() {
|
||||
Index<K,V> h; Node<K,V> n; long est;
|
||||
Index<K,V> h; Node<K,V> hn, n; long est;
|
||||
VarHandle.acquireFence();
|
||||
if ((h = head) == null) {
|
||||
if ((h = head) == null || (hn = h.node) == null) {
|
||||
n = null;
|
||||
est = 0L;
|
||||
}
|
||||
else {
|
||||
n = h.node;
|
||||
n = hn.next;
|
||||
est = getAdderCount();
|
||||
}
|
||||
return new KeySpliterator<K,V>(comparator, h, n, null, est);
|
||||
|
@ -3307,14 +3307,14 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
|
|||
|
||||
// Almost the same as keySpliterator()
|
||||
final ValueSpliterator<K,V> valueSpliterator() {
|
||||
Index<K,V> h; Node<K,V> n; long est;
|
||||
Index<K,V> h; Node<K,V> hn, n; long est;
|
||||
VarHandle.acquireFence();
|
||||
if ((h = head) == null) {
|
||||
if ((h = head) == null || (hn = h.node) == null) {
|
||||
n = null;
|
||||
est = 0L;
|
||||
}
|
||||
else {
|
||||
n = h.node;
|
||||
n = hn.next;
|
||||
est = getAdderCount();
|
||||
}
|
||||
return new ValueSpliterator<K,V>(comparator, h, n, null, est);
|
||||
|
@ -3411,14 +3411,14 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
|
|||
|
||||
// Almost the same as keySpliterator()
|
||||
final EntrySpliterator<K,V> entrySpliterator() {
|
||||
Index<K,V> h; Node<K,V> n; long est;
|
||||
Index<K,V> h; Node<K,V> hn, n; long est;
|
||||
VarHandle.acquireFence();
|
||||
if ((h = head) == null) {
|
||||
if ((h = head) == null || (hn = h.node) == null) {
|
||||
n = null;
|
||||
est = 0L;
|
||||
}
|
||||
else {
|
||||
n = h.node;
|
||||
n = hn.next;
|
||||
est = getAdderCount();
|
||||
}
|
||||
return new EntrySpliterator<K,V>(comparator, h, n, null, est);
|
||||
|
|
|
@ -1323,6 +1323,37 @@ public class ConcurrentSkipListMapTest extends JSR166TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterators.trySplit() returns null with an empty map and non-null when
|
||||
* it is not empty.
|
||||
*/
|
||||
public void testSpliterators() {
|
||||
// To test JDK-8343426
|
||||
ConcurrentSkipListMap<Integer, Integer> map = new ConcurrentSkipListMap<>();
|
||||
for (int i = 1; i <= 1000; i++) map.put(i, i);
|
||||
// ensure that the splits do happen
|
||||
assertNotNull(map.keySet().spliterator().trySplit());
|
||||
assertNotNull(map.entrySet().spliterator().trySplit());
|
||||
assertNotNull(map.values().spliterator().trySplit());
|
||||
// ensure that the splits return *all* the items in the set
|
||||
assertEquals(500_500, map.keySet()
|
||||
.parallelStream()
|
||||
.mapToInt(Integer::valueOf)
|
||||
.sum());
|
||||
assertEquals(500_500, map.values()
|
||||
.parallelStream()
|
||||
.mapToInt(Integer::valueOf)
|
||||
.sum());
|
||||
assertEquals(500_500 * 2, map.entrySet()
|
||||
.parallelStream()
|
||||
.mapToInt(entry -> entry.getKey() + entry.getValue())
|
||||
.sum());
|
||||
map.clear();
|
||||
assertNull(map.keySet().spliterator().trySplit());
|
||||
assertNull(map.entrySet().spliterator().trySplit());
|
||||
assertNull(map.values().spliterator().trySplit());
|
||||
}
|
||||
|
||||
static void assertEq(Item i, int j) {
|
||||
if (i == null)
|
||||
mustEqual(j, -1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue