1 package com.jofti.store; 2 3 import java.io.IOException ; 4 import java.io.ObjectInputStream ; 5 import java.io.ObjectOutputStream ; 6 import java.nio.ByteBuffer ; 7 import java.util.HashMap ; 8 import java.util.Iterator ; 9 import java.util.Map ; 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 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 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 (nodeFbos); 72 73 nodeOut.useProtocolVersion(1); 74 } catch (Exception e) { 75 throw new JoftiException(e); 76 } 77 this.nodeSize = nodeSize; 78 this.manager = (AbstractStoreManager) manager; 79 } 80 81 82 public LeafNodeEntry convertFromStore(ByteBuffer buf) 83 throws JoftiException 84 { 85 86 ObjectInputStream in = null; 87 LeafNodeEntry entry = null; 88 89 try { 90 91 bybuf.resetData(buf); 92 in = new ObjectInputStream (bybuf); 94 95 byte type = in.readByte(); 97 98 if (type == NULL_ENTRY) { 99 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 Object obj = readValue(in); 112 113 type = in.readByte(); 115 116 int dimension = in.readInt(); 118 119 if (type == KEY_VALUE) { 120 121 byte j = in.readByte(); 125 126 Map map = new HashMap (j); 127 for (int k = 0; k < j; k++) { 128 map.put(readValue(in), readValue(in)); 129 } 130 entry.value = new KeyValueObject(dimension, (Comparable ) obj, 131 map); 132 133 } else { 134 135 entry.value = new ValueObject(dimension, (Comparable ) obj); 136 137 } 138 int l = in.readInt(); 140 141 for (int k = 0; k < l; k++) { 142 entry.addUniqueId(readValue(in)); 143 } 144 145 } catch (Exception e) { 146 throw new JoftiException("Unable to read entry " + buf, e); 147 } finally { 148 if (in != null) { 150 try { 151 in.close(); 152 } catch (Exception e) { 153 } 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 nodeOut.writeByte(MAX_ENTRY); 170 171 } else { 172 nodeOut.writeByte(LEAF_ENTRY); 174 } 175 177 ValueObject valObj = (ValueObject) entry.value; 178 179 writeValue(nodeOut, valObj.getRealValue()); 180 181 if (entry.value instanceof KeyValueObject) { 183 nodeOut.writeByte(KEY_VALUE); 185 186 nodeOut.writeInt(((ValueObject) entry.value).getDimension()); 188 189 Map map = ((KeyValueObject) valObj).getAttributes(); 191 192 nodeOut.writeByte((byte) map.size()); 194 Iterator it = map.entrySet().iterator(); 195 for (int i = 0; i < map.size(); i++) { 196 Map.Entry mapEntry = (Map.Entry ) it.next(); 197 writeValue(nodeOut, mapEntry.getKey()); 198 writeValue(nodeOut, mapEntry.getValue()); 199 200 } 201 202 } else { 203 nodeOut.writeByte(VALUE_OBJECT); 205 206 nodeOut.writeInt(((ValueObject) entry.value).getDimension()); 208 } 209 210 int size = entry.getUniqueIdSize(); 211 212 nodeOut.writeInt(size); 213 if (size > 0) { 214 Iterator 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 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 buffer, int numberEntries) 239 throws JoftiException 240 { 241 242 IPage page = manager.doGetNewPage(buffer.limit()); 243 244 ByteBuffer 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 for (int i = 0; i < numberEntries; i++) { 256 257 pointers[i] = pBuf.position(); 259 int size = pBuf.getInt(); 260 pBuf.position(pBuf.position() + size); 262 263 } 264 pBuf.reset(); 265 266 } catch (Throwable 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 out, Object obj) 277 throws IOException { 278 Class clazz = obj.getClass(); 279 if (clazz == String .class) { 280 out.writeByte(STRING); 281 282 out.writeUTF((String ) obj); 283 284 } else if (clazz == Integer .class) { 285 out.writeByte(INTEGER); 286 out.writeInt(((Integer ) obj).intValue()); 287 288 } else if (clazz == Long .class) { 289 out.writeByte(LONG); 290 out.writeLong(((Long ) obj).longValue()); 291 } else { 292 out.writeByte(OTHER); 293 out.writeObject(obj); 294 } 295 } 296 297 private Object readValue(ObjectInputStream in) throws IOException , 298 ClassNotFoundException { 299 int valType = in.readByte(); 300 switch (valType) { 301 case STRING: 302 return in.readUTF(); 303 case INTEGER: 304 return new Integer (in.readInt()); 305 306 case LONG: 307 return new Long (in.readLong()); 308 default: 309 return in.readObject(); 310 } 311 312 } 313 } | Popular Tags |