Mercurial > hg > Database > Alice
view src/main/java/alice/datasegment/ReceiveData.java @ 650:4289b232b3fd
nulValue
author | suruga |
---|---|
date | Fri, 02 Feb 2018 18:26:49 +0900 |
parents | b8527d1032c4 |
children | 058bff2123c8 |
line wrap: on
line source
package alice.datasegment; import java.io.*; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.zip.*; import org.msgpack.MessagePack; import org.msgpack.type.NilValue; import org.msgpack.type.Value; /** * 送られてきたDSを一時的に取っておくクラス。inputでも使用。 */ public class ReceiveData { private Object val;//for Object DS private byte[] messagePack;//for byteArray(serialized) DS private byte[] zMessagePack;//for byteArray(compressed) DS private int dataSize;//圧縮前(MessagePack)のデータサイズ private Class<?> clazz; private long time;//測定用 private boolean setTime = false; private int depth = 1; private boolean setZepped = false; private int zippedDataSize;//圧縮後のデータサイズ private static final MessagePack packer = new MessagePack(); /** * コンストラクタ。Object型のDSと圧縮のメタ情報を受け取る。 * put/update/reply用? * @param obj DS本体(Object) */ public ReceiveData(Object obj) { if (obj == null) { clazz = NilValue.class; } else { clazz = obj.getClass(); } val = obj; } /** * コンストラクタ。byteArray型のDSと圧縮のメタ情報を受け取り、byteArrayフラグを立てる。 * * @param messagePack DS本体(byteArray) */ public ReceiveData(byte[] messagePack, boolean compressed, int datasize) { this.dataSize = datasize; if (compressed){ this.zMessagePack = messagePack; } else { this.messagePack = messagePack; } } public boolean isByteArray(){ return messagePack != null | zMessagePack != null; } public boolean compressed(){ return zMessagePack != null; } public boolean serialized(){ return val == null; } public Object getObj(){ return asClass(Object.class); } public String asString(){ return asClass(String.class); } public int asInteger() { return asClass(Integer.class); } public Float asFloat() { return asClass(Float.class); } public Value getVal(){///get DS as Value type if (val == null){///val != null return null; } else { try { return packer.unconvert(val);///convert to Value type by MassagePack } catch (IOException e) { e.printStackTrace(); } return null; } } /** * DSを任意の型で取得するメソッド。 * DSがbyteArrayでなければ指定された型に変換して返す。 * DSがbyteArrayなら解凍状態にして指定された型に変換して返す。 * * @param clazz * @param <T> * @return */ public <T> T asClass(Class<T> clazz) {///javasist try { if (val != null) { return (T) val; } if (zMessagePack != null && messagePack == null) { messagePack = unzip(zMessagePack, dataSize); } return packer.read(messagePack, clazz); } catch (IOException e) {// | DataFormatException e e.printStackTrace(); return null; } } public byte[] getMessagePack(){ if (messagePack != null){ return messagePack; } else { try { messagePack = packer.write(val); setDataSize(messagePack.length); } catch (IOException e) { e.printStackTrace(); } return messagePack; } } public byte[] getZMessagePack(){ if (zMessagePack != null){ return zMessagePack; } else { try { zip(); } catch (IOException e) { e.printStackTrace(); } return zMessagePack; } } public void zip() throws IOException { LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>(); int inputIndex = 0; LinkedList<ByteBuffer> outputs = new LinkedList<ByteBuffer>(); Deflater deflater = new Deflater(); inputs.add(ByteBuffer.wrap(getMessagePack())); int len = 0; int INFLATE_BUFSIZE = 1024 * 100;//ToDo:fix ByteBuffer c1 = allocate(INFLATE_BUFSIZE);//for output while (inputIndex < inputs.size()) { ByteBuffer b1 = inputs.get(inputIndex++); deflater.setInput(b1.array(), b1.position(), b1.remaining()); if (inputIndex == inputs.size()){ deflater.finish(); } int len1 = 0; do { len1 = deflater.deflate(c1.array(), c1.position(), c1.remaining()); if (len1 > 0) { len += len1; c1.position(c1.position() + len1); if (c1.remaining() == 0) { c1.flip(); outputs.addLast(c1); c1 = allocate(INFLATE_BUFSIZE); } } } while (len1 > 0 || !deflater.needsInput()); } if (c1.position() != 0) { c1.flip(); outputs.addLast(c1); } deflater.reset(); zMessagePack = new byte[len]; int tmp = 0; for (int i = 0; i < outputs.size(); i++){ System.arraycopy(outputs.get(i).array(), 0, zMessagePack, 0 + tmp, outputs.get(i).limit());//limit? remaining? tmp += outputs.get(i).limit(); } } protected byte[] unzip(byte[] input, int dataSize) {///read header & unzip int length = input.length; Inflater inflater = new Inflater(); byte [] output = new byte [dataSize];///byteArray for unziped data inflater.setInput(input, 0, length);///set unzip data without header try { inflater.inflate(output, 0, dataSize);///unzip } catch (DataFormatException e) { e.printStackTrace(); } inflater.reset(); return output; } public ByteBuffer allocate(int size) { ByteBuffer b = null; while(true){ try { b = ByteBuffer.allocate(size); } catch (OutOfMemoryError e) { b = null; } if (b!=null) { break; } try { wait(); } catch (InterruptedException e) { } } return b; } public int getDataSize(){ return this.dataSize; } public void setDataSize(int datasize){ this.dataSize = datasize; } public void setTimes(long time, boolean setTime, int depth){ this.time = time; this.setTime = setTime; this.depth = depth; } public long getTime(){ return this.time; } public boolean getSetTime(){ return this.setTime; } public int getDepth(){ return this.depth; } public void setZipped(int zippedDataSize, boolean setZepped){ this.zippedDataSize = zippedDataSize; this.setZepped = setZepped; } public int getZippedDataSize(){ return this.zippedDataSize; } public boolean getSetZipped(){ return this.setZepped; } }