se.sics.caracaldb.global.LookupSerializer.java Source code

Java tutorial

Introduction

Here is the source code for se.sics.caracaldb.global.LookupSerializer.java

Source

/*
 * This file is part of the CaracalDB distributed storage system.
 *
 * Copyright (C) 2009 Swedish Institute of Computer Science (SICS) 
 * Copyright (C) 2009 Royal Institute of Technology (KTH)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package se.sics.caracaldb.global;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import io.netty.buffer.ByteBuf;
import java.nio.ByteBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.sics.caracaldb.CoreSerializer;
import se.sics.caracaldb.Key;
import se.sics.caracaldb.global.SchemaData.SingleSchema;
import static se.sics.caracaldb.global.SchemaData.deserialiseSchema;
import se.sics.caracaldb.utils.CustomSerialisers;
import se.sics.kompics.address.Address;
import se.sics.kompics.network.netty.serialization.Serializer;
import se.sics.kompics.network.netty.serialization.Serializers;
import se.sics.kompics.network.netty.serialization.SpecialSerializers;
import se.sics.kompics.network.netty.serialization.SpecialSerializers.BitBuffer;
import se.sics.kompics.network.netty.serialization.SpecialSerializers.MessageSerializationUtil.MessageFields;

/**
 *
 * @author lkroll
 */
public class LookupSerializer implements Serializer {

    private static final Logger LOG = LoggerFactory.getLogger(LookupSerializer.class);

    private static final Boolean[] FORWARD = new Boolean[] { false, false };
    private static final Boolean[] SCHEMA = new Boolean[] { false, true };
    private static final Boolean[] REQUEST = new Boolean[] { true, false };
    private static final Boolean[] SAMPLE = new Boolean[] { true, true };
    // SCHEMA-
    private static final Boolean[] CREATE = new Boolean[] { false, false };
    private static final Boolean[] DROP = new Boolean[] { false, true };
    private static final Boolean[] RESP = new Boolean[] { true, false };

    @Override
    public int identifier() {
        return CoreSerializer.LOOKUP.id;
    }

