1
2
3
4
5 package org.sourceforge.jemm.collections;
6
7 import java.util.Collection;
8 import java.util.Map;
9 import java.util.Set;
10 import java.util.concurrent.ConcurrentMap;
11
12 import org.sourceforge.jemm.collections.internal.ClearRequest;
13 import org.sourceforge.jemm.collections.internal.ContainsRequest;
14 import org.sourceforge.jemm.collections.internal.ContainsResponse;
15 import org.sourceforge.jemm.collections.internal.SizeRequest;
16 import org.sourceforge.jemm.collections.internal.SizeResponse;
17 import org.sourceforge.jemm.collections.internal.StoredValue;
18 import org.sourceforge.jemm.collections.internal.map.ContainsValueRequest;
19 import org.sourceforge.jemm.collections.internal.map.MapGetRequest;
20 import org.sourceforge.jemm.collections.internal.map.MapGetResponse;
21 import org.sourceforge.jemm.collections.internal.map.MapKeySetRequest;
22 import org.sourceforge.jemm.collections.internal.map.MapKeySetResponse;
23 import org.sourceforge.jemm.collections.internal.map.MapPutIfAbsentRequest;
24 import org.sourceforge.jemm.collections.internal.map.MapPutIfAbsentResponse;
25 import org.sourceforge.jemm.collections.internal.map.MapPutRequest;
26 import org.sourceforge.jemm.collections.internal.map.MapPutResponse;
27 import org.sourceforge.jemm.collections.internal.map.MapRemoveKVRequest;
28 import org.sourceforge.jemm.collections.internal.map.MapRemoveKVResponse;
29 import org.sourceforge.jemm.collections.internal.map.MapRemoveRequest;
30 import org.sourceforge.jemm.collections.internal.map.MapRemoveResponse;
31 import org.sourceforge.jemm.collections.internal.map.MapReplaceKONRequest;
32 import org.sourceforge.jemm.collections.internal.map.MapReplaceKONResponse;
33 import org.sourceforge.jemm.collections.internal.map.MapReplaceKVRequest;
34 import org.sourceforge.jemm.collections.internal.map.MapReplaceKVResponse;
35 import org.sourceforge.jemm.collections.internal.map.MapValuesRequest;
36 import org.sourceforge.jemm.collections.internal.map.MapValuesResponse;
37 import org.sourceforge.jemm.lifecycle.ShadowTypeObject;
38 import org.sourceforge.jemm.util.JEMMType;
39
40
41
42
43
44
45
46
47
48
49 public final class JemmMap<K, V> extends JEMMType implements ConcurrentMap<K, V> {
50
51
52
53
54 public JemmMap() {
55 super();
56 }
57
58
59
60
61 protected JemmMap(ShadowTypeObject jemmOIF) {
62 super(jemmOIF);
63 }
64
65 public void clear() {
66 jemmOIF.processRequest(new ClearRequest());
67 }
68
69 public boolean containsKey(final Object uKey) {
70 ContainsResponse result = (ContainsResponse) jemmOIF.processRequest(new ContainsRequest(uKey));
71 if(result.isFound())
72 return true;
73 else
74 if(result.getPossibles() != null)
75 for (Object possible : result.getPossibles())
76 if(uKey.equals(possible))
77 return true;
78 return false;
79 }
80
81 public boolean containsValue(final Object value) {
82 ContainsResponse result = (ContainsResponse) jemmOIF.processRequest(new ContainsValueRequest(value));
83 if(result.isFound())
84 return true;
85 else
86 if(result.getPossibles() != null)
87 for (Object possible : result.getPossibles())
88 if(value.equals(possible))
89 return true;
90 return false;
91 }
92
93
94
95
96 public Set<java.util.Map.Entry<K, V>> entrySet() {
97 throw new UnsupportedOperationException();
98 }
99
100 @SuppressWarnings("unchecked")
101 public V get(final Object uKey) {
102 StoredValue key = new StoredValue(uKey);
103 MapGetRequest req = new MapGetRequest(key);
104 while(true) {
105 MapGetResponse resp = (MapGetResponse) jemmOIF.processRequest(req);
106 if(resp.isFound())
107 return (V) resp.getValue();
108
109 if(!resp.hasPossibleMatches())
110 return null;
111
112 StoredValue newKey = null;
113 StoredValue[] possibleMatches = resp.getPossibleMatches();
114 for(int i=0; i<possibleMatches.length && newKey == null; i++)
115 if(possibleMatches[i].equals(key))
116 newKey = possibleMatches[i];
117
118 if(newKey == null)
119 return null;
120 else
121 req = new MapGetRequest(newKey);
122 }
123 }
124
125 public boolean isEmpty() {
126 return size() == 0;
127 }
128
129 @SuppressWarnings("unchecked")
130 public Set<K> keySet() {
131 return (Set<K>) ((MapKeySetResponse) jemmOIF.processRequest(new MapKeySetRequest())).getKeySet();
132 }
133
134 @SuppressWarnings("unchecked")
135 public V put(K uKey, V uValue) {
136
137 StoredValue sKey = new StoredValue(uKey);
138 StoredValue sValue = new StoredValue(uValue);
139
140 MapPutRequest req = new MapPutRequest(sKey,sValue,null);
141 while(true) {
142 MapPutResponse response = (MapPutResponse) jemmOIF.processRequest(req);
143 if(response.isSuccess())
144 return (V) response.getPreviousValue();
145
146 StoredValue keyTarget = null;
147 StoredValue[] possibleMatches = response.getPossibleMatches();
148 for(int i=0; i<possibleMatches.length && keyTarget==null; i++)
149 if(possibleMatches[i].equals(sKey))
150 keyTarget = possibleMatches[i];
151
152 if(keyTarget == null)
153 req = new MapPutRequest(sKey,sValue,possibleMatches);
154 else
155 req = new MapPutRequest(keyTarget,sValue,null);
156 }
157 }
158
159
160
161
162 public void putAll(Map<? extends K, ? extends V> t) {
163
164 throw new UnsupportedOperationException();
165 }
166
167 @SuppressWarnings("unchecked")
168 public V remove(Object uKey) {
169 StoredValue key = new StoredValue(uKey);
170
171 MapRemoveRequest req = new MapRemoveRequest(key);
172 while(true) {
173 MapRemoveResponse resp = (MapRemoveResponse) jemmOIF.processRequest(req);
174 if(resp.isRemoved())
175 return (V) resp.getOldValue();
176 else {
177 StoredValue[] potentialMatches = resp.getPotentialMatches();
178 if(potentialMatches == null)
179 return null;
180
181 StoredValue match = null;
182 for(int i=0; i<potentialMatches.length && match == null; i++)
183 if(key.equals(potentialMatches[i]))
184 match = potentialMatches[i];
185
186 if(match == null)
187 return null;
188
189 req = new MapRemoveRequest(match);
190 }
191 }
192
193 }
194
195 public int size() {
196 return ((SizeResponse) jemmOIF.processRequest(new SizeRequest())).getSize();
197 }
198
199 @SuppressWarnings("unchecked")
200 public Collection<V> values() {
201 return (Collection<V>) ((MapValuesResponse) jemmOIF.processRequest(new MapValuesRequest())).getValues();
202 }
203
204 @SuppressWarnings("unchecked")
205 public V putIfAbsent(K uKey, V uValue) {
206
207 StoredValue key = new StoredValue(uKey);
208 StoredValue value = new StoredValue(uValue);
209
210 MapPutIfAbsentRequest req = new MapPutIfAbsentRequest(key,value,null);
211 while(true) {
212 MapPutIfAbsentResponse resp = (MapPutIfAbsentResponse) jemmOIF.processRequest(req);
213 if(resp.wasPut() || resp.getPossibleMatches() == null)
214 return (V) resp.getPreviousValue();
215
216 StoredValue[] possibles = resp.getPossibleMatches();
217 Object[] possibleValues = resp.getPossibleValues();
218 for (int i = 0; i < possibles.length; i++) {
219 StoredValue possible = possibles[i];
220 if(possible.equals(key))
221 return (V) possibleValues[i];
222 }
223
224 req = new MapPutIfAbsentRequest(key,value,possibles);
225 }
226 }
227
228 public boolean remove(Object uKey, Object uValue) {
229
230 StoredValue key = new StoredValue(uKey);
231 StoredValue value = new StoredValue(uValue);
232
233
234 MapRemoveKVRequest req = new MapRemoveKVRequest(key,value);
235 while(true) {
236 MapRemoveKVResponse resp = (MapRemoveKVResponse) jemmOIF.processRequest(req);
237 if(resp.isSuccess())
238 return true;
239
240 if(!resp.hasPotentials())
241 return false;
242
243 StoredValue potentialKeys[] = resp.getPotentialKeyMatches();
244 StoredValue potentialValues[] = resp.getPotentialValueMatches();
245
246 StoredValue newKey= null;
247 StoredValue newValue = null;
248
249 for (int i = 0; i < potentialKeys.length && newKey == null; i++) {
250 if(potentialKeys[i].equals(key)) {
251 if(potentialValues[i].equals(value)) {
252 newKey = potentialKeys[i];
253 newValue = potentialValues[i];
254 } else
255 return false;
256 }
257 }
258
259 if(newKey == null)
260 return false;
261
262 req = new MapRemoveKVRequest(newKey,newValue);
263 }
264 }
265
266 @SuppressWarnings("unchecked")
267 public V replace(K uKey, V uValue) {
268 StoredValue key = new StoredValue(uKey);
269 StoredValue value = new StoredValue(uValue);
270
271 MapReplaceKVRequest req = new MapReplaceKVRequest(key,value);
272 while(true) {
273 MapReplaceKVResponse resp = (MapReplaceKVResponse) jemmOIF.processRequest(req);
274 if(resp.isSuccess())
275 return (V) resp.getOldValue();
276
277 if(!resp.hasPotentialKeyMatches())
278 return null;
279
280 StoredValue newKey = null;
281
282 StoredValue[] potentialKeyMatches = resp.getPotentialKeyMatches();
283 for (int i = 0; i < potentialKeyMatches.length && newKey != null; i++) {
284 if(potentialKeyMatches[i].equals(key))
285 newKey = potentialKeyMatches[i];
286 }
287
288 if(newKey == null)
289 return null;
290
291 req = new MapReplaceKVRequest(newKey,value);
292 }
293 }
294
295 public boolean replace(K uKey, V uOldValue, V uNewValue) {
296 StoredValue key = new StoredValue(uKey);
297 StoredValue oldValue = new StoredValue(uOldValue);
298 final StoredValue newValue = new StoredValue(uNewValue);
299
300 MapReplaceKONRequest req = new MapReplaceKONRequest(key,oldValue,newValue);
301 while(true) {
302 MapReplaceKONResponse resp = (MapReplaceKONResponse) jemmOIF.processRequest(req);
303 if(resp.isSuccess())
304 return true;
305
306 if(!resp.hasPotentialKeyMatches())
307 return false;
308
309 StoredValue newKey = null;
310 StoredValue newOldValue = null;
311
312 StoredValue[] potentialKeyMatches = resp.getPotentialKeyMatches();
313 StoredValue[] potentialValueMatches = resp.getPotentialValueMatches();
314
315 for (int i = 0; i < potentialKeyMatches.length && newKey != null; i++) {
316 if(potentialKeyMatches[i].equals(key)) {
317 if(!potentialValueMatches[i].equals(oldValue))
318 return false;
319
320 newKey = potentialKeyMatches[i];
321 newOldValue = potentialValueMatches[i];
322 }
323 }
324
325 if(newKey == null)
326 return false;
327 req = new MapReplaceKONRequest(newKey,newOldValue,newValue);
328 }
329 }
330 }