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