Added SupplierCache (so it may be leveraged by StreamARN work). (#1096)
This commit is contained in:
parent
5e7d4788ec
commit
fc52976c3d
2 changed files with 92 additions and 0 deletions
|
|
@ -0,0 +1,36 @@
|
||||||
|
package software.amazon.kinesis.common;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches results from a {@link Supplier}. Caching is especially useful when
|
||||||
|
* {@link Supplier#get()} is an expensive call that produces static results.
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SupplierCache<T> {
|
||||||
|
|
||||||
|
private final Supplier<T> supplier;
|
||||||
|
|
||||||
|
private volatile T result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cached result. If the cache is null, the supplier will be
|
||||||
|
* invoked to populate the cache.
|
||||||
|
*
|
||||||
|
* @return cached result which may be null
|
||||||
|
*/
|
||||||
|
public T get() {
|
||||||
|
if (result == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
// double-check lock
|
||||||
|
if (result == null) {
|
||||||
|
result = supplier.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package software.amazon.kinesis.common;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class SupplierCacheTest {
|
||||||
|
|
||||||
|
private static final Object DUMMY_RESULT = SupplierCacheTest.class;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Supplier<Object> mockSupplier;
|
||||||
|
|
||||||
|
private SupplierCache<Object> cache;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
cache = new SupplierCache<>(mockSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCache() {
|
||||||
|
when(mockSupplier.get()).thenReturn(DUMMY_RESULT);
|
||||||
|
|
||||||
|
final Object result1 = cache.get();
|
||||||
|
final Object result2 = cache.get();
|
||||||
|
|
||||||
|
assertEquals(DUMMY_RESULT, result1);
|
||||||
|
assertSame(result1, result2);
|
||||||
|
verify(mockSupplier).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCacheWithNullResult() {
|
||||||
|
when(mockSupplier.get()).thenReturn(null).thenReturn(DUMMY_RESULT);
|
||||||
|
|
||||||
|
final Object result1 = cache.get();
|
||||||
|
final Object result2 = cache.get();
|
||||||
|
|
||||||
|
assertNull(result1);
|
||||||
|
assertEquals(DUMMY_RESULT, result2);
|
||||||
|
verify(mockSupplier, times(2)).get();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue