1 package com.atlassian.cache.impl;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.List;
6 import java.util.concurrent.ConcurrentHashMap;
7 import java.util.concurrent.ConcurrentMap;
8
9 import javax.annotation.Nonnull;
10 import javax.annotation.Nullable;
11 import javax.annotation.ParametersAreNonnullByDefault;
12
13 import com.atlassian.cache.Cache;
14 import com.atlassian.cache.CacheLoader;
15 import com.atlassian.cache.CacheManager;
16 import com.atlassian.cache.CacheSettings;
17 import com.atlassian.cache.CacheSettingsBuilder;
18 import com.atlassian.cache.CacheSettingsDefaultsProvider;
19 import com.atlassian.cache.CachedReference;
20 import com.atlassian.cache.ManagedCache;
21 import com.atlassian.util.concurrent.Function;
22 import com.atlassian.util.concurrent.ManagedLock;
23 import com.atlassian.util.concurrent.ManagedLocks;
24 import com.atlassian.util.concurrent.Supplier;
25
26 import static com.google.common.base.Preconditions.checkNotNull;
27
28
29
30
31
32
33 @ParametersAreNonnullByDefault
34 public abstract class AbstractCacheManager implements CacheManager
35 {
36
37
38
39
40
41
42 protected final ConcurrentMap<String, Supplier<ManagedCache>> caches = new ConcurrentHashMap<String, Supplier<ManagedCache>>();
43
44
45 protected final Function<String, ManagedLock> cacheCreationLocks = ManagedLocks.weakManagedLockFactory();
46
47 protected final @Nullable CacheSettingsDefaultsProvider cacheSettingsDefaultsProvider;
48
49 protected AbstractCacheManager(@Nullable CacheSettingsDefaultsProvider cacheSettingsDefaultsProvider)
50 {
51 this.cacheSettingsDefaultsProvider = cacheSettingsDefaultsProvider;
52 }
53
54 @Nonnull
55 @SuppressWarnings("unchecked")
56 @Override
57 public Collection<Cache<?, ?>> getCaches()
58 {
59 List<Cache<?, ?>> managedCaches = new ArrayList<Cache<?, ?>>(64);
60
61 for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
62 {
63 final ManagedCache managedCache = cacheRef.get();
64
65 if (managedCache instanceof Cache)
66 {
67 managedCaches.add((Cache<?,?>)managedCache);
68 }
69 }
70 return managedCaches;
71 }
72
73 @Nonnull
74 @Override
75 public Collection<ManagedCache> getManagedCaches()
76 {
77 List<ManagedCache> managedCaches = new ArrayList<ManagedCache>(64);
78 for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
79 {
80 final ManagedCache managedCache = cacheRef.get();
81 if (managedCache != null)
82 {
83 managedCaches.add(managedCache);
84 }
85 }
86 return managedCaches;
87 }
88
89 @Nullable
90 @Override
91 public ManagedCache getManagedCache(@Nonnull String name)
92 {
93 final Supplier<ManagedCache> cacheRef = caches.get(name);
94 return (null == cacheRef) ? null : cacheRef.get();
95 }
96
97 @Override
98 public void flushCaches()
99 {
100 for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
101 {
102 final ManagedCache managedCache = cacheRef.get();
103 if (managedCache != null && managedCache.isFlushable())
104 {
105 managedCache.clear();
106 }
107 }
108 }
109
110 @Nonnull
111 @Override
112 public <K, V> Cache<K, V> getCache(@Nonnull final String name)
113 {
114 return getCache(name, null);
115 }
116
117 @Nonnull
118 @Override
119 public <K, V> Cache<K, V> getCache(@Nonnull Class<?> owningClass, @Nonnull String name)
120 {
121 return getCache(cacheName(owningClass, name));
122 }
123
124 @Nonnull
125 @Override
126 public <K, V> Cache<K, V> getCache(@Nonnull final String name, @Nonnull final Class<K> keyType, @Nonnull final Class<V> valueType)
127 {
128 return getCache(name);
129 }
130
131 @Nonnull
132 @Override
133 public <K, V> Cache<K, V> getCache(@Nonnull String name, @Nullable CacheLoader<K, V> loader)
134 {
135 return getCache(name, loader, new CacheSettingsBuilder().build());
136 }
137
138 @Nonnull
139 @Override
140 public <V> CachedReference<V> getCachedReference(@Nonnull String name, @Nonnull com.atlassian.cache.Supplier<V> supplier)
141 {
142 return getCachedReference(name, supplier, new CacheSettingsBuilder().build());
143 }
144
145 @Nonnull
146 @Override
147 public <V> CachedReference<V> getCachedReference(@Nonnull Class<?> owningClass,
148 @Nonnull String name,
149 @Nonnull com.atlassian.cache.Supplier<V> supplier)
150 {
151 return getCachedReference(owningClass, name, supplier, new CacheSettingsBuilder().build());
152 }
153
154 @Nonnull
155 @Override
156 public <V> CachedReference<V> getCachedReference(@Nonnull Class<?> owningClass,
157 @Nonnull String name,
158 @Nonnull com.atlassian.cache.Supplier<V> supplier,
159 @Nonnull CacheSettings settings)
160 {
161 return getCachedReference(cacheName(owningClass, name), supplier, settings);
162 }
163
164 private static String cacheName(Class<?> owningClass, String name)
165 {
166 checkNotNull(name, "name cannot be null");
167 return owningClass.getName() + '.' + name;
168 }
169
170 @Nonnull
171 @SuppressWarnings("unchecked")
172 @Override
173 public <K, V> Cache<K, V> getCache(@Nonnull String name, @Nullable CacheLoader<K, V> loader, @Nonnull CacheSettings settings)
174 {
175 if (null == loader)
176 {
177 return (Cache<K, V>) createSimpleCache(name, mergeSettings(name, settings));
178 }
179 else
180 {
181 return (Cache<K, V>) createComputingCache(name, mergeSettings(name, settings), loader);
182 }
183 }
184
185
186
187
188
189
190 protected abstract <K, V> ManagedCache createComputingCache(@Nonnull String name, @Nonnull CacheSettings settings, @Nullable CacheLoader<K, V> loader);
191
192
193
194
195
196
197
198 protected abstract ManagedCache createSimpleCache(@Nonnull String name, @Nonnull CacheSettings settings);
199
200 protected CacheSettings mergeSettings(String name, CacheSettings settings)
201 {
202 if (cacheSettingsDefaultsProvider == null)
203 {
204 return settings;
205 }
206
207 return cacheSettingsDefaultsProvider.getDefaults(name).override(settings);
208 }
209
210 @Override
211 public void shutdown()
212 {
213
214 }
215 }