Mercurial > hg > blitz_condensed
comparison src/org/dancres/blitz/entry/RootStorage.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.FileNotFoundException; | |
5 | |
6 import java.util.logging.*; | |
7 | |
8 import java.util.ArrayList; | |
9 import org.dancres.blitz.entry.ci.CacheIndexer; | |
10 | |
11 import org.dancres.blitz.mangler.MangledField; | |
12 import org.dancres.blitz.mangler.MangledEntry; | |
13 | |
14 import org.dancres.util.BytePacker; | |
15 | |
16 import org.dancres.blitz.Logging; | |
17 import org.dancres.blitz.config.EntryConstraints; | |
18 | |
19 import org.dancres.util.ObjectTransformer; | |
20 | |
21 import org.dancres.blitz.meta.RegistryFactory; | |
22 import org.dancres.blitz.meta.Registry; | |
23 | |
24 import org.dancres.blitz.disk.DiskTxn; | |
25 import org.dancres.blitz.disk.Disk; | |
26 | |
27 import org.dancres.blitz.oid.Allocator; | |
28 import org.dancres.blitz.oid.AllocatorFactory; | |
29 import org.dancres.blitz.oid.OID; | |
30 | |
31 import org.dancres.blitz.arc.BackingStore; | |
32 | |
33 import org.dancres.blitz.cache.Identifiable; | |
34 import org.dancres.blitz.cache.Identifier; | |
35 import org.dancres.blitz.cache.CacheListener; | |
36 | |
37 import org.dancres.blitz.lease.ReapFilter; | |
38 | |
39 import org.dancres.blitz.stats.TypesStat; | |
40 import org.dancres.blitz.stats.StatsBoard; | |
41 | |
42 /** | |
43 <p>Handles all responsibilities associated with the root Entry type | |
44 "java.lang.Object". This is an internal implementation detail. We | |
45 maintain a repository of java.lang.Object for the purposes of tracking | |
46 subtype information which is used when the JavaSpaces programmer invokes a | |
47 <code>take</code> or <code>read</code> on the proxy with a | |
48 <code>null</code> template. The <code>null</argument>, of course, means | |
49 find an entry of any type.</p> | |
50 | |
51 Storage of concrete instances of Entry are handled by EntryStorage. | |
52 | |
53 @see org.dancres.blitz.entry.EntryStorage | |
54 */ | |
55 class RootStorage implements Storage { | |
56 private String theType; | |
57 | |
58 /** | |
59 Required because we still store type information | |
60 */ | |
61 private Registry theMetaData; | |
62 | |
63 private ArrayList theSubtypes = new ArrayList(); | |
64 private String[] theCurrentSubtypes = new String[0]; | |
65 | |
66 private boolean noSchemaDefined = false; | |
67 | |
68 private TypesStat theTypesStat; | |
69 | |
70 private EntryConstraints theConstraints = EntryConstraints.MINIMUM; | |
71 | |
72 RootStorage() { | |
73 theType = EntryRepository.ROOT_TYPE; | |
74 CacheIndexer.newIndexer(theType, theConstraints); | |
75 } | |
76 | |
77 public int getNumEntries() throws IOException { | |
78 return 0; | |
79 } | |
80 | |
81 public EntryConstraints getConstraints() { | |
82 return theConstraints; | |
83 } | |
84 | |
85 void add(CacheListener aListener) { | |
86 } | |
87 | |
88 public String getType() { | |
89 return theType; | |
90 } | |
91 | |
92 public String getName() { | |
93 return theType; | |
94 } | |
95 | |
96 public TupleLocator findCached(MangledEntry anEntry) { | |
97 return null; | |
98 } | |
99 | |
100 /** | |
101 @return <code>true</code> if initialization succeeded in accordance | |
102 with the mustExist flag. i.e. If mustExist is true and the databases | |
103 couldn't be opened one will receive <code>false</code> NOT an | |
104 exception. | |
105 */ | |
106 public boolean init(boolean mustExist) throws IOException { | |
107 if (mustExist) { | |
108 if (! RegistryFactory.exists(theType)) | |
109 return false; | |
110 } | |
111 | |
112 try { | |
113 theMetaData = RegistryFactory.get(theType, null); | |
114 | |
115 DiskTxn myTxn = DiskTxn.newStandalone(); | |
116 | |
117 try { | |
118 byte[] mySubtypeInfo = | |
119 theMetaData.getAccessor(myTxn).loadRaw(FixedOIDs.SUBTYPES_KEY); | |
120 | |
121 if (mySubtypeInfo != null) { | |
122 theSubtypes =(ArrayList) | |
123 ObjectTransformer.toObject(mySubtypeInfo); | |
124 updateCurrentTypes(); | |
125 } | |
126 } finally { | |
127 myTxn.commit(); | |
128 } | |
129 | |
130 } catch (FileNotFoundException aFNFE) { | |
131 EntryStorage.theLogger.log(Level.SEVERE, | |
132 "Couldn't open type db", aFNFE); | |
133 throw new IOException("Couldn't open type db"); | |
134 } | |
135 | |
136 return true; | |
137 } | |
138 | |
139 /** | |
140 Tells this Repository about a subtype which has just been created | |
141 and would need to be search if this type were the specified template. | |
142 */ | |
143 public synchronized void addSubtype(String aType) throws IOException { | |
144 if (! theSubtypes.contains(aType)) { | |
145 theSubtypes.add(aType); | |
146 updateCurrentTypes(); | |
147 theMetaData.getAccessor().save(FixedOIDs.SUBTYPES_KEY, | |
148 theSubtypes); | |
149 } | |
150 } | |
151 | |
152 public synchronized String[] getSubtypes() { | |
153 return theCurrentSubtypes; | |
154 } | |
155 | |
156 /** | |
157 Called to setup schema information, create indexes etc - should only | |
158 be called once in response to <code>true</code> being returned from | |
159 <code>didntExist()</code> | |
160 */ | |
161 public synchronized void setFields(MangledField[] aSetOfFields) | |
162 throws IOException { | |
163 throw new RuntimeException("Shouldn't ever be called - noSchemaDefined is always false!"); | |
164 } | |
165 | |
166 /** | |
167 Indicates if we were created for the first time as the result of | |
168 a call to <code>EntryRepositoryFactory.get()</code>. Note that this | |
169 flag is reset after <code>setFields()</code> is called. Thus, even | |
170 if an EntryRepository has been informed of children, it will still | |
171 return <code>true</code> until <code>setFields</code> is called. | |
172 */ | |
173 public boolean noSchemaDefined() { | |
174 return noSchemaDefined; | |
175 } | |
176 | |
177 public void close() throws IOException { | |
178 theMetaData.close(); | |
179 } | |
180 | |
181 public OID getNextId() throws IOException { | |
182 throw new IOException("Shouldn't be called"); | |
183 } | |
184 | |
185 public void delete() throws IOException { | |
186 RegistryFactory.delete(theType); | |
187 } | |
188 | |
189 public void bringOutTheDead(EntryReaper aReaper) throws IOException { | |
190 return; | |
191 } | |
192 | |
193 private synchronized void updateCurrentTypes() { | |
194 if (theTypesStat == null) { | |
195 theTypesStat = new TypesStat(); | |
196 StatsBoard.get().add(theTypesStat); | |
197 } | |
198 | |
199 String[] myTypes = new String[theSubtypes.size()]; | |
200 theCurrentSubtypes = (String[]) theSubtypes.toArray(myTypes); | |
201 | |
202 theTypesStat.setTypes(theCurrentSubtypes); | |
203 } | |
204 | |
205 private KeyIndex newIndex(String aName, int anOffset) throws IOException { | |
206 throw new IOException("Shouldn't be called"); | |
207 } | |
208 | |
209 private void loadIndexes(byte[] aSetOfIndexes) | |
210 throws IOException { | |
211 } | |
212 | |
213 /* ******************************************************************* | |
214 * BackingStore impl | |
215 * *******************************************************************/ | |
216 | |
217 public void save(Identifiable anIdentifiable) throws IOException { | |
218 throw new IOException("Shouldn't be called"); | |
219 } | |
220 | |
221 public Identifiable load(Identifier anId) throws IOException { | |
222 throw new IOException("Shouldn't be called"); | |
223 } | |
224 | |
225 /* ********************************************************************* | |
226 Search code starts here | |
227 *********************************************************************/ | |
228 | |
229 /** | |
230 Return a set of potential matches based on the passed template. Note | |
231 one must test each returned tuple for an exact match across ALL keys | |
232 because this method is "speculative". It will return likely matches | |
233 it does not guarentee to have located an exact subset based on the | |
234 passed template. As a full match is necessary to avoid hash-collisions | |
235 this shouldn't be a problem. | |
236 | |
237 @param anEntry a template to use to locate matches. | |
238 | |
239 @return TupleLocator instance of <code>null</code> if there are no | |
240 possible matches. | |
241 */ | |
242 public TupleLocator find(MangledEntry anEntry) throws IOException { | |
243 return null; | |
244 } | |
245 } |