source: osm/applications/editors/josm/plugins/imagerycache/src/org/mapdb/SnapshotEngine.java@ 30532

Last change on this file since 30532 was 30532, checked in by donvip, 10 years ago

[josm_plugins] fix compilation warnings

File size: 4.7 KB
Line 
1package org.mapdb;
2
3import java.util.Map;
4import java.util.concurrent.ConcurrentHashMap;
5import java.util.concurrent.locks.ReentrantLock;
6import java.util.concurrent.locks.ReentrantReadWriteLock;
7
8/**
9 * Naive implementation of Snapshots on top of StorageEngine.
10 * On update it takes old value and stores it aside.
11 * <p/>
12 * TODO merge snapshots down with Storage for best performance
13 *
14 * @author Jan Kotek
15 */
16public class SnapshotEngine extends EngineWrapper{
17
18 protected final ReentrantLock[] locks = Utils.newLocks(32);
19
20 protected final static Object NOT_EXIST = new Object();
21 protected final static Object NOT_INIT_YET = new Object();
22
23
24 protected final Map<Snapshot, String> snapshots = new ConcurrentHashMap<Snapshot, String>();
25
26
27 protected SnapshotEngine(Engine engine) {
28 super(engine);
29 }
30
31 public Engine snapshot() {
32 return new Snapshot();
33 }
34
35 /** protects <code>snapshot</code> when modified */
36 protected final ReentrantReadWriteLock snapshotsLock = new ReentrantReadWriteLock();
37
38 @SuppressWarnings("unchecked")
39 @Override
40 public <A> long put(A value, Serializer<A> serializer) {
41 long recid = super.put(value, serializer);
42 Utils.lock(locks,recid);
43 try{
44 for(Snapshot s:snapshots.keySet()){
45 s.oldValues.putIfAbsent(recid, NOT_EXIST);
46 }
47 return recid;
48 }finally{
49 Utils.unlock(locks,recid);
50 }
51 }
52
53 @SuppressWarnings("unchecked")
54 @Override
55 public <A> boolean compareAndSwap(long recid, A expectedOldValue, A newValue, Serializer<A> serializer) {
56 Utils.lock(locks,recid);
57 try{
58 boolean ret = super.compareAndSwap(recid, expectedOldValue, newValue, serializer);
59 if(ret==true){
60 for(Snapshot s:snapshots.keySet()){
61 s.oldValues.putIfAbsent(recid, expectedOldValue);
62 }
63 }
64 return ret;
65 }finally{
66 Utils.unlock(locks,recid);
67 }
68 }
69
70 @SuppressWarnings("unchecked")
71 @Override
72 public <A> void update(long recid, A value, Serializer<A> serializer) {
73 Utils.lock(locks,recid);
74 try{
75 Object val = NOT_INIT_YET;
76 for(Snapshot s:snapshots.keySet()){
77 if(s.oldValues.get(recid)==null){
78 if(val == NOT_INIT_YET)
79 val = get(recid, serializer);
80 s.oldValues.put(recid,val);
81 }
82 }
83
84 super.update(recid, value, serializer);
85 }finally{
86 Utils.unlock(locks,recid);
87 }
88 }
89
90 @SuppressWarnings("unchecked")
91 @Override
92 public <A> void delete(long recid, Serializer<A> serializer) {
93 Utils.lock(locks,recid);
94 try{
95 Object val = NOT_INIT_YET;
96 for(Snapshot s:snapshots.keySet()){
97 if(s.oldValues.get(recid)==null){
98 if(val == NOT_INIT_YET)
99 val = get(recid, serializer);
100 s.oldValues.put(recid,val);
101 }
102 }
103
104 super.delete(recid,serializer);
105 }finally{
106 Utils.unlock(locks,recid);
107 }
108 }
109
110 public static Engine createSnapshotFor(Engine engine) {
111 SnapshotEngine se = null;
112 while(true){
113 if(engine instanceof SnapshotEngine){
114 se = (SnapshotEngine) engine;
115 break;
116 }else if(engine instanceof EngineWrapper){
117 engine = ((EngineWrapper)engine).getWrappedEngine();
118 }else{
119 throw new IllegalArgumentException("Could not create Snapshot for Engine: "+engine);
120 }
121 }
122
123 return se.snapshot();
124 }
125
126 protected class Snapshot extends ReadOnlyEngine{
127
128 protected LongConcurrentHashMap oldValues = new LongConcurrentHashMap();
129
130 public Snapshot() {
131 super(SnapshotEngine.this);
132 snapshots.put(Snapshot.this, "");
133 }
134
135
136 @SuppressWarnings("unchecked")
137 @Override
138 public <A> A get(long recid, Serializer<A> serializer) {
139 Utils.lock(locks,recid);
140 try{
141 Object ret = oldValues.get(recid);
142 if(ret!=null){
143 if(ret==NOT_EXIST) return null;
144 return (A) ret;
145 }
146 return SnapshotEngine.this.getWrappedEngine().get(recid, serializer);
147 }finally{
148 Utils.unlock(locks,recid);
149 }
150 }
151
152 @Override
153 public boolean isClosed() {
154 return oldValues!=null;
155 }
156
157 @Override
158 public void close() {
159 snapshots.remove(Snapshot.this);
160 oldValues.clear();
161 }
162 }
163}
Note: See TracBrowser for help on using the repository browser.