package edu.berkeley.lipstick.util.serializer; import edu.berkeley.lipstick.util.DataWrapper; import edu.berkeley.lipstick.util.KeyDependency; import edu.berkeley.lipstick.util.KeyDependencySet; import edu.berkeley.lipstick.util.WriteClock; import java.io.*; import java.nio.ByteBuffer; public class CustomDWSerializer implements IDWSerializer { private static final ThreadLocal<ByteBuffer> threadBuf = new ThreadLocal<ByteBuffer>(){ @Override protected ByteBuffer initialValue() { return ByteBuffer.allocate(4096); } }; private void putString(String s) { byte[] sBytes = s.getBytes(); threadBuf.get().putShort((short) sBytes.length); threadBuf.get().put(sBytes); } private void putClock(WriteClock wc) { threadBuf.get().putShort((short) wc.getWriters().size()); for(String writer : wc.getWriters()) { putString(writer); threadBuf.get().putInt((int) wc.getValue(writer)); } } private void putKeyDependency(String key, KeyDependency kd) { putString(key); putClock(kd.getClock()); } public byte[] toByteArray(DataWrapper input) throws Exception { ByteBuffer buf = threadBuf.get(); buf.clear(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos); out.writeObject(input.getValue()); out.close(); buf.putShort((short)bos.size()); buf.put(bos.toByteArray()); buf.putLong(input.getTimestamp()); buf.putShort((short) input.getKeyDependencySet().getDependencies().size()); for(String kdString : input.getKeyDependencySet().getKeys()) { putKeyDependency(kdString, input.getDependency(kdString)); } byte[] b = new byte[buf.position()]; buf.rewind(); buf.get(b); return b; } private String getString(ByteBuffer buf) { short len = buf.getShort(); byte[] strBytes = new byte[len]; buf.get(strBytes); return new String(strBytes); } private KeyDependency getKeyDependency(ByteBuffer buf) { WriteClock wc = new WriteClock(); short entries = buf.getShort(); for(int i = 0; i < entries; ++i) { String writer = getString(buf); int value = buf.getInt(); wc.setValue(writer, value); } return new KeyDependency(wc); } public DataWrapper fromByteArray(String key, byte[] input) throws Exception { ByteBuffer buf = ByteBuffer.wrap(input); short valueLen = buf.getShort(); byte[] valueBytes = new byte[valueLen]; buf.get(valueBytes); ByteArrayInputStream bis = new ByteArrayInputStream(valueBytes); ObjectInput in = new ObjectInputStream(bis); Object o = in.readObject(); in.close(); long timestamp = buf.getLong(); KeyDependencySet kds = new KeyDependencySet(); DataWrapper ret = new DataWrapper(key, o, kds, timestamp); short kdsSize = buf.getShort(); for(short i = 0; i < kdsSize; ++i) { String depKey = getString(buf); kds.putDependency(depKey, getKeyDependency(buf)); } return ret; } }