    @Override
    public void toBinary(Object o, ByteBuf buf) {
        if (o instanceof ForwardMessage) {
            ForwardMessage msg = (ForwardMessage) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, FORWARD[0], FORWARD[1]);
            CustomSerialisers.serialiseKey(msg.forwardTo, buf);
            Serializers.toBinary(msg.msg, buf);
            return;
        }
        if (o instanceof SampleRequest) {
            SampleRequest msg = (SampleRequest) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, REQUEST[0], REQUEST[1]);
            buf.writeInt(msg.n);
            buf.writeBoolean(msg.schema);
            return;
        }
        if (o instanceof Sample) {
            Sample msg = (Sample) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, SAMPLE[0], SAMPLE[1]);
            buf.writeInt(msg.nodes.size());
            for (Address addr : msg.nodes) {
                SpecialSerializers.AddressSerializer.INSTANCE.toBinary(addr, buf);
            }
            if (msg.schemaData == null) {
                buf.writeInt(-1);
                return;
            }
            buf.writeInt(msg.schemaData.length);
            buf.writeBytes(msg.schemaData);
            return;
        }
        if (o instanceof Schema.CreateReq) {
            Schema.CreateReq msg = (Schema.CreateReq) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, SCHEMA[0], SCHEMA[1]);
            BitBuffer flags = BitBuffer.create(CREATE);
            byte[] flagsB = flags.finalise();
            buf.writeBytes(flagsB);
            SchemaData.serialiseSchema(buf, ByteBuffer.wrap(new byte[0]), msg.name, msg.metaData);
            return;
        }
        if (o instanceof Schema.DropReq) {
            Schema.DropReq msg = (Schema.DropReq) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, SCHEMA[0], SCHEMA[1]);
            BitBuffer flags = BitBuffer.create(DROP);
            byte[] flagsB = flags.finalise();
            buf.writeBytes(flagsB);
            byte[] nameB = msg.name.getBytes(SchemaData.CHARSET);
            buf.writeInt(nameB.length);
            buf.writeBytes(nameB);
            return;
        }
        if (o instanceof Schema.Response) {
            Schema.Response msg = (Schema.Response) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, SCHEMA[0], SCHEMA[1]);
            BitBuffer flags = BitBuffer.create(RESP);
            flags.write(msg.success);
            byte[] flagsB = flags.finalise();
            buf.writeBytes(flagsB);
            byte[] nameB = msg.name.getBytes(SchemaData.CHARSET);
            buf.writeInt(nameB.length);
            buf.writeBytes(nameB);
            if (msg.id == null) {
                buf.writeInt(-1);
            } else {
                buf.writeInt(msg.id.length);
                buf.writeBytes(msg.id);
            }
            if (msg.msg == null) {
                buf.writeInt(-1);
            } else {
                byte[] msgB = msg.msg.getBytes(SchemaData.CHARSET);
                buf.writeInt(msgB.length);
                buf.writeBytes(msgB);
            }
            return;
        }
        LOG.warn("Couldn't serialize {}: {}", o, o.getClass());
    }

    @Override
    public Object fromBinary(ByteBuf buf, Optional<Object> hint) {
        MessageFields fields = SpecialSerializers.MessageSerializationUtil.msgFromBinary(buf);
        if (matches(fields, FORWARD)) {
            Key key = CustomSerialisers.deserialiseKey(buf);
            Forwardable msg = (Forwardable) Serializers.fromBinary(buf, Optional.absent());
            return new ForwardMessage(fields.src, fields.dst, fields.orig, fields.proto, key, msg);
        }
        if (matches(fields, REQUEST)) {
            int n = buf.readInt();
            boolean schema = buf.readBoolean();
            return new SampleRequest(fields.src, fields.dst, n, schema);
        }
        if (matches(fields, SAMPLE)) {
            int size = buf.readInt();
            ImmutableSet.Builder<Address> builder = ImmutableSet.builder();
            for (int i = 0; i < size; i++) {
                Address addr = (Address) SpecialSerializers.AddressSerializer.INSTANCE.fromBinary(buf,
                        Optional.absent());
                builder.add(addr);
            }
            int schemaL = buf.readInt();
            if (schemaL < 0) {
                return new Sample(fields.src, fields.dst, builder.build(), null);
            }
            byte[] schemaData = new byte[schemaL];
            buf.readBytes(schemaData);
            return new Sample(fields.src, fields.dst, builder.build(), schemaData);
        }
        if (matches(fields, SCHEMA)) {
            byte[] flagsB = new byte[1];
            buf.readBytes(flagsB);
            boolean[] flags = BitBuffer.extract(8, flagsB);
            if (matches(flags, CREATE)) {
                SingleSchema schema = deserialiseSchema(buf);
                return new Schema.CreateReq(fields.src, fields.dst, fields.orig, schema.name, schema.meta);
            }
            if (matches(flags, DROP)) {
                int nameL = buf.readInt();
                byte[] nameB = new byte[nameL];
                buf.readBytes(nameB);
                String name = new String(nameB, SchemaData.CHARSET);
                return new Schema.DropReq(fields.src, fields.dst, fields.orig, name);
            }
            if (matches(flags, RESP)) {
                int nameL = buf.readInt();
                byte[] nameB = new byte[nameL];
                buf.readBytes(nameB);
                String name = new String(nameB, SchemaData.CHARSET);
                int idL = buf.readInt();
                byte[] id = null;
                if (idL >= 0) {
                    id = new byte[idL];
                    buf.readBytes(id);
                }
                int msgL = buf.readInt();
                String msg = null;
                if (msgL >= 0) {
                    byte[] msgB = new byte[msgL];
                    buf.readBytes(msgB);
                    msg = new String(msgB, SchemaData.CHARSET);
                }
                return new Schema.Response(fields.src, fields.dst, name, id, flags[2], msg);
            }
        }
        LOG.warn("Don't know how to deserialise fields: {}", fields);
        return null;
    }

    private boolean matches(MessageFields fields, Boolean[] type) {
        return (fields.flag1 == type[0]) && (fields.flag2 == type[1]);
    }

    private boolean matches(boolean[] flags, Boolean[] type) {
        return (flags[0] == type[0]) && (flags[1] == type[1]);
    }

}