Package krati.retention

Source Code of krati.retention.SimpleEventBatchSerializer

/*
* Copyright (c) 2010-2012 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package krati.retention;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;

import krati.io.SerializationException;
import krati.io.Serializer;
import krati.retention.clock.Clock;

/**
* SimpleEventBatchSerializer
*
* <pre>
*               HEADER                                               [        EVENT         ] ...
*  ------- ---- ------ ------------ -------------- -------- -------- [----------- ----------] ...
*  int     int  long   long         long           Clock    Clock    [int         byte[]    ] ...
*  ------- ---- ------ ------------ -------------- -------- -------- [----------- ----------] ...
*  version size origin creationTime completionTime minClock maxClock [valueLength valueBytes] ...
* </pre>
*
* @version 0.4.2
* @author jwu
*
* <p>
* 08/01, 2011 - Created
*/
public class SimpleEventBatchSerializer<T> implements EventBatchSerializer<T> {
    private final Serializer<T> _valueSerializer;
    private final Serializer<Clock> _clockSerializer;
   
    public SimpleEventBatchSerializer(Serializer<T> valueSerializer, Serializer<Clock> clockSerializer) {
        this._valueSerializer = valueSerializer;
        this._clockSerializer = clockSerializer;
    }
   
    @Override
    public EventBatch<T> deserialize(byte[] bytes) throws SerializationException {
        if(bytes == null) return null;
       
        // Deserialize header first
        EventBatchHeader header = deserializeHeader(bytes);
       
        int minClockLength = header.getMinClock().values().length << 3;
        int maxClockLength = header.getMaxClock().values().length << 3;
        int headerLength = NUM_NON_CLOCK_BYTES_IN_HEADER + minClockLength + maxClockLength;
       
        try {
            ByteBuffer buffer = ByteBuffer.wrap(bytes, headerLength, bytes.length - headerLength);
            SimpleEventBatch<T> batch = new SimpleEventBatch<T>(header.getOrigin(), header.getMinClock(), header.getSize());
            batch.setCreationTime(header.getCreationTime());
            batch.setCompletionTime(header.getCompletionTime());
           
            // Read individual events
            for(int i = 0, size = header.getSize(); i < size; i++) {
                // Deserialize value
                int length = buffer.getInt();
                byte[] valueBytes = new byte[length];
                buffer.get(valueBytes);
               
                T value = _valueSerializer.deserialize(valueBytes);
               
                // Deserialize clock
                length = buffer.get();
                byte[] clockBytes = new byte[length];
                buffer.get(clockBytes);
               
                Clock clock = _clockSerializer.deserialize(clockBytes);
               
                Event<T> event = new SimpleEvent<T>(value, clock);
                if(!batch.put(event)) {
                    throw new SerializationException("Invalid clocks:" + " clock=" + clock + " minClock=" + header.getMinClock() + " maxClock=" + header.getMaxClock());
                }
            }
           
            return batch;
        } catch(SerializationException e) {
            throw e;
        } catch(Exception e) {
            throw new SerializationException("Failed to deserialize", e);
        }
    }
   
    @Override
    public byte[] serialize(EventBatch<T> object) throws SerializationException {
        if(object == null) return null;
        
        byte[] valueBytes = null;
        byte[] clockBytes = null;
        byte[] intBytes = new byte[4];
        byte[] clockLenByte = new byte[1];
        ByteBuffer bbInt = ByteBuffer.wrap(intBytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
       
        // Serialize header first
        byte[] headerBytes = serializeHeader(object);
       
        try {
            // Write header bytes
            baos.write(headerBytes);
           
            Iterator<Event<T>> iter = object.iterator();
            while(iter.hasNext()) {
                Event<T> event = iter.next();
                T value = event.getValue();
                Clock clock = event.getClock();
               
                // Serialize value
                valueBytes = _valueSerializer.serialize(value);
               
                bbInt.clear();
                bbInt.putInt(valueBytes.length);
               
                baos.write(intBytes);
                baos.write(valueBytes);
               
                // Serialize clock
                clockBytes = _clockSerializer.serialize(clock);
                clockLenByte[0] = (byte)clockBytes.length;
               
                baos.write(clockLenByte);
                baos.write(clockBytes);
            }
           
            return baos.toByteArray();
        } catch(SerializationException e) {
            throw e;
        } catch(Exception e) {
            throw new SerializationException("Failed to serialize", e);
        }
    }
   
    @Override
    public EventBatchHeader deserializeHeader(byte[] bytes) throws SerializationException {
        if(bytes == null) {
            return null;
        }
       
        ByteBuffer bb = ByteBuffer.wrap(bytes);
       
        // Version
        int version = bb.getInt();
        if(version < 0) {
            throw new SerializationException("Invalid version: " + version);
        }
       
        // Size
        int size = bb.getInt();
        if(size < 0) {
            throw new SerializationException("Invalid size: " + size);
        }
       
        // Origin
        long origin = bb.getLong();
       
        long creationTime = bb.getLong();
       
        long completionTime = bb.getLong();
       
        // minClock
        int length = bb.get();
        byte[] minClockBytes = new byte[length];
        bb.get(minClockBytes);
        Clock minClock = _clockSerializer.deserialize(minClockBytes);
       
        // maxClock
        length = bb.get();
        byte[] maxClockBytes = new byte[length];
        bb.get(maxClockBytes);
        Clock maxClock = _clockSerializer.deserialize(maxClockBytes);
       
        return new SimpleEventBatchHeader(version, size, origin, creationTime, completionTime, minClock, maxClock);
    }
   
    @Override
    public byte[] serializeHeader(EventBatchHeader header) throws SerializationException {
        if(header == null) {
            return null;
        }
       
        byte[] minClockBytes = _clockSerializer.serialize(header.getMinClock());
        byte[] maxClockBytes = _clockSerializer.serialize(header.getMaxClock());
       
        // Int Int Long Long Long Byte Clock Byte Clock
        // 4 + 4 + 8 + 8 + 8 + 1 + length + 1 + length
       
        byte[] byteArray = new byte[NUM_NON_CLOCK_BYTES_IN_HEADER + minClockBytes.length + maxClockBytes.length];
        ByteBuffer bb = ByteBuffer.wrap(byteArray);
       
        bb.putInt(header.getVersion());         // 4
        bb.putInt(header.getSize());            // 4
        bb.putLong(header.getOrigin());         // 8
        bb.putLong(header.getCreationTime());   // 8
        bb.putLong(header.getCompletionTime()); // 8
        bb.put((byte)minClockBytes.length);     // 1
        bb.put(minClockBytes);                  // minClockBytes
        bb.put((byte)maxClockBytes.length);     // 1
        bb.put(maxClockBytes);                  // maxClockBytes
       
        return byteArray;
    }
   
    private final static int NUM_NON_CLOCK_BYTES_IN_HEADER = 34;
}
TOP

Related Classes of krati.retention.SimpleEventBatchSerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.