View Javadoc

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 com.atlassian.cache.Cache;
10  import com.atlassian.cache.CacheLoader;
11  import com.atlassian.cache.CacheManager;
12  import com.atlassian.cache.CacheSettings;
13  import com.atlassian.cache.CacheSettingsBuilder;
14  import com.atlassian.cache.CachedReference;
15  import com.atlassian.cache.ManagedCache;
16  import com.atlassian.util.concurrent.Function;
17  import com.atlassian.util.concurrent.ManagedLock;
18  import com.atlassian.util.concurrent.ManagedLocks;
19  import com.atlassian.util.concurrent.NotNull;
20  import com.atlassian.util.concurrent.Supplier;
21  
22  import static com.google.common.base.Preconditions.checkNotNull;
23  
24  /**
25   * A partial implementation of {@link CacheManager}.
26   *
27   * @since 2.0.6
28   */
29  public abstract class AbstractCacheManager implements CacheManager
30  {
31  
32      /**
33       * Map of all the caches.
34       * Before creating a cache to put into the map, acquire a lock using {@link #cacheCreationLocks}
35       * to ensure that a cache is created only once.
36       */
37      protected final ConcurrentMap<String, Supplier<ManagedCache>> caches = new ConcurrentHashMap<String, Supplier<ManagedCache>>();
38      /** Used to synchronize the creation of caches. */
39      protected final Function<String, ManagedLock> cacheCreationLocks = ManagedLocks.weakManagedLockFactory();
40  
41  
42  
43      @SuppressWarnings("unchecked")
44      @Override
45      public Collection<Cache<?, ?>> getCaches()
46      {
47          List<Cache<?, ?>> managedCaches = new ArrayList<Cache<?, ?>>();
48  
49          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
50          {
51              final ManagedCache managedCache = cacheRef.get();
52              if (managedCache != null)
53              {
54                  managedCaches.add((Cache) managedCache);
55              }
56          }
57          return managedCaches;
58      }
59  
60      @Override
61      public Collection<ManagedCache> getManagedCaches()
62      {
63          List<ManagedCache> managedCaches = new ArrayList<ManagedCache>();
64  
65          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
66          {
67              final ManagedCache managedCache = cacheRef.get();
68              if (managedCache != null)
69              {
70                  managedCaches.add(managedCache);
71              }
72          }
73          return managedCaches;
74      }
75  
76      @Override
77      public ManagedCache getManagedCache(@NotNull String name)
78      {
79          final Supplier<ManagedCache> cacheRef = caches.get(name);
80          return (null == cacheRef) ? null : cacheRef.get();
81      }
82  
83      @Override
84      public void flushCaches()
85      {
86          for (final com.atlassian.util.concurrent.Supplier<ManagedCache> cacheRef : caches.values())
87          {
88              final ManagedCache managedCache = cacheRef.get();
89              if (managedCache != null && managedCache.isFlushable())
90              {
91                  managedCache.clear();
92              }
93          }
94      }
95  
96      @Override
97      public <K, V> Cache<K, V> getCache(@NotNull final String name)
98      {
99          return getCache(name, null);
100     }
101 
102     @Override
103     public <K, V> Cache<K, V> getCache(Class<?> owningClass, String name)
104     {
105         return getCache(cacheName(owningClass, name));
106     }
107 
108     @Override
109     public <K, V> Cache<K, V> getCache(final String name, final Class<K> keyType, final Class<V> valueType)
110     {
111         return getCache(name);
112     }
113 
114     @Override
115     public <K, V> Cache<K, V> getCache(String name, CacheLoader<K, V> loader)
116     {
117         return getCache(name, loader, new CacheSettingsBuilder().build());
118     }
119 
120     @Override
121     public <V> CachedReference<V> getCachedReference(String name, com.atlassian.cache.Supplier<V> supplier)
122     {
123         return getCachedReference(name, supplier, new CacheSettingsBuilder().build());
124     }
125 
126     @Override
127     public <V> CachedReference<V> getCachedReference(Class<?> owningClass,
128                                                      String name,
129                                                      com.atlassian.cache.Supplier<V> supplier)
130     {
131         return getCachedReference(owningClass, name, supplier, new CacheSettingsBuilder().build());
132     }
133 
134     @Override
135     public <V> CachedReference<V> getCachedReference(Class<?> owningClass,
136                                                      String name,
137                                                      com.atlassian.cache.Supplier<V> supplier,
138                                                      CacheSettings settings)
139     {
140         return getCachedReference(cacheName(owningClass, name), supplier, settings);
141     }
142 
143     private static String cacheName(Class<?> owningClass, String name)
144     {
145         checkNotNull(name, "name cannot be null");
146         return owningClass.getName() + "." + name;
147     }
148 
149     @SuppressWarnings("unchecked")
150     @Override
151     public <K, V> Cache<K, V> getCache(String name, CacheLoader<K, V> loader, CacheSettings settings)
152     {
153         if (null == loader)
154         {
155             return (Cache<K, V>) createSimpleCache(name, settings);
156         }
157         else
158         {
159             return (Cache<K, V>) createComputingCache(name, settings, loader);
160         }
161     }
162 
163     /**
164      * Creates a cache that upon a miss is able to populate itself using the loader.
165      *
166      * @return a non-null cache
167      */
168     protected abstract <K, V> ManagedCache createComputingCache(String name, CacheSettings settings, CacheLoader<K, V> loader);
169 
170     /**
171      * Creates a cache with no loader, i.e. one populated via explicit puts.
172      *
173      * @param name the name to give the cache (required)
174      * @return a non-null cache
175      */
176     protected abstract ManagedCache createSimpleCache(String name, CacheSettings settings);
177 }