1 package net.sf.ehcache.terracotta;
2
3 import net.sf.ehcache.util.RetryAssert;
4 import org.hamcrest.CoreMatchers;
5 import org.hamcrest.core.Is;
6 import org.junit.Test;
7
8 import java.util.concurrent.Callable;
9 import java.util.concurrent.ConcurrentHashMap;
10 import java.util.concurrent.ConcurrentMap;
11 import java.util.concurrent.atomic.AtomicLong;
12
13 import static java.util.concurrent.TimeUnit.SECONDS;
14 import static org.hamcrest.CoreMatchers.equalTo;
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.junit.Assert.assertThat;
17
18 /***
19 * @author Alex Snaps
20 */
21 public class WeakIdentityConcurrentMapTest {
22
23 private Long someKey = 1024L;
24
25 @Test
26 public void testReturnsValueAndCleanUpsProperly() {
27
28 final ConcurrentMap<String, AtomicLong> cleanedUpValues = new ConcurrentHashMap<String, AtomicLong>();
29
30 final WeakIdentityConcurrentMap<Long, String> map = new WeakIdentityConcurrentMap<Long, String>(new WeakIdentityConcurrentMap.CleanUpTask<String>() {
31 public void cleanUp(final String value) {
32 final AtomicLong previous = cleanedUpValues.putIfAbsent(value, new AtomicLong(1));
33 if(previous != null) {
34 previous.incrementAndGet();
35 }
36 }
37 });
38
39 final String value1 = "someValue for 1";
40 final String value2 = "someValue for 1024";
41 assertThat(map.putIfAbsent(1L, value1), CoreMatchers.<Object>nullValue());
42 assertThat(map.putIfAbsent(someKey, value2), CoreMatchers.<Object>nullValue());
43 assertThat(map.putIfAbsent(someKey, value2), equalTo(value2));
44 assertThat(map.get(1L), equalTo(value1));
45 assertThat(map.get(someKey), equalTo(value2));
46 someKey = null;
47
48 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
49 public Integer call() throws Exception {
50 int i = 0;
51 while (i++ < 50) {
52 System.gc();
53 assertThat(map.get(someKey), CoreMatchers.<Object>nullValue());
54 }
55 return cleanedUpValues.size();
56 }
57 }, Is.is(1));
58
59 assertThat(cleanedUpValues.get(value2), CoreMatchers.<Object>notNullValue());
60 assertThat(cleanedUpValues.get(value2).get(), is(1L));
61 }
62 }