mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +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
|
// factory method for KeySpliterator
|
||||||
final KeySpliterator<K,V> 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();
|
VarHandle.acquireFence();
|
||||||
if ((h = head) == null) {
|
if ((h = head) == null || (hn = h.node) == null) {
|
||||||
n = null;
|
n = null;
|
||||||
est = 0L;
|
est = 0L;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
n = h.node;
|
n = hn.next;
|
||||||
est = getAdderCount();
|
est = getAdderCount();
|
||||||
}
|
}
|
||||||
return new KeySpliterator<K,V>(comparator, h, n, null, est);
|
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()
|
// Almost the same as keySpliterator()
|
||||||
final ValueSpliterator<K,V> valueSpliterator() {
|
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();
|
VarHandle.acquireFence();
|
||||||
if ((h = head) == null) {
|
if ((h = head) == null || (hn = h.node) == null) {
|
||||||
n = null;
|
n = null;
|
||||||
est = 0L;
|
est = 0L;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
n = h.node;
|
n = hn.next;
|
||||||
est = getAdderCount();
|
est = getAdderCount();
|
||||||
}
|
}
|
||||||
return new ValueSpliterator<K,V>(comparator, h, n, null, est);
|
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()
|
// Almost the same as keySpliterator()
|
||||||
final EntrySpliterator<K,V> entrySpliterator() {
|
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();
|
VarHandle.acquireFence();
|
||||||
if ((h = head) == null) {
|
if ((h = head) == null || (hn = h.node) == null) {
|
||||||
n = null;
|
n = null;
|
||||||
est = 0L;
|
est = 0L;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
n = h.node;
|
n = hn.next;
|
||||||
est = getAdderCount();
|
est = getAdderCount();
|
||||||
}
|
}
|
||||||
return new EntrySpliterator<K,V>(comparator, h, n, null, est);
|
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) {
|
static void assertEq(Item i, int j) {
|
||||||
if (i == null)
|
if (i == null)
|
||||||
mustEqual(j, -1);
|
mustEqual(j, -1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue