1 package com.atlassian.cache.memory;
2
3 import com.atlassian.cache.CacheLoader;
4 import com.atlassian.cache.CacheSettings;
5 import com.atlassian.cache.CacheSettingsBuilder;
6 import com.atlassian.cache.CachedReference;
7 import com.atlassian.cache.ManagedCache;
8 import com.atlassian.cache.impl.AbstractCacheManager;
9 import com.atlassian.cache.impl.ReferenceKey;
10 import com.atlassian.cache.impl.StrongSupplier;
11 import com.atlassian.cache.impl.WeakSupplier;
12 import com.atlassian.util.concurrent.Supplier;
13 import com.google.common.cache.Cache;
14 import com.google.common.cache.CacheBuilder;
15 import com.google.common.cache.LoadingCache;
16
17 import static java.util.concurrent.TimeUnit.MILLISECONDS;
18
19
20
21
22
23
24 public class MemoryCacheManager extends AbstractCacheManager
25 {
26 @SuppressWarnings("unchecked")
27 @Override
28 public <V> CachedReference<V> getCachedReference(final String name,
29 final com.atlassian.cache.Supplier<V> supplier,
30 final CacheSettings settings)
31 {
32
33 final CacheSettings overridenSettings = settings.override(
34 new CacheSettingsBuilder().flushable().maxEntries(1).build());
35
36
37 return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<DelegatingCachedReference<V>>()
38 {
39 @Override
40 public DelegatingCachedReference<V> get()
41 {
42 LoadingCache<ReferenceKey, V> computingCache = createCacheBuilder(overridenSettings).build(
43 new com.google.common.cache.CacheLoader<ReferenceKey, V>()
44 {
45 @Override
46 public V load(final ReferenceKey key) throws Exception
47 {
48 return supplier.get();
49 }
50 });
51 DelegatingCachedReference cache = DelegatingCachedReference.create(computingCache, name, overridenSettings);
52 caches.put(name, new WeakSupplier<ManagedCache>(cache));
53 return cache;
54 }
55 });
56 }
57
58 @SuppressWarnings("unchecked")
59 protected ManagedCache createSimpleCache(final String name, final CacheSettings settings)
60 {
61
62 Supplier<ManagedCache> cacheSupplier = caches.get(name);
63 if (cacheSupplier != null)
64 {
65 ManagedCache cache = cacheSupplier.get();
66 if (cache != null)
67 {
68 return cache;
69 }
70 }
71 return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<ManagedCache>()
72 {
73 @Override
74 public ManagedCache get()
75 {
76 if (!caches.containsKey(name))
77 {
78 final Cache<Object, Object> simpleCache = createCacheBuilder(settings).build();
79 DelegatingCache cache = DelegatingCache.create(simpleCache, name, settings);
80 caches.put(name, new StrongSupplier<ManagedCache>(cache));
81 }
82 return caches.get(name).get();
83 }
84 });
85 }
86
87 @SuppressWarnings("unchecked")
88 protected <K, V> ManagedCache createComputingCache(final String name, final CacheSettings settings, final CacheLoader<K, V> loader)
89 {
90 return cacheCreationLocks.get(name).withLock(new com.atlassian.util.concurrent.Supplier<DelegatingCache<K, V>>()
91 {
92 @Override
93 public DelegatingCache<K, V> get()
94 {
95 LoadingCache<K, V> computingCache = createCacheBuilder(settings)
96 .build(new com.google.common.cache.CacheLoader<K, V>()
97 {
98 @Override
99 public V load(final K key) throws Exception
100 {
101 return loader.load(key);
102 }
103 });
104 DelegatingCache cache = DelegatingCache.create(computingCache, name, settings);
105 if (!caches.containsKey(name))
106 {
107 caches.put(name, new WeakSupplier<ManagedCache>(cache));
108 }
109 return cache;
110 }
111 });
112 }
113
114 private CacheBuilder createCacheBuilder(CacheSettings settings)
115 {
116 final CacheBuilder cacheBuilder = CacheBuilder.newBuilder();
117 if (null != settings.getMaxEntries())
118 {
119 cacheBuilder.maximumSize(settings.getMaxEntries());
120 }
121
122 if (null != settings.getExpireAfterAccess())
123 {
124 cacheBuilder.expireAfterAccess(settings.getExpireAfterAccess(), MILLISECONDS);
125 }
126 else if (null != settings.getExpireAfterWrite())
127 {
128 cacheBuilder.expireAfterWrite(settings.getExpireAfterWrite(), MILLISECONDS);
129 }
130 return cacheBuilder;
131 }
132 }