se.sics.caracaldb.paxos.PaxosSerializer.java Source code

Java tutorial

Introduction

Here is the source code for se.sics.caracaldb.paxos.PaxosSerializer.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.paxos;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import io.netty.buffer.ByteBuf;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.sics.caracaldb.CoreSerializer;
import se.sics.caracaldb.View;
import se.sics.caracaldb.paxos.Paxos.Accept;
import se.sics.caracaldb.paxos.Paxos.Accepted;
import se.sics.caracaldb.paxos.Paxos.Forward;
import se.sics.caracaldb.paxos.Paxos.Install;
import se.sics.caracaldb.paxos.Paxos.Instance;
import se.sics.caracaldb.paxos.Paxos.NoPromise;
import se.sics.caracaldb.paxos.Paxos.PaxosMsg;
import se.sics.caracaldb.paxos.Paxos.Prepare;
import se.sics.caracaldb.paxos.Paxos.Promise;
import se.sics.caracaldb.paxos.Paxos.Rejected;
import se.sics.caracaldb.replication.log.Reconfigure;
import se.sics.caracaldb.replication.log.Value;
import se.sics.caracaldb.utils.CustomSerialisers;
import se.sics.kompics.network.Msg;
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.MessageSerializationUtil.MessageFields;

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

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

    static final byte PREPARE = 1;
    static final byte PROMISE = 2;
    static final byte NO_PROMISE = 3;
    static final byte ACCEPT = 4;
    static final byte ACCEPTED = 5;
    static final byte REJECTED = 6;
    static final byte INSTALL = 7;
    // Non PaxosMsg
    static final byte FORWARD = 10;

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

    @Override
    public void toBinary(Object o, ByteBuf buf) {
        // Non PaxosMsg
        if (o instanceof Forward) {
            Forward f = (Forward) o;
            SpecialSerializers.MessageSerializationUtil.msgToBinary(f, buf, true, false);
            buf.writeByte(FORWARD);
            Serializers.toBinary(f.p, buf);
            return;
        }
        if (!(o instanceof PaxosMsg)) {
            return;
        }
        // PaxosMsg
        PaxosMsg msg = (PaxosMsg) o;
        SpecialSerializers.MessageSerializationUtil.msgToBinary(msg, buf, false, false);
        buf.writeInt(msg.ballot);
        if (o instanceof Prepare) {
            buf.writeByte(PREPARE);
            return;
        }
        if (o instanceof Promise) {
            buf.writeByte(PROMISE);
            Promise p = (Promise) o;
            buf.writeInt(p.maxInstances.size());
            for (Instance i : p.maxInstances) {
                instanceToBinary(i, buf);
            }
            CustomSerialisers.serialiseView(p.view, buf);
            return;
        }
        if (o instanceof NoPromise) {
            buf.writeByte(NO_PROMISE);
            return;
        }
        if (o instanceof Accept) {
            buf.writeByte(ACCEPT);
            Accept a = (Accept) o;
            instanceToBinary(a.i, buf);
            return;
        }
        if (o instanceof Accepted) {
            buf.writeByte(ACCEPTED);
            Accepted a = (Accepted) o;
            instanceToBinary(a.i, buf);
            CustomSerialisers.serialiseView(a.view, buf);
            return;
        }
        if (o instanceof Rejected) {
            buf.writeByte(REJECTED);
            Rejected r = (Rejected) o;
            instanceToBinary(r.i, buf);
            return;
        }
        if (o instanceof Install) {
            buf.writeByte(INSTALL);
            Install inst = (Install) o;
            Serializers.toBinary(inst.event, buf);
            buf.writeLong(inst.highestDecided);
            buf.writeInt(inst.log.size());
            for (Entry<Long, Value> e : inst.log.entrySet()) {
                Long k = e.getKey();
                Value v = e.getValue();
                buf.writeLong(k);
                Serializers.toBinary(v, buf);
            }
            return;
        }
        LOG.error("Could not find serializer for {}:{}!", o, o.getClass());
    }

    @Override
    public Object fromBinary(ByteBuf buf, Optional<Object> hint) {
        MessageFields fields = SpecialSerializers.MessageSerializationUtil.msgFromBinary(buf);
        if (fields.flag1) {
            return otherFromBinary(fields, buf);
        } else {
            return paxosFromBinary(fields, buf);
        }
    }

    private void instanceToBinary(Instance i, ByteBuf buf) {
        buf.writeLong(i.id);
        buf.writeInt(i.ballot);
        Serializers.toBinary(i.value, buf);
    }

    private Instance instanceFromBinary(ByteBuf buf) {
        long id = buf.readLong();
        int ballot = buf.readInt();
        Value v = (Value) Serializers.fromBinary(buf, Optional.absent());
        return new Instance(id, ballot, v);
    }

    private Msg otherFromBinary(MessageFields fields, ByteBuf buf) {
        byte type = buf.readByte();
        Value val;
        switch (type) {
        case FORWARD:
            val = (Value) Serializers.fromBinary(buf, Optional.absent());
            return new Forward(fields.src, fields.dst, fields.orig, val);
        default:
            LOG.error("Unknown Msg type: {}", type);
            return null;
        }
    }

    private PaxosMsg paxosFromBinary(MessageFields fields, ByteBuf buf) {
        int ballot = buf.readInt();
        byte type = buf.readByte();
        View v;
        Instance ins;
        int size;
        switch (type) {
        case PREPARE:
            return new Prepare(fields.src, fields.dst, ballot);
        case PROMISE:
            size = buf.readInt();
            ImmutableSet.Builder<Instance> builder = ImmutableSet.builder();
            for (int i = 0; i < size; i++) {
                builder.add(instanceFromBinary(buf));
            }
            v = CustomSerialisers.deserialiseView(buf);
            return new Promise(fields.src, fields.dst, ballot, builder.build(), v);
        case NO_PROMISE:
            return new NoPromise(fields.src, fields.dst, ballot);
        case ACCEPT:
            ins = instanceFromBinary(buf);
            return new Accept(fields.src, fields.dst, ballot, ins);
        case ACCEPTED:
            ins = instanceFromBinary(buf);
            v = CustomSerialisers.deserialiseView(buf);
            return new Accepted(fields.src, fields.dst, ballot, ins, v);
        case REJECTED:
            ins = instanceFromBinary(buf);
            return new Rejected(fields.src, fields.dst, ballot, ins);
        case INSTALL:
            Reconfigure rec = (Reconfigure) Serializers.fromBinary(buf, Optional.absent());
            long highestDecided = buf.readLong();
            size = buf.readInt();
            ImmutableSortedMap.Builder<Long, Value> mBuilder = ImmutableSortedMap.naturalOrder();
            for (int i = 0; i < size; i++) {
                long k = buf.readLong();
                Value val = (Value) Serializers.fromBinary(buf, Optional.absent());
                mBuilder.put(k, val);
            }
            return new Install(fields.src, fields.dst, ballot, rec, highestDecided, mBuilder.build());
        default:
            LOG.error("Unknown PaxosMsg type: {}", type);
            return null;
        }
    }

}