Mercurial > hg > blitz_condensed
comparison src/org/dancres/blitz/entry/EntryRepositoryFactory.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3dc0c5604566 |
---|---|
1 package org.dancres.blitz.entry; | |
2 | |
3 import java.io.IOException; | |
4 import java.io.InputStream; | |
5 import java.io.InputStreamReader; | |
6 import java.io.Serializable; | |
7 | |
8 import java.util.Map; | |
9 import java.util.HashMap; | |
10 import java.util.Collection; | |
11 | |
12 import java.util.logging.*; | |
13 | |
14 import net.jini.config.ConfigurationFile; | |
15 import net.jini.config.Configuration; | |
16 import net.jini.config.ConfigurationException; | |
17 | |
18 import org.dancres.blitz.disk.Disk; | |
19 import org.dancres.blitz.disk.Syncable; | |
20 | |
21 import org.dancres.blitz.config.ConfigurationFactory; | |
22 | |
23 import org.dancres.blitz.Logging; | |
24 | |
25 import org.dancres.blitz.lease.LeaseReaper; | |
26 | |
27 import org.dancres.blitz.txn.TxnManager; | |
28 | |
29 import org.prevayler.SnapshotContributor; | |
30 | |
31 public class EntryRepositoryFactory implements Syncable, SnapshotContributor { | |
32 private static final String LOG_COUNTS = "logCounts"; | |
33 | |
34 private static LeaseReaper theReaper; | |
35 | |
36 private static final Logger theLogger = | |
37 Logging.newLogger("org.dancres.blitz.entry.EntryRepositoryFactory"); | |
38 | |
39 private static EntryRepositoryFactory theReposFactory = | |
40 new EntryRepositoryFactory(); | |
41 | |
42 private Map theRepositories = new HashMap(); | |
43 | |
44 private boolean logCountOnBoot; | |
45 private boolean haveRegisteredForSnapshot = false; | |
46 private Object theLogLock = new Object(); | |
47 | |
48 private EntryRepositoryFactory() { | |
49 try { | |
50 long myReapTime = | |
51 ((Long) | |
52 ConfigurationFactory.getEntry("leaseReapInterval", | |
53 long.class, | |
54 new Long(0))).longValue(); | |
55 | |
56 InputStream myStream = | |
57 getClass().getResourceAsStream("filters.properties"); | |
58 | |
59 if (myStream == null) | |
60 throw new RuntimeException("Reap filters are missing!"); | |
61 else { | |
62 Configuration myConfig = | |
63 new ConfigurationFile(new InputStreamReader(myStream), | |
64 null); | |
65 | |
66 theReaper = new LeaseReaper(myConfig, myReapTime); | |
67 } | |
68 | |
69 } catch (Exception anE) { | |
70 theLogger.log(Level.SEVERE, "Failed to init reaper", anE); | |
71 throw new RuntimeException("Critical failure starting reaper"); | |
72 } | |
73 | |
74 /* | |
75 Figure out if instance counts should be put into checkpoints and | |
76 log files. Note we don't actually do anymore work here. The | |
77 remainder is done using barrier methods in this class and in | |
78 EntryReposImpl. | |
79 | |
80 EntryReposImpl is responsible for trapping "first use" and emitting | |
81 a record into the log. | |
82 | |
83 EntryRepositoryFactory is responsible for placing similar records | |
84 into the checkpoint snapshot. | |
85 */ | |
86 try { | |
87 logCountOnBoot = | |
88 ((Boolean) | |
89 ConfigurationFactory.getEntry(LOG_COUNTS, | |
90 Boolean.class, | |
91 new Boolean(false))).booleanValue(); | |
92 | |
93 } catch (ConfigurationException aCE) { | |
94 theLogger.log(Level.SEVERE, | |
95 "Failed to load logInstanceCounts setting", aCE); | |
96 } | |
97 | |
98 Disk.add(this); | |
99 } | |
100 | |
101 public static void reap() { | |
102 theReaper.reap(); | |
103 } | |
104 | |
105 public static EntryRepositoryFactory get() { | |
106 /* | |
107 Anyone wishing to access the factory's functions must go through | |
108 this method first so it's the ideal place to barrier for registering | |
109 with TxnManager to supply instance count records to checkpoints. | |
110 */ | |
111 theReposFactory.registerBarrier(); | |
112 | |
113 return theReposFactory; | |
114 } | |
115 | |
116 /* | |
117 Unfortunately, we may be instantiated during recovery at which point | |
118 the transaction manager is not available so we must stave off | |
119 registration of our SnapshotContributor until recovery is completed. | |
120 */ | |
121 private void registerBarrier() { | |
122 synchronized(theLogLock) { | |
123 if (!logCountOnBoot || TxnManager.get().isRecovery()) | |
124 return; | |
125 else if (!haveRegisteredForSnapshot) { | |
126 /* | |
127 If we have to log counts at boot we also need to log them at | |
128 checkpoints - register SnapshotContributor | |
129 */ | |
130 TxnManager.get().add(this); | |
131 haveRegisteredForSnapshot = true; | |
132 } | |
133 } | |
134 } | |
135 | |
136 public Serializable getContribution() { | |
137 EntryReposImpl[] myRepos = getRepositoriesSnapshot(); | |
138 | |
139 InstanceCheckpoint myContribution = new InstanceCheckpoint(); | |
140 | |
141 for (int i = 0; i < myRepos.length; i++) { | |
142 myContribution.add(myRepos[i].getType(), | |
143 myRepos[i].getTotalLiveEntries()); | |
144 } | |
145 | |
146 return myContribution; | |
147 } | |
148 | |
149 public boolean isDebugLogging() { | |
150 return logCountOnBoot; | |
151 } | |
152 | |
153 /** | |
154 Locate the EntryRepository instance for the specified type, creating | |
155 a new, empty one, if it's not already present | |
156 */ | |
157 public synchronized EntryRepository get(String aType) | |
158 throws IOException { | |
159 EntryReposImpl myRepos = (EntryReposImpl) theRepositories.get(aType); | |
160 | |
161 if (myRepos == null) { | |
162 Storage myStore = StorageFactory.getStorage(aType); | |
163 myStore.init(false); | |
164 | |
165 myRepos = new EntryReposImpl(myStore); | |
166 theRepositories.put(aType, myRepos); | |
167 } | |
168 | |
169 return myRepos; | |
170 } | |
171 | |
172 /** | |
173 Locate the EntryRepository instance for the specified type. | |
174 If it doesn't already exist, return <code>null</code>. | |
175 */ | |
176 public synchronized EntryRepository find(String aType) | |
177 throws IOException { | |
178 | |
179 EntryReposImpl myRepos = (EntryReposImpl) theRepositories.get(aType); | |
180 | |
181 if (myRepos == null) { | |
182 Storage myStore = StorageFactory.getStorage(aType); | |
183 | |
184 if (myStore.init(true)) { | |
185 myRepos = new EntryReposImpl(myStore); | |
186 theRepositories.put(aType, myRepos); | |
187 } | |
188 } | |
189 | |
190 return myRepos; | |
191 } | |
192 | |
193 synchronized EntryReposRecovery getAdmin(String aType) | |
194 throws IOException { | |
195 return (EntryReposRecovery) get(aType); | |
196 } | |
197 | |
198 public void sync() throws Exception { | |
199 EntryReposImpl[] myRepositories = getRepositoriesSnapshot(); | |
200 | |
201 for (int i = 0; i < myRepositories.length; i++) { | |
202 myRepositories[i].sync(); | |
203 } | |
204 } | |
205 | |
206 public void close() throws Exception { | |
207 EntryReposImpl[] myRepositories = getRepositoriesSnapshot(); | |
208 | |
209 for (int i = 0; i < myRepositories.length; i++) { | |
210 myRepositories[i].close(); | |
211 } | |
212 } | |
213 | |
214 private EntryReposImpl[] getRepositoriesSnapshot() { | |
215 synchronized(this) { | |
216 Collection myRepositories = theRepositories.values(); | |
217 | |
218 EntryReposImpl[] myResult = | |
219 new EntryReposImpl[myRepositories.size()]; | |
220 | |
221 return (EntryReposImpl[]) myRepositories.toArray(myResult); | |
222 } | |
223 } | |
224 | |
225 public void deleteAllEntrys() throws IOException { | |
226 EntryReposImpl[] myRepos = getRepositoriesSnapshot(); | |
227 | |
228 for (int i = 0; i < myRepos.length; i++) { | |
229 myRepos[i].deleteAllEntrys(); | |
230 } | |
231 } | |
232 | |
233 public void deleteAllRepos() throws IOException { | |
234 // For each repository, close them and invoke delete | |
235 synchronized(this) { | |
236 EntryReposImpl[] myRepos = getRepositoriesSnapshot(); | |
237 | |
238 for (int i = 0; i < myRepos.length; i++) { | |
239 myRepos[i].close(); | |
240 myRepos[i].delete(); | |
241 } | |
242 | |
243 theRepositories.clear(); | |
244 } | |
245 } | |
246 | |
247 static LeaseReaper getReaper() { | |
248 return theReaper; | |
249 } | |
250 } |