1 package com.atlassian.cache.memory;
2
3 import java.util.SortedMap;
4
5 import javax.annotation.Nonnull;
6 import javax.annotation.Nullable;
7
8 import com.atlassian.cache.CacheException;
9 import com.atlassian.cache.CacheSettings;
10 import com.atlassian.cache.CacheStatisticsKey;
11 import com.atlassian.cache.CachedReference;
12 import com.atlassian.cache.CachedReferenceListener;
13 import com.atlassian.cache.impl.CachedReferenceListenerSupport;
14 import com.atlassian.cache.impl.DefaultCachedReferenceListenerSupport;
15 import com.atlassian.cache.impl.ReferenceKey;
16 import com.atlassian.util.concurrent.Supplier;
17
18 import com.google.common.cache.LoadingCache;
19 import com.google.common.cache.RemovalListener;
20 import com.google.common.cache.RemovalNotification;
21 import com.google.common.util.concurrent.UncheckedExecutionException;
22
23 import static com.atlassian.cache.memory.DelegatingCacheStatistics.toStatistics;
24
25
26
27
28
29
30 class DelegatingCachedReference<V> extends ManagedCacheSupport implements CachedReference<V>
31 {
32 private final LoadingCache<ReferenceKey, V> internalCache;
33 private final CachedReferenceListenerSupport<V> listenerSupport;
34
35 private DelegatingCachedReference(final LoadingCache<ReferenceKey, V> internalCache,
36 String name, CacheSettings settings)
37 {
38 super(name, settings);
39 this.internalCache = internalCache;
40
41 this.listenerSupport = new DefaultCachedReferenceListenerSupport<V>();
42 }
43
44 static <V> DelegatingCachedReference<V> create(final LoadingCache<ReferenceKey, V> internalCache,
45 String name, CacheSettings settings)
46 {
47 return new DelegatingCachedReference<V>(internalCache, name, settings);
48 }
49
50 @Nonnull
51 @Override
52 public V get()
53 {
54 try
55 {
56 return internalCache.get(ReferenceKey.KEY);
57 }
58 catch (UncheckedExecutionException e)
59 {
60 throw new CacheException(e.getCause());
61 }
62 catch (Exception e)
63 {
64 throw new CacheException(e);
65 }
66 }
67
68 @Override
69 public void reset()
70 {
71 try
72 {
73 internalCache.invalidate(ReferenceKey.KEY);
74 }
75 catch (Exception e)
76 {
77 throw new CacheException(e);
78 }
79 }
80
81 @Override
82 public void clear()
83 {
84 reset();
85 }
86
87 @Override
88 public boolean equals(@Nullable final Object other)
89 {
90 if (other instanceof DelegatingCachedReference)
91 {
92 DelegatingCachedReference<?> otherDelegatingReference = (DelegatingCachedReference<?>) other;
93 if (internalCache.equals(otherDelegatingReference.internalCache))
94 {
95 return true;
96 }
97 }
98 return false;
99 }
100
101 @Override
102 public int hashCode()
103 {
104 return 3 + internalCache.hashCode();
105 }
106
107 @Nonnull
108 @Override
109 public SortedMap<CacheStatisticsKey,Supplier<Long>> getStatistics()
110 {
111 return toStatistics(internalCache);
112 }
113
114 @Override
115 public void addListener(@Nonnull CachedReferenceListener<V> listener, boolean includeValues)
116 {
117 listenerSupport.add(listener, includeValues);
118 }
119
120 @Override
121 public void removeListener(@Nonnull CachedReferenceListener<V> listener)
122 {
123 listenerSupport.remove(listener);
124 }
125
126 protected static class DelegatingReferenceRemovalListener<V> implements RemovalListener<ReferenceKey, V>
127 {
128 private DelegatingCachedReference<V> cachedReference;
129
130 protected void onSupply(V value)
131 {
132 cachedReference.listenerSupport.notifySet(value);
133 }
134
135 @Override
136 public void onRemoval(RemovalNotification<ReferenceKey, V> notification)
137 {
138 switch (notification.getCause())
139 {
140 case COLLECTED:
141 case EXPIRED:
142 cachedReference.listenerSupport.notifyEvict(notification.getValue());
143 break;
144 case EXPLICIT:
145 cachedReference.listenerSupport.notifyReset(notification.getValue());
146 break;
147 case REPLACED:
148 V value = cachedReference.internalCache.getIfPresent(ReferenceKey.KEY);
149 cachedReference.listenerSupport.notifySet(value);
150 break;
151 }
152 }
153
154 public void setCachedReference(DelegatingCachedReference<V> cachedReference)
155 {
156 this.cachedReference = cachedReference;
157 }
158 }
159 }