420 lines
12 KiB
Java
420 lines
12 KiB
Java
/*
|
|
* Copyright (C) 2010 The Guava Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.common.collect;
|
|
|
|
import com.google.common.collect.Synchronized.SynchronizedNavigableMap;
|
|
import com.google.common.collect.Synchronized.SynchronizedNavigableSet;
|
|
import com.google.common.collect.Synchronized.SynchronizedSortedMap;
|
|
import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
|
|
import com.google.common.collect.testing.SafeTreeMap;
|
|
import com.google.common.collect.testing.TestStringSortedMapGenerator;
|
|
import com.google.common.collect.testing.features.CollectionFeature;
|
|
import com.google.common.collect.testing.features.CollectionSize;
|
|
import com.google.common.collect.testing.features.MapFeature;
|
|
import com.google.common.testing.SerializableTester;
|
|
import java.io.Serializable;
|
|
import java.util.Comparator;
|
|
import java.util.Map.Entry;
|
|
import java.util.NavigableMap;
|
|
import java.util.NavigableSet;
|
|
import java.util.SortedMap;
|
|
import junit.framework.TestSuite;
|
|
|
|
/**
|
|
* Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}.
|
|
*
|
|
* @author Louis Wasserman
|
|
*/
|
|
public class SynchronizedNavigableMapTest extends SynchronizedMapTest {
|
|
@Override
|
|
protected <K, V> NavigableMap<K, V> create() {
|
|
@SuppressWarnings("unchecked")
|
|
NavigableMap<K, V> innermost =
|
|
new SafeTreeMap<>((Comparator<? super K>) Ordering.natural().nullsFirst());
|
|
TestMap<K, V> inner = new TestMap<>(innermost, mutex);
|
|
NavigableMap<K, V> outer = Synchronized.navigableMap(inner, mutex);
|
|
return outer;
|
|
}
|
|
|
|
static class TestEntry<K, V> extends ForwardingMapEntry<K, V> implements Serializable {
|
|
private final Entry<K, V> delegate;
|
|
private final Object mutex;
|
|
|
|
TestEntry(Entry<K, V> delegate, Object mutex) {
|
|
this.delegate = delegate;
|
|
this.mutex = mutex;
|
|
}
|
|
|
|
@Override
|
|
protected Entry<K, V> delegate() {
|
|
return delegate;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object object) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return super.equals(object);
|
|
}
|
|
|
|
@Override
|
|
public K getKey() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return super.getKey();
|
|
}
|
|
|
|
@Override
|
|
public V getValue() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return super.getValue();
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return super.hashCode();
|
|
}
|
|
|
|
@Override
|
|
public V setValue(V value) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return super.setValue(value);
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
static class TestMap<K, V> extends SynchronizedMapTest.TestMap<K, V>
|
|
implements NavigableMap<K, V> {
|
|
|
|
public TestMap(NavigableMap<K, V> delegate, Object mutex) {
|
|
super(delegate, mutex);
|
|
}
|
|
|
|
@Override
|
|
protected NavigableMap<K, V> delegate() {
|
|
return (NavigableMap<K, V>) super.delegate();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> ceilingEntry(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().ceilingEntry(key);
|
|
}
|
|
|
|
@Override
|
|
public K ceilingKey(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().ceilingKey(key);
|
|
}
|
|
|
|
@Override
|
|
public NavigableSet<K> descendingKeySet() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().descendingKeySet();
|
|
}
|
|
|
|
@Override
|
|
public NavigableMap<K, V> descendingMap() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().descendingMap();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> firstEntry() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().firstEntry();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> floorEntry(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().floorEntry(key);
|
|
}
|
|
|
|
@Override
|
|
public K floorKey(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().floorKey(key);
|
|
}
|
|
|
|
@Override
|
|
public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().headMap(toKey, inclusive);
|
|
}
|
|
|
|
@Override
|
|
public SortedMap<K, V> headMap(K toKey) {
|
|
return headMap(toKey, false);
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> higherEntry(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().higherEntry(key);
|
|
}
|
|
|
|
@Override
|
|
public K higherKey(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().higherKey(key);
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> lastEntry() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().lastEntry();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> lowerEntry(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().lowerEntry(key);
|
|
}
|
|
|
|
@Override
|
|
public K lowerKey(K key) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().lowerKey(key);
|
|
}
|
|
|
|
@Override
|
|
public NavigableSet<K> navigableKeySet() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> pollFirstEntry() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().pollFirstEntry();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> pollLastEntry() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().pollLastEntry();
|
|
}
|
|
|
|
@Override
|
|
public NavigableMap<K, V> subMap(
|
|
K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive);
|
|
}
|
|
|
|
@Override
|
|
public SortedMap<K, V> subMap(K fromKey, K toKey) {
|
|
return delegate().subMap(fromKey, true, toKey, false);
|
|
}
|
|
|
|
@Override
|
|
public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().tailMap(fromKey, inclusive);
|
|
}
|
|
|
|
@Override
|
|
public SortedMap<K, V> tailMap(K fromKey) {
|
|
return tailMap(fromKey, true);
|
|
}
|
|
|
|
@Override
|
|
public Comparator<? super K> comparator() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().comparator();
|
|
}
|
|
|
|
@Override
|
|
public K firstKey() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().firstKey();
|
|
}
|
|
|
|
@Override
|
|
public K lastKey() {
|
|
assertTrue(Thread.holdsLock(mutex));
|
|
return delegate().lastKey();
|
|
}
|
|
|
|
private static final long serialVersionUID = 0;
|
|
}
|
|
|
|
public static TestSuite suite() {
|
|
TestSuite suite = new TestSuite();
|
|
suite.addTestSuite(SynchronizedNavigableMapTest.class);
|
|
suite.addTest(
|
|
NavigableMapTestSuiteBuilder.using(
|
|
new TestStringSortedMapGenerator() {
|
|
private final Object mutex = new Integer(1);
|
|
|
|
@Override
|
|
protected SortedMap<String, String> create(Entry<String, String>[] entries) {
|
|
NavigableMap<String, String> innermost = new SafeTreeMap<>();
|
|
for (Entry<String, String> entry : entries) {
|
|
innermost.put(entry.getKey(), entry.getValue());
|
|
}
|
|
TestMap<String, String> inner = new TestMap<>(innermost, mutex);
|
|
NavigableMap<String, String> outer = Synchronized.navigableMap(inner, mutex);
|
|
return outer;
|
|
}
|
|
})
|
|
.named("Maps.synchronizedNavigableMap[SafeTreeMap]")
|
|
.withFeatures(
|
|
CollectionSize.ANY,
|
|
CollectionFeature.KNOWN_ORDER,
|
|
MapFeature.GENERAL_PURPOSE,
|
|
MapFeature.ALLOWS_NULL_VALUES,
|
|
CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
|
|
.createTestSuite());
|
|
|
|
return suite;
|
|
}
|
|
|
|
public void testComparator() {
|
|
create().comparator();
|
|
}
|
|
|
|
public void testCeilingEntry() {
|
|
create().ceilingEntry("a");
|
|
}
|
|
|
|
public void testCeilingKey() {
|
|
create().ceilingKey("a");
|
|
}
|
|
|
|
public void testDescendingKeySet() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableSet<String> descendingKeySet = map.descendingKeySet();
|
|
assertTrue(descendingKeySet instanceof SynchronizedNavigableSet);
|
|
assertSame(mutex, ((SynchronizedNavigableSet<String>) descendingKeySet).mutex);
|
|
}
|
|
|
|
public void testDescendingMap() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableMap<String, Integer> descendingMap = map.descendingMap();
|
|
assertTrue(descendingMap instanceof SynchronizedNavigableMap);
|
|
assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) descendingMap).mutex);
|
|
}
|
|
|
|
public void testFirstEntry() {
|
|
create().firstEntry();
|
|
}
|
|
|
|
public void testFirstKey() {
|
|
NavigableMap<String, Integer> map = create();
|
|
map.put("a", 1);
|
|
map.firstKey();
|
|
}
|
|
|
|
public void testFloorEntry() {
|
|
create().floorEntry("a");
|
|
}
|
|
|
|
public void testFloorKey() {
|
|
create().floorKey("a");
|
|
}
|
|
|
|
public void testHeadMap_K() {
|
|
NavigableMap<String, Integer> map = create();
|
|
SortedMap<String, Integer> headMap = map.headMap("a");
|
|
assertTrue(headMap instanceof SynchronizedSortedMap);
|
|
assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) headMap).mutex);
|
|
}
|
|
|
|
public void testHeadMap_K_B() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableMap<String, Integer> headMap = map.headMap("a", true);
|
|
assertTrue(headMap instanceof SynchronizedNavigableMap);
|
|
assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) headMap).mutex);
|
|
}
|
|
|
|
public void testHigherEntry() {
|
|
create().higherEntry("a");
|
|
}
|
|
|
|
public void testHigherKey() {
|
|
create().higherKey("a");
|
|
}
|
|
|
|
public void testLastEntry() {
|
|
create().lastEntry();
|
|
}
|
|
|
|
public void testLastKey() {
|
|
NavigableMap<String, Integer> map = create();
|
|
map.put("a", 1);
|
|
map.lastKey();
|
|
}
|
|
|
|
public void testLowerEntry() {
|
|
create().lowerEntry("a");
|
|
}
|
|
|
|
public void testLowerKey() {
|
|
create().lowerKey("a");
|
|
}
|
|
|
|
public void testNavigableKeySet() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableSet<String> navigableKeySet = map.navigableKeySet();
|
|
assertTrue(navigableKeySet instanceof SynchronizedNavigableSet);
|
|
assertSame(mutex, ((SynchronizedNavigableSet<String>) navigableKeySet).mutex);
|
|
}
|
|
|
|
public void testPollFirstEntry() {
|
|
create().pollFirstEntry();
|
|
}
|
|
|
|
public void testPollLastEntry() {
|
|
create().pollLastEntry();
|
|
}
|
|
|
|
public void testSubMap_K_K() {
|
|
NavigableMap<String, Integer> map = create();
|
|
SortedMap<String, Integer> subMap = map.subMap("a", "b");
|
|
assertTrue(subMap instanceof SynchronizedSortedMap);
|
|
assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
|
|
}
|
|
|
|
public void testSubMap_K_B_K_B() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableMap<String, Integer> subMap = map.subMap("a", true, "b", false);
|
|
assertTrue(subMap instanceof SynchronizedNavigableMap);
|
|
assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
|
|
}
|
|
|
|
public void testTailMap_K() {
|
|
NavigableMap<String, Integer> map = create();
|
|
SortedMap<String, Integer> subMap = map.tailMap("a");
|
|
assertTrue(subMap instanceof SynchronizedSortedMap);
|
|
assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
|
|
}
|
|
|
|
public void testTailMap_K_B() {
|
|
NavigableMap<String, Integer> map = create();
|
|
NavigableMap<String, Integer> subMap = map.tailMap("a", true);
|
|
assertTrue(subMap instanceof SynchronizedNavigableMap);
|
|
assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
|
|
}
|
|
|
|
@Override
|
|
public void testSerialization() {
|
|
SerializableTester.reserializeAndAssert(create());
|
|
}
|
|
}
|