[java-support] branch maint-7 updated: JSPT-82: Add method(s) to LockableClassToInstanceMultiMap which lock ...
Brent Putman
putmanb at georgetown.edu
Tue Oct 2 19:40:33 EDT 2018
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch maint-7
in repository java-support.
View the commit online:
http://git.shibboleth.net/view/?p=java-support.git;a=commit;h=72e5641796429fefb24311290c2bebf1ea3a45d3
The following commit(s) were added to refs/heads/maint-7 by this push:
new 72e5641 JSPT-82: Add method(s) to LockableClassToInstanceMultiMap which lock ...
72e5641 is described below
commit 72e5641796429fefb24311290c2bebf1ea3a45d3
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Tue Oct 2 19:40:32 2018 -0400
JSPT-82: Add method(s) to LockableClassToInstanceMultiMap which lock ...
---
.../LockableClassToInstanceMultiMap.java | 249 ++++++++++++++-
.../LockableClassToInstanceMultiMapTest.java | 351 +++++++++++++++++++++
2 files changed, 597 insertions(+), 3 deletions(-)
diff --git a/src/main/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMap.java b/src/main/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMap.java
index 54935af..628da0f 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMap.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMap.java
@@ -17,16 +17,31 @@
package net.shibboleth.utilities.java.support.collection;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.Live;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
/**
* A specialization of {@link ClassToInstanceMultiMap} which exposes a map-specific
- * instance of {@link ReadWriteLock}. Callers of the map are responsible for explicitly locking
- * (and unlocking) for reading and/or writing, based on application use cases and concurrency
- * requirements.
+ * instance of {@link ReadWriteLock}.
+ *
+ * <p>
+ * Callers of the map are generally responsible for explicitly locking
+ * and unlocking for reading and writing, based on application use cases and concurrency
+ * requirements. For simple single-statement atomic operations, convenience
+ * methods are supplied which execute the corresponding superclass operation under the
+ * read or write lock, as appropriate.
+ * </p>
*
* @param <B> a bound for the types of values in the map
*/
@@ -65,5 +80,233 @@ public class LockableClassToInstanceMultiMap<B> extends ClassToInstanceMultiMap<
@Nonnull public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ */
+ public void clearWithLock() {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ clear();
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @param key key to check for in the map
+ *
+ * @return true if the map contains a mapping for the specified key
+ */
+ public boolean containsKeyWithLock(@Nullable final Class<?> key) {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return containsKey(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @param value value to check for in this map
+ *
+ * @return true if the map contains a mapping to the specified value
+ */
+ public boolean containsValueWithLock(@Nonnull final B value) {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return containsValue(value);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @param <T> type identifier
+ * @param type map key
+ *
+ * @return instances mapped to the given type or an empty list
+ */
+ @Nonnull @NonnullElements @Unmodifiable @Live public <T> List<T> getWithLock(@Nullable final Class<T> type) {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return get(type);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @return true if this map contains no entries, false otherwise
+ */
+ public boolean isEmptyWithLock() {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return isEmpty();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @return set of keys contained in this map
+ */
+ @Nonnull @NonnullElements @Unmodifiable @Live public Set<Class<?>> keysWithLock() {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return keys();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param value value to be stored in the map
+ */
+ public void putWithLock(@Nonnull final B value) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ put(value);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param map map containing values to be added
+ */
+ public void putAllWithLock(@Nullable @NonnullElements final ClassToInstanceMultiMap<? extends B> map) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ putAll(map);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param newValues values to be added
+ */
+ public void putAllWithLock(@Nullable @NonnullElements final Iterable<? extends B> newValues) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ putAll(newValues);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param value the value to remove
+ */
+ public void removeWithLock(@Nonnull final B value) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ remove(value);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param type the type of values to remove
+ */
+ public void removeWithLock(@Nullable final Class<?> type) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ remove(type);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param map the map containing the values to remove
+ */
+ public void removeAllWithLock(@Nullable @NonnullElements final ClassToInstanceMultiMap<? extends B> map) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ removeAll(map);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a write lock.
+ *
+ * @param removeValues the values to remove
+ */
+ public void removeAllWithLock(@Nullable @NonnullElements final Iterable<? extends B> removeValues) {
+ final Lock writeLock = getReadWriteLock().writeLock();
+ try {
+ writeLock.lock();
+ removeAll(removeValues);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ /**
+ * Convenience method which executes the like-named method from superclass {@link ClassToInstanceMultiMap}
+ * under a read lock.
+ *
+ * @return collection of values currently present in the map
+ */
+ @Nonnull @NonnullElements @Unmodifiable @Live public Collection<? extends B> valuesWithLock() {
+ final Lock readLock = getReadWriteLock().readLock();
+ try {
+ readLock.lock();
+ return values();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/test/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMapTest.java b/src/test/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMapTest.java
new file mode 100644
index 0000000..476d085
--- /dev/null
+++ b/src/test/java/net/shibboleth/utilities/java/support/collection/LockableClassToInstanceMultiMapTest.java
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.utilities.java.support.collection;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+import org.joda.time.Chronology;
+import org.joda.time.DateTime;
+import org.joda.time.Instant;
+import org.joda.time.ReadableDateTime;
+import org.joda.time.ReadableInstant;
+import org.joda.time.base.AbstractDateTime;
+import org.joda.time.base.AbstractInstant;
+import org.joda.time.base.BaseDateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/** Unit test for {@link LockableClassToInstanceMultiMap}. */
+public class LockableClassToInstanceMultiMapTest {
+
+ @Test public void testClearIsEmpty() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>();
+
+ map.clear();
+ Assert.assertTrue(map.isEmptyWithLock());
+
+ map.put(new Object());
+ Assert.assertFalse(map.isEmptyWithLock());
+
+ map.clear();
+ Assert.assertTrue(map.isEmptyWithLock());
+ }
+
+ @Test public void testKeysAndContainsKey() {
+ LockableClassToInstanceMultiMap<AbstractInstant> map = new LockableClassToInstanceMultiMap<>();
+ populate(map);
+ Assert.assertEquals(map.keysWithLock().size(), 2);
+ Assert.assertFalse(map.containsKeyWithLock(null));
+ Assert.assertFalse(map.containsKeyWithLock(Chronology.class));
+ Assert.assertFalse(map.containsKeyWithLock(AbstractInstant.class));
+ Assert.assertFalse(map.containsKeyWithLock(AbstractDateTime.class));
+ Assert.assertFalse(map.containsKeyWithLock(BaseDateTime.class));
+ Assert.assertTrue(map.containsKeyWithLock(DateTime.class));
+ Assert.assertFalse(map.containsKeyWithLock(Comparable.class));
+ Assert.assertFalse(map.containsKeyWithLock(ReadableDateTime.class));
+ Assert.assertFalse(map.containsKeyWithLock(ReadableInstant.class));
+ Assert.assertFalse(map.containsKeyWithLock(Serializable.class));
+ Assert.assertTrue(map.containsKeyWithLock(Instant.class));
+
+ map = new LockableClassToInstanceMultiMap<>(true);
+ populate(map);
+ Assert.assertEquals(map.keysWithLock().size(), 9);
+ Assert.assertFalse(map.containsKeyWithLock(null));
+ Assert.assertFalse(map.containsKeyWithLock(Chronology.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractInstant.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractDateTime.class));
+ Assert.assertTrue(map.containsKeyWithLock(BaseDateTime.class));
+ Assert.assertTrue(map.containsKeyWithLock(DateTime.class));
+ Assert.assertTrue(map.containsKeyWithLock(Comparable.class));
+ Assert.assertTrue(map.containsKeyWithLock(ReadableDateTime.class));
+ Assert.assertTrue(map.containsKeyWithLock(ReadableInstant.class));
+ Assert.assertTrue(map.containsKeyWithLock(Serializable.class));
+ Assert.assertTrue(map.containsKeyWithLock(Instant.class));
+ }
+
+ @Test public void testValuesAndContainsValues() {
+ LockableClassToInstanceMultiMap<AbstractInstant> map = new LockableClassToInstanceMultiMap<>();
+
+ DateTime now = new DateTime();
+ map.putWithLock(now);
+
+ DateTime now100 = now.plus(100);
+ map.putWithLock(now100);
+
+ Instant instant = new Instant();
+ map.putWithLock(instant);
+
+ Assert.assertEquals(map.valuesWithLock().size(), 3);
+ Assert.assertFalse(map.containsValueWithLock(null));
+ Assert.assertFalse(map.containsValueWithLock(now.minus(100)));
+ Assert.assertFalse(map.containsValueWithLock(instant.minus(100)));
+ Assert.assertTrue(map.containsValueWithLock(instant));
+ Assert.assertTrue(map.containsValueWithLock(now));
+ Assert.assertTrue(map.containsValueWithLock(now100));
+ }
+
+ @Test public void testEquals() {
+ final LockableClassToInstanceMultiMap<AbstractInstant> map = new LockableClassToInstanceMultiMap<>();
+ final LockableClassToInstanceMultiMap<AbstractInstant> map2 = new LockableClassToInstanceMultiMap<>();
+ final LockableClassToInstanceMultiMap<AbstractInstant> map3 = new LockableClassToInstanceMultiMap<>();
+
+ final DateTime now = new DateTime();
+ map.putWithLock(now);
+ map2.putWithLock(now);
+ map3.putWithLock(now);
+
+ final DateTime now100 = now.plus(100);
+ map.putWithLock(now100);
+ map2.putWithLock(now100);
+ map3.putWithLock(now100);
+
+ final Instant instant = new Instant();
+ map.putWithLock(instant);
+ map2.putWithLock(instant);
+
+ Assert.assertTrue(map.equals(map2));
+ Assert.assertFalse(map.equals(map3));
+
+ Assert.assertEquals(map.hashCode(), map2.hashCode());
+ Assert.assertNotEquals(map.hashCode(), map3.hashCode());
+
+ }
+
+ @Test public void testGet() {
+ LockableClassToInstanceMultiMap<AbstractInstant> map = new LockableClassToInstanceMultiMap<>();
+ populate(map);
+
+ List<?> values = map.getWithLock(null);
+ Assert.assertEquals(values.size(), 0);
+
+ values = map.getWithLock(DateTime.class);
+ Assert.assertEquals(values.size(), 2);
+
+ values = map.getWithLock(Instant.class);
+ Assert.assertEquals(values.size(), 1);
+ }
+
+ @Test public void testNoIndexedDuplicateValues() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>(true);
+
+ map.putWithLock(new FooBarImpl());
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 1);
+ }
+
+ @Test public void testDuplicateInsertions() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>(true);
+
+ FooBarImpl fb = new FooBarImpl();
+
+ map.putWithLock(fb);
+ map.putWithLock(fb);
+
+ Assert.assertEquals(map.valuesWithLock().size(), 1);
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 1);
+ }
+
+ @Test public void testRemoveValue() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>(true);
+
+ FooBarImpl fb = new FooBarImpl();
+ FooImpl f = new FooImpl();
+
+ map.putWithLock(fb); // This is what we'll remove.
+ map.putWithLock(f); // This is canary to test that its indexes don't disappear.
+
+ Assert.assertTrue(map.containsValueWithLock(fb));
+ Assert.assertTrue(map.containsValueWithLock(f));
+
+ Assert.assertTrue(map.containsKeyWithLock(Foo.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFoo.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 2);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 2);
+ Assert.assertEquals(map.getWithLock(FooImpl.class).size(), 1);
+
+ Assert.assertTrue(map.containsKeyWithLock(Bar.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFooBar.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooBarImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 1);
+
+ map.remove(fb);
+
+ Assert.assertFalse(map.containsValueWithLock(fb));
+ Assert.assertTrue(map.containsValueWithLock(f));
+
+ Assert.assertTrue(map.containsKeyWithLock(Foo.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFoo.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooImpl.class).size(), 1);
+
+ Assert.assertFalse(map.containsKeyWithLock(Bar.class));
+ Assert.assertFalse(map.containsKeyWithLock(AbstractFooBar.class));
+ Assert.assertFalse(map.containsKeyWithLock(FooBarImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 0);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 0);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 0);
+ }
+
+ @Test public void testRemoveByType() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>(true);
+
+ FooBarImpl fb = new FooBarImpl();
+ FooImpl f = new FooImpl();
+
+ map.putWithLock(fb);
+ map.putWithLock(f);
+
+ Assert.assertTrue(map.containsValueWithLock(fb));
+ Assert.assertTrue(map.containsValueWithLock(f));
+
+ Assert.assertTrue(map.containsKeyWithLock(Foo.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFoo.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 2);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 2);
+ Assert.assertEquals(map.getWithLock(FooImpl.class).size(), 1);
+
+ Assert.assertTrue(map.containsKeyWithLock(Bar.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFooBar.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooBarImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 1);
+
+ map.removeWithLock(Bar.class);
+
+ Assert.assertFalse(map.containsValueWithLock(fb));
+ Assert.assertTrue(map.containsValueWithLock(f));
+
+ Assert.assertTrue(map.containsKeyWithLock(Foo.class));
+ Assert.assertTrue(map.containsKeyWithLock(AbstractFoo.class));
+ Assert.assertTrue(map.containsKeyWithLock(FooImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(AbstractFoo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(FooImpl.class).size(), 1);
+
+ Assert.assertFalse(map.containsKeyWithLock(Bar.class));
+ Assert.assertFalse(map.containsKeyWithLock(AbstractFooBar.class));
+ Assert.assertFalse(map.containsKeyWithLock(FooBarImpl.class));
+
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 0);
+ Assert.assertEquals(map.getWithLock(AbstractFooBar.class).size(), 0);
+ Assert.assertEquals(map.getWithLock(FooBarImpl.class).size(), 0);
+
+ }
+
+ @Test public void testRemoveAll() {
+ LockableClassToInstanceMultiMap<Object> map = new LockableClassToInstanceMultiMap<>(true);
+
+ FooImpl f1 = new FooImpl();
+ FooImpl f2 = new FooImpl();
+ FooImpl f3 = new FooImpl();
+
+ FooBarImpl fb1 = new FooBarImpl();
+ FooBarImpl fb2 = new FooBarImpl();
+ FooBarImpl fb3 = new FooBarImpl();
+
+ map.putWithLock(f1);
+ map.putWithLock(f2);
+ map.putWithLock(f3);
+ map.putWithLock(fb1);
+ map.putWithLock(fb2);
+ map.putWithLock(fb3);
+
+ Assert.assertEquals(map.valuesWithLock().size(), 6);
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 6);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 3);
+
+ map.removeAllWithLock(Arrays.asList(f1, f2, fb1));
+
+ Assert.assertEquals(map.valuesWithLock().size(), 3);
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 3);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 2);
+
+ map.removeAllWithLock(Arrays.asList(fb2, fb3));
+
+ Assert.assertEquals(map.valuesWithLock().size(), 1);
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 1);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 0);
+ Assert.assertFalse(map.containsKeyWithLock(Bar.class));
+
+ map.removeAllWithLock(Arrays.asList(f3));
+
+ Assert.assertEquals(map.valuesWithLock().size(), 0);
+ Assert.assertTrue(map.isEmptyWithLock());
+ Assert.assertEquals(map.getWithLock(Foo.class).size(), 0);
+ Assert.assertEquals(map.getWithLock(Bar.class).size(), 0);
+ Assert.assertFalse(map.containsKeyWithLock(Foo.class));
+ Assert.assertFalse(map.containsKeyWithLock(Bar.class));
+ }
+
+ protected void populate(LockableClassToInstanceMultiMap<AbstractInstant> map) {
+ DateTime now = new DateTime();
+ map.putWithLock(now);
+
+ DateTime now100 = now.plus(100);
+ map.putWithLock(now100);
+
+ Instant instant = new Instant();
+ map.putWithLock(instant);
+ }
+
+ // Test classes and interfaces
+
+ public interface Foo {
+ };
+
+ public interface Bar extends Foo {
+ };
+
+ public abstract class AbstractFoo implements Foo {
+ };
+
+ public class FooImpl extends AbstractFoo {
+ };
+
+ public abstract class AbstractFooBar extends AbstractFoo implements Bar {
+ };
+
+ public class FooBarImpl extends AbstractFooBar {
+ };
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list