001
014
015 package com.liferay.portal.kernel.cache;
016
017 import com.liferay.portal.kernel.concurrent.CompeteLatch;
018
019 import java.io.Serializable;
020
021 import java.util.Collection;
022 import java.util.concurrent.ConcurrentHashMap;
023 import java.util.concurrent.ConcurrentMap;
024
025
028 public class BlockingPortalCache implements PortalCache {
029
030 public BlockingPortalCache(PortalCache portalCache) {
031 _portalCache = portalCache;
032 }
033
034 @Override
035 public void destroy() {
036 }
037
038 @Override
039 public Collection<Object> get(Collection<Serializable> keys) {
040 return _portalCache.get(keys);
041 }
042
043 @Override
044 public Object get(Serializable key) {
045 Object value = _portalCache.get(key);
046
047 if (value != null) {
048 return value;
049 }
050
051 CompeteLatch lastCompeteLatch = _competeLatch.get();
052
053 if (lastCompeteLatch != null) {
054 lastCompeteLatch.done();
055
056 _competeLatch.set(null);
057 }
058
059 CompeteLatch currentCompeteLatch = _competeLatchMap.get(key);
060
061 if (currentCompeteLatch == null) {
062 CompeteLatch newCompeteLatch = new CompeteLatch();
063
064 currentCompeteLatch = _competeLatchMap.putIfAbsent(
065 key, newCompeteLatch);
066
067 if (currentCompeteLatch == null) {
068 currentCompeteLatch = newCompeteLatch;
069 }
070 }
071
072 _competeLatch.set(currentCompeteLatch);
073
074 if (!currentCompeteLatch.compete()) {
075 try {
076 currentCompeteLatch.await();
077 }
078 catch (InterruptedException ie) {
079 }
080
081 _competeLatch.set(null);
082
083 value = _portalCache.get(key);
084 }
085
086 return value;
087 }
088
089 @Override
090 public String getName() {
091 return _portalCache.getName();
092 }
093
094 @Override
095 public void put(Serializable key, Object value) {
096 if (key == null) {
097 throw new IllegalArgumentException("Key is null");
098 }
099
100 if (value == null) {
101 throw new IllegalArgumentException("Value is null");
102 }
103
104 _portalCache.put(key, value);
105
106 CompeteLatch competeLatch = _competeLatch.get();
107
108 if (competeLatch != null) {
109 competeLatch.done();
110
111 _competeLatch.set(null);
112 }
113
114 _competeLatchMap.remove(key);
115 }
116
117 @Override
118 public void put(Serializable key, Object value, int timeToLive) {
119 if (key == null) {
120 throw new IllegalArgumentException("Key is null");
121 }
122
123 if (value == null) {
124 throw new IllegalArgumentException("Value is null");
125 }
126
127 _portalCache.put(key, value, timeToLive);
128
129 CompeteLatch competeLatch = _competeLatch.get();
130
131 if (competeLatch != null) {
132 competeLatch.done();
133
134 _competeLatch.set(null);
135 }
136
137 _competeLatchMap.remove(key);
138 }
139
140 @Override
141 public void put(Serializable key, Serializable value) {
142 if (key == null) {
143 throw new IllegalArgumentException("Key is null");
144 }
145
146 if (value == null) {
147 throw new IllegalArgumentException("Value is null");
148 }
149
150 _portalCache.put(key, value);
151
152 CompeteLatch competeLatch = _competeLatch.get();
153
154 if (competeLatch != null) {
155 competeLatch.done();
156
157 _competeLatch.set(null);
158 }
159
160 _competeLatchMap.remove(key);
161 }
162
163 @Override
164 public void put(Serializable key, Serializable value, int timeToLive) {
165 if (key == null) {
166 throw new IllegalArgumentException("Key is null");
167 }
168
169 if (value == null) {
170 throw new IllegalArgumentException("Value is null");
171 }
172
173 _portalCache.put(key, value, timeToLive);
174
175 CompeteLatch competeLatch = _competeLatch.get();
176
177 if (competeLatch != null) {
178 competeLatch.done();
179
180 _competeLatch.set(null);
181 }
182
183 _competeLatchMap.remove(key);
184 }
185
186 @Override
187 public void registerCacheListener(CacheListener cacheListener) {
188 _portalCache.registerCacheListener(cacheListener);
189 }
190
191 @Override
192 public void registerCacheListener(
193 CacheListener cacheListener, CacheListenerScope cacheListenerScope) {
194
195 _portalCache.registerCacheListener(cacheListener, cacheListenerScope);
196 }
197
198 @Override
199 public void remove(Serializable key) {
200 _portalCache.remove(key);
201
202 CompeteLatch competeLatch = _competeLatchMap.remove(key);
203
204 if (competeLatch != null) {
205 competeLatch.done();
206 }
207 }
208
209 @Override
210 public void removeAll() {
211 _portalCache.removeAll();
212 _competeLatchMap.clear();
213 }
214
215 @Override
216 public void unregisterCacheListener(CacheListener cacheListener) {
217 _portalCache.unregisterCacheListener(cacheListener);
218 }
219
220 @Override
221 public void unregisterCacheListeners() {
222 _portalCache.unregisterCacheListeners();
223 }
224
225 private static ThreadLocal<CompeteLatch> _competeLatch =
226 new ThreadLocal<CompeteLatch>();
227
228 private final ConcurrentMap<Serializable, CompeteLatch> _competeLatchMap =
229 new ConcurrentHashMap<Serializable, CompeteLatch>();
230 private final PortalCache _portalCache;
231
232 }