KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > store > ExternalisableHelper


1 package com.jofti.store;
2
3 import java.io.IOException JavaDoc;
4 import java.io.ObjectInputStream JavaDoc;
5 import java.io.ObjectOutputStream JavaDoc;
6 import java.nio.ByteBuffer JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13
14 import com.jofti.btree.IPage;
15 import com.jofti.btree.KeyValueObject;
16 import com.jofti.btree.LeafNodeEntry;
17 import com.jofti.btree.MaxLeafNodeEntry;
18 import com.jofti.btree.ValueObject;
19 import com.jofti.core.IStoreManager;
20 import com.jofti.exception.JoftiException;
21 import com.jofti.util.ByteBufferArrayInputStream;
22 import com.jofti.util.FastByteArrayOutputStream;
23
24 /**
25  *
26  * Helper to aid in the serialization and deserialization of Stored Leaf Nodes.
27  * <p>
28  * @author xenephon (xenephon@jofti.com)
29  *
30  */

31 public class ExternalisableHelper {
32
33     private static final byte STRING = 0;
34
35     private static final byte LONG = 1;
36
37     private static final byte INTEGER = 2;
38
39     private static final byte BOOLEAN = 3;
40
41     private static final byte OTHER = 4;
42
43     private static final byte MAX_ENTRY = 0;
44
45     private static final byte LEAF_ENTRY = 1;
46
47     private static final byte NULL_ENTRY = 2;
48
49     private static final byte KEY_VALUE = 1;
50
51     private static final byte VALUE_OBJECT = 2;
52     
53     private static Log log = LogFactory.getLog(ExternalisableHelper.class);
54
55     FastByteArrayOutputStream nodeFbos = null;
56
57     ByteBufferArrayInputStream bybuf = null;
58
59     ObjectOutputStream JavaDoc nodeOut = null;
60
61     AbstractStoreManager manager = null;
62
63     int nodeSize = 0;
64
65     public void init(int nodeSize, int blockSize, IStoreManager manager)
66             throws JoftiException
67     {
68         bybuf = new ByteBufferArrayInputStream(null);
69         nodeFbos = new FastByteArrayOutputStream(blockSize);
70         try {
71             nodeOut = new ObjectOutputStream JavaDoc(nodeFbos);
72
73             nodeOut.useProtocolVersion(1);
74         } catch (Exception JavaDoc e) {
75             throw new JoftiException(e);
76         }
77         this.nodeSize = nodeSize;
78         this.manager = (AbstractStoreManager) manager;
79     }
80
81
82     public LeafNodeEntry convertFromStore(ByteBuffer JavaDoc buf)
83             throws JoftiException
84     {
85
86         ObjectInputStream JavaDoc in = null;
87         LeafNodeEntry entry = null;
88
89         try {
90
91             bybuf.resetData(buf);
92             // unfortunately we have to create a new stream here
93
in = new ObjectInputStream JavaDoc(bybuf);
94
95             // get the type of entry
96
byte type = in.readByte();
97
98             if (type == NULL_ENTRY) {
99                 //we can leave here
100
return null;
101             } else if (type == MAX_ENTRY) {
102
103                 entry = new MaxLeafNodeEntry();
104             } else {
105                 if (entry == null) {
106                     entry = new LeafNodeEntry();
107                 }
108             }
109
110             // get the value object
111
Object JavaDoc obj = readValue(in);
112
113             // get value object type
114
type = in.readByte();
115
116             //get the dimension
117
int dimension = in.readInt();
118
119             if (type == KEY_VALUE) {
120
121                 // get the number of entries in hashmap
122
// we assume that there are no more than 256 dimensions for a
123
// key value
124
byte j = in.readByte();
125
126                 Map JavaDoc map = new HashMap JavaDoc(j);
127                 for (int k = 0; k < j; k++) {
128                     map.put(readValue(in), readValue(in));
129                 }
130                 entry.value = new KeyValueObject(dimension, (Comparable JavaDoc) obj,
131                         map);
132
133             } else {
134
135                 entry.value = new ValueObject(dimension, (Comparable JavaDoc) obj);
136
137             }
138             // get number of entries in set - mostly will be few
139
int l = in.readInt();
140
141             for (int k = 0; k < l; k++) {
142                 entry.addUniqueId(readValue(in));
143             }
144
145         } catch (Exception JavaDoc e) {
146             throw new JoftiException("Unable to read entry " + buf, e);
147         } finally {
148             // make sure we close the input stream
149
if (in != null) {
150                 try {
151                     in.close();
152                 } catch (Exception JavaDoc e) {
153                     // put a warning here
154
}
155                 in = null;
156             }
157         }
158
159         return entry;
160
161     }
162
163     public byte[] convertForStore(LeafNodeEntry entry) throws JoftiException
164     {
165         byte[] res =null;
166         try {
167         if (entry instanceof MaxLeafNodeEntry) {
168             // maxLeafNodeEntry
169
nodeOut.writeByte(MAX_ENTRY);
170
171         } else {
172             //LeafNodeEntry
173
nodeOut.writeByte(LEAF_ENTRY);
174         }
175         // write out the value
176

177         ValueObject valObj = (ValueObject) entry.value;
178
179         writeValue(nodeOut, valObj.getRealValue());
180
181         //write out the key value
182
if (entry.value instanceof KeyValueObject) {
183             //type for ke yvalue object
184
nodeOut.writeByte(KEY_VALUE);
185
186             //write the dimension
187
nodeOut.writeInt(((ValueObject) entry.value).getDimension());
188
189             // write out the attributes
190
Map JavaDoc map = ((KeyValueObject) valObj).getAttributes();
191
192             // write out the size of the key value attributes
193
nodeOut.writeByte((byte) map.size());
194             Iterator JavaDoc it = map.entrySet().iterator();
195             for (int i = 0; i < map.size(); i++) {
196                 Map.Entry JavaDoc mapEntry = (Map.Entry JavaDoc) it.next();
197                 writeValue(nodeOut, mapEntry.getKey());
198                 writeValue(nodeOut, mapEntry.getValue());
199
200             }
201
202         } else {
203             //write out type of value object
204
nodeOut.writeByte(VALUE_OBJECT);
205
206             //write out dimension
207
nodeOut.writeInt(((ValueObject) entry.value).getDimension());
208         }
209
210         int size = entry.getUniqueIdSize();
211
212         nodeOut.writeInt(size);
213         if (size > 0) {
214             Iterator JavaDoc it = entry.uniqueIdSet.iterator();
215             for (int i = 0; i < size; i++) {
216                 writeValue(nodeOut, it.next());
217             }
218         }
219
220         nodeOut.flush();
221         size = nodeFbos.getSize();
222         byte[] tempData = nodeFbos.getByteArray();
223         res = new byte[size];
224
225         System.arraycopy(tempData, 0, res, 0, size);
226
227         nodeOut.reset();
228         nodeFbos.reset();
229
230         } catch (Throwable JavaDoc t){
231             throw new JoftiException("Unable to serialize entry "+ entry,t);
232         }
233         return res;
234
235     }
236
237
238     IPage readExternalBuffer(java.nio.ByteBuffer JavaDoc buffer, int numberEntries)
239             throws JoftiException
240     {
241
242         IPage page = manager.doGetNewPage(buffer.limit());
243
244         ByteBuffer JavaDoc pBuf = page.getBuffer();
245
246         int[] pointers = page.getPointers();
247         
248         try {
249             pBuf.clear();
250             pBuf.put(buffer);
251             pBuf.flip();
252             pBuf.mark();
253
254             // lets loop through the entries
255
for (int i = 0; i < numberEntries; i++) {
256
257                 // first get the size of each entry
258
pointers[i] = pBuf.position();
259                 int size = pBuf.getInt();
260                 // set the position of the entry
261
pBuf.position(pBuf.position() + size);
262
263             }
264             pBuf.reset();
265
266         } catch (Throwable JavaDoc e) {
267             log.fatal("expected to read " + numberEntries + " pos at "
268                     + buffer);
269             throw new JoftiException("unable to read block ", e);
270         }
271         return page;
272
273     }
274
275     
276     private void writeValue(ObjectOutputStream JavaDoc out, Object JavaDoc obj)
277             throws IOException JavaDoc {
278         Class JavaDoc clazz = obj.getClass();
279         if (clazz == String JavaDoc.class) {
280             out.writeByte(STRING);
281
282             out.writeUTF((String JavaDoc) obj);
283
284         } else if (clazz == Integer JavaDoc.class) {
285             out.writeByte(INTEGER);
286             out.writeInt(((Integer JavaDoc) obj).intValue());
287
288         } else if (clazz == Long JavaDoc.class) {
289             out.writeByte(LONG);
290             out.writeLong(((Long JavaDoc) obj).longValue());
291         } else {
292             out.writeByte(OTHER);
293             out.writeObject(obj);
294         }
295     }
296
297     private Object JavaDoc readValue(ObjectInputStream JavaDoc in) throws IOException JavaDoc,
298             ClassNotFoundException JavaDoc {
299         int valType = in.readByte();
300         switch (valType) {
301         case STRING:
302             return in.readUTF();
303         case INTEGER:
304             return new Integer JavaDoc(in.readInt());
305
306         case LONG:
307             return new Long JavaDoc(in.readLong());
308         default:
309             return in.readObject();
310         }
311
312     }
313 }
Popular Tags