1 16 17 package com.google.inject.util; 18 19 import static com.google.inject.util.ReferenceType.SOFT; 20 import static com.google.inject.util.ReferenceType.STRONG; 21 import static com.google.inject.util.ReferenceType.WEAK; 22 23 import junit.framework.TestCase; 24 25 import java.util.concurrent.CountDownLatch ; 26 27 30 public class ReferenceCacheTest extends TestCase { 31 32 public void testRuntimeException() { 33 class CreationException extends RuntimeException {} 34 try { 35 new ReferenceCache() { 36 protected Object create(Object key) { 37 throw new CreationException(); 38 } 39 }.get(new Object ()); 40 fail(); 41 } catch (CreationException e) { } 42 } 43 44 public void testApply() { 45 ReferenceMap<String , Integer > cache = ReferenceCache.of( 46 WEAK, WEAK, new SomeFunction()); 47 assertEquals(Integer.valueOf(1), cache.get("foo")); 48 assertEquals(Integer.valueOf(1), cache.get("foo")); 49 assertEquals(Integer.valueOf(2), cache.get("bar")); 50 assertEquals(Integer.valueOf(1), cache.get("foo")); 51 assertEquals(Integer.valueOf(3), cache.get("baz")); 52 } 53 54 public void testSleepConcurrency() throws InterruptedException { 55 ReferenceMap<String , Integer > cache = ReferenceCache.of( 56 WEAK, WEAK, new SleepFunction()); 57 assertConcurrency(cache, false); 58 } 59 60 public void testBusyConcurrency() throws InterruptedException { 61 ReferenceMap<String , Integer > cache = ReferenceCache.of( 62 WEAK, WEAK, new BusyFunction()); 63 assertConcurrency(cache, false); 64 } 65 66 public void testFastConcurrency() throws InterruptedException { 67 ReferenceMap<String , Integer > cache = ReferenceCache.of( 68 WEAK, WEAK, new SomeFunction()); 69 assertConcurrency(cache, false); 70 } 71 72 public void testSleepCanonical() throws InterruptedException { 73 ReferenceMap<String , Integer > cache = ReferenceCache.of( 74 STRONG, SOFT, new SleepFunction()); 75 assertConcurrency(cache, true); 76 } 77 78 public void testBusyCanonical() throws InterruptedException { 79 ReferenceMap<String , Integer > cache = ReferenceCache.of( 80 STRONG, SOFT, new BusyFunction()); 81 assertConcurrency(cache, true); 82 } 83 84 public void testFastCanonical() throws InterruptedException { 85 ReferenceMap<String , Integer > cache = ReferenceCache.of( 86 STRONG, SOFT, new SomeFunction()); 87 assertConcurrency(cache, true); 88 } 89 90 private static void assertConcurrency( 91 final ReferenceMap<String , Integer > cache, 92 final boolean simulateAliasing) throws InterruptedException { 93 final int n = 20; 94 final CountDownLatch startSignal = new CountDownLatch (1); 95 final CountDownLatch doneSignal = new CountDownLatch (n); 96 for (int i = 0; i < n; i++) { 97 new Thread () { 98 public void run() { 99 try { 100 startSignal.await(); 101 for (int j = 0; j < n; j++) { 102 cache.get(simulateAliasing ? new String ("foo") : "foo"); 103 } 104 doneSignal.countDown(); 105 } catch (InterruptedException ignored) {} 106 } 107 }.start(); 108 } 109 110 startSignal.countDown(); 111 doneSignal.await(); 112 assertEquals(Integer.valueOf(1), cache.get("foo")); 113 assertEquals(Integer.valueOf(2), cache.get("bar")); 114 } 115 116 private static class SomeFunction implements Function<String , Integer > { 117 private int numApplies = 0; 118 public Integer apply(String s) { 119 return ++numApplies; 120 } 121 } 122 123 private static class SleepFunction implements Function<String , Integer > { 124 private int numApplies = 0; 125 public Integer apply(String s) { 126 try { 127 Thread.sleep(100); 128 } catch (InterruptedException e) { 129 throw new RuntimeException (e); 130 } 131 return ++numApplies; 132 } 133 } 134 135 private static class BusyFunction implements Function<String , Integer > { 136 private int numApplies = 0; 137 public Integer apply(String s) { 138 for (int i = 0; i < 1000; i++) { 139 Math.sqrt(i); 140 } 141 return ++numApplies; 142 } 143 } 144 } 145 | Popular Tags |