1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.river.norm;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import net.jini.config.ConfigurationException;
29 import org.apache.river.norm.proxy.StoreException;
30 import org.apache.river.norm.proxy.CorruptedStoreException;
31 import org.apache.river.norm.lookup.SubStore;
32 import org.apache.river.reliableLog.LogHandler;
33 import org.apache.river.reliableLog.ReliableLog;
34 import org.apache.river.system.FileSystem;
35 import org.apache.river.thread.ReadersWriter;
36
37
38
39
40
41
42
43 class PersistentStore {
44
45 private static final Logger logger = Logger.getLogger("org.apache.river.norm");
46
47
48
49
50
51 private ReliableLog log;
52
53
54
55
56
57
58
59
60
61 final private ReadersWriter mutatorLock = new ReadersWriter();
62
63
64
65
66
67 final static private ThreadLocal lockState = new ThreadLocal();
68
69
70 final static private Long zero = Long.valueOf(0);
71
72
73 final private File storeLocation;
74
75
76 final private LogHandler logHandler;
77
78
79 private NormServerBaseImpl server;
80
81
82 private int updateCount;
83
84
85 private List subStores = new LinkedList();
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 PersistentStore(String logDir, LogHandler logHandler,
101 NormServerBaseImpl server)
102 throws StoreException
103 {
104 this.logHandler = logHandler;
105 this.server = server;
106 if (logDir == null) {
107 storeLocation = null;
108 } else {
109 storeLocation = new File(logDir);
110 try {
111 log = new ReliableLog(
112 storeLocation.getCanonicalPath(), logHandler);
113 } catch (IOException e) {
114 throw new CorruptedStoreException(
115 "Failure creating reliable log", e);
116 }
117
118 try {
119 log.recover();
120 } catch (IOException e) {
121 throw new CorruptedStoreException(
122 "Failure recovering reliable log", e);
123 }
124 }
125 }
126
127
128
129
130
131 void setServer(NormServerBaseImpl server){
132 synchronized (this){
133 if (this.server == null) this.server = server;
134 }
135 }
136
137
138
139
140
141
142 void destroy() throws IOException {
143
144 synchronized (subStores){
145 for (Iterator i = subStores.iterator(); i.hasNext(); ) {
146 SubStore subStore = (SubStore) i.next();
147 subStore.prepareDestroy();
148 }
149 }
150 if (log != null) {
151 log.deletePersistentStore();
152 FileSystem.destroy(storeLocation, true);
153 }
154 }
155
156
157
158
159 void addSubStore(SubStore subStore) throws StoreException {
160 try {
161 if (log == null) {
162 subStore.setDirectory(null);
163 } else {
164 final String subDir = subStore.subDirectory();
165
166 if (subDir == null) {
167 subStore.setDirectory(storeLocation);
168 } else {
169 subStore.setDirectory(new File(storeLocation, subDir));
170 }
171 }
172 synchronized (subStores){
173 subStores.add(subStore);
174 }
175 } catch (IOException e) {
176 throw new StoreException("Failure adding substore " + subStore,
177 e);
178 } catch (ConfigurationException e) {
179 throw new StoreException("Failure adding substore " + subStore,
180 e);
181 }
182 }
183
184
185
186
187
188
189
190
191
192
193
194 void acquireMutatorLock() {
195
196
197 Long lockStateVal = (Long) lockState.get();
198 if (lockStateVal == null)
199 lockStateVal = zero;
200
201 final long longVal = lockStateVal.longValue();
202
203 if (longVal == 0) {
204
205
206
207 mutatorLock.readLock();
208 }
209
210
211 lockState.set(Long.valueOf(longVal + 1));
212 }
213
214
215
216
217 void releaseMutatorLock() {
218 Long lockStateVal = (Long) lockState.get();
219 if (lockStateVal == null)
220 lockStateVal = zero;
221
222 final long longVal = lockStateVal.longValue();
223
224 if (longVal == 0) {
225
226 return;
227 }
228
229 if (longVal == 1) {
230
231
232 mutatorLock.readUnlock();
233 lockStateVal = zero;
234 } else {
235 lockStateVal = Long.valueOf(longVal - 1);
236 }
237
238 lockState.set(lockStateVal);
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253 void update(Object o) {
254 if (log == null) {
255 return;
256 }
257 final Long lockStateVal = (Long) lockState.get();
258 if (lockStateVal == null || lockStateVal.longValue() == 0) {
259 throw new IllegalStateException("PersistentStore.update:" +
260 "Must acquire mutator lock before calling update()");
261 }
262
263 synchronized (this) {
264 try {
265 log.update(o, true);
266 updateCount++;
267 server.updatePerformed(updateCount);
268 } catch (IOException e) {
269
270 logger.log(Level.WARNING, "IOException while updating log", e);
271 }
272 }
273 }
274
275
276
277
278
279
280
281
282
283 void snapshot() throws IOException {
284 if (log == null) {
285 return;
286 }
287 try {
288
289 mutatorLock.writeLock();
290 synchronized (this){
291 updateCount = 0;
292 }
293
294
295
296 log.snapshot();
297 } finally {
298
299 mutatorLock.writeUnlock();
300 }
301 }
302 }