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 }