View Javadoc

1   /***
2    * 
3    * Copyright 2004 Protique Ltd
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License"); 
6    * you may not use this file except in compliance with the License. 
7    * You may obtain a copy of the License at 
8    * 
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License. 
16   * 
17   **/
18  package org.codehaus.activespace.cache.impl;
19  
20  import javax.cache.Cache;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.Map;
24  
25  /***
26   * Implements a thread local view of a cache which implements am
27   * optimistic transaction policy using the
28   * <i>REPEATABLE_READ</i> transaction isolation level, such that
29   * values looked up in the cache will remain the same during the transaction
30   * which is unlike the <i>READ_COMMITTED</i> isolation level where only committed
31   * data is read but the data can change during the transaction.
32   *
33   * @version $Revision: 1.1 $
34   */
35  public class RepeatableReadThreadCache extends ThreadCache {
36      private Map localReads;
37  
38      public RepeatableReadThreadCache(Cache behindCache) {
39          super(behindCache);
40          this.localReads = createMap();
41      }
42  
43      public RepeatableReadThreadCache(Cache behindCache, Map localChanges, Map localRemoves, Map localReads) {
44          super(behindCache, localChanges, localRemoves);
45          this.localReads = localReads;
46      }
47  
48      public Object remove(Object key) {
49          VersionedValue entry = (VersionedValue) localReads.remove(key);
50          if (entry != null) {
51              localRemove(key, entry.getVersion());
52              return entry.getValue();
53          }
54          else {
55              return super.remove(key);
56          }
57      }
58  
59      public TransactionalCacheCommand createTransactionCommand() {
60          TransactionalCacheCommand answer = super.createTransactionCommand();
61          Map readVersions = new HashMap(localReads.size());
62          for (Iterator iter = localReads.entrySet().iterator(); iter.hasNext();) {
63              Entry entry = (Entry) iter.next();
64              Object key = entry.getKey();
65              VersionedValue versionValue = (VersionedValue) entry.getValue();
66              readVersions.put(key, versionValue.getVersion());
67          }
68          answer.setReadVersions(readVersions);
69          return answer;
70      }
71  
72      protected Object getLocalChangeValue(Object key) {
73          VersionedValue entry = (VersionedValue) localReads.get(key);
74          if (entry != null) {
75              return entry.getValue();
76          }
77          else {
78              Object value = super.getLocalChangeValue(key);
79              localReads.put(key, createVersionedValue(key, value));
80              return value;
81          }
82      }
83  }