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