view src/main/java/alice/datasegment/ReceiveData.java @ 523:145c425db88d dispose

add CompressedLDSM
author Nozomi Teruya <e125769@ie.u-ryukyu.ac.jp>
date Thu, 09 Apr 2015 18:36:26 +0900
parents 7ef0ebb40c9b
children 30a74eee59c7
line wrap: on
line source

package alice.datasegment;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.zip.*;

import org.apache.log4j.Logger;
import org.msgpack.type.Value;
import alice.codesegment.SingletonMessage;

/**
 * 送られてきたDSを一時的に取っておくクラス。inputでも使用。
 */
public class ReceiveData {
    private Object val;//Object型のDS
    private byte[] messagePack;//byteArray(serialized)のDS
    private byte[] zMessagePack;//byteArray(compressed)のDS
    private Class<?> clazz;
    private Logger logger = Logger.getLogger("MessagePack");

    public long time;//測定用
    public boolean setTime = false;
    public int depth = 1;

    /**
     * コンストラクタ。Object型のDSと圧縮のメタ情報を受け取る。
     * put/update用?
     * @param obj DS本体(Object)
     */
    public ReceiveData(Object obj, boolean cFlag, boolean sFlag) {
        val = obj;
         if (cFlag){
            messagePack = (byte[])val;
             ByteBuffer buf = null;

            try {
                zMessagePack = zip(messagePack);
                buf = ByteBuffer.allocate(zMessagePack.length + 1);
                buf.put((byte) 0xc1);
                buf.put(zMessagePack);
                zMessagePack = buf.array();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * コンストラクタ。byteArray型のDSと圧縮のメタ情報を受け取り、byteArrayフラグを立てる。
     *
     * @param messagePack DS本体(byteArray)
     */
    public ReceiveData(byte[] messagePack) {

        if (messagePack[0] == 0xc1){
            this.zMessagePack = messagePack;
        } else {
            this.messagePack = messagePack;
        }

        logger.debug(this.messagePack);
        logger.debug(this.zMessagePack);
    }


    public boolean isByteArray(){//byteArrayフラグの状態を取得するメソッド
        return messagePack != null;
    }

    public boolean compressed(){//compressedフラグの状態を取得するメソッド
        return zMessagePack != null;
    }

    public boolean serialized(){//serializedフラグの状態を取得するメソッド
        return val != null;
    }

    public Object getObj(){//Object型のDS本体を取得するメソッド。
        return asClass(Object.class);
    }

    public String asString(){//String型としてDSを取得するメソッド。DSがシリアライズされていればStringクラスを返す。
        return asClass(String.class);
    }

    public int asInteger(){//Int型としてDSを取得するメソッド。DSがシリアライズされていればIntクラスを返す。
        return asClass(Integer.class);
    }

    public Float asFloat(){//Float型としてDSを取得するメソッド。DSがシリアライズされていればFloatクラスを返す。
        return asClass(Float.class);
    }

    public Value getVal(){//Value型としてDSを取得するメソッド
        if (val == null){//もとはval != null
            return asClass(Value.class);
        } else {
            try {
                return SingletonMessage.getInstance().unconvert(val);//MassagePackでvalue型に変換。できなければnullを返す。
            } 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;
            }
            byte[] b = messagePack;

            if (zMessagePack != null && messagePack == null) {
                logger.debug("zMessagePack = " + zMessagePack);
                messagePack = unzip(zMessagePack);
                b = messagePack;
            }

            logger.debug("MessagePack = " + messagePack);

            if (val == null) {
                this.clazz = clazz;
                return SingletonMessage.getInstance().read(b, clazz);
            } else {
                return (T) val;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * java.util.zip.Inflater(zlib)を使ってbyteArray型のDSを解凍する。
     *
     * @param input 圧縮されたbyteArray型のDS
     * @return 解凍したbyteArray型DS
     * @throws IOException
     * @throws DataFormatException
     */
    public byte[] unzip(byte[] input) throws IOException, DataFormatException{
        Inflater inflater = new Inflater();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        InflaterOutputStream ios = new InflaterOutputStream(os, inflater);
        ios.write(input);
        ios.finish();
        return os.toByteArray();
    }

    /**
     * java.util.zip.Deflater(zlib)を使ってbyteArray型のDSを圧縮する。
     *
     * @param input 非圧縮状態のbyteArray型のDS
     * @return 圧縮したbyteArray型DS
     * @throws IOException
     */
    public byte[] zip(byte[] input) throws IOException{
        Deflater deflater = new Deflater();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        DeflaterOutputStream dos = new DeflaterOutputStream(os, deflater);
        dos.write(input);
        dos.finish();
        return os.toByteArray();
    }

}