view src/main/java/suikwasha/distributedalgorithm/algorithms/peterson/PertersonAlgorithm.java @ 2:8e1f63faa2fd default tip

added Franklin's Algorithm
author suikwasha
date Tue, 23 Oct 2012 16:49:26 +0900
parents 38a110b13db1
children
line wrap: on
line source

package suikwasha.distributedalgorithm.algorithms.peterson;

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

import suikwasha.distributedalgorithm.framework.Algorithm;
import suikwasha.distributedalgorithm.framework.Context;
import suikwasha.distributedalgorithm.framework.Message;
import suikwasha.distributedalgorithm.framework.Port;

public class PertersonAlgorithm implements Algorithm
{
	private final long num;
	private long max;
	
	public PertersonAlgorithm(long _num)
	{
		max = -1;
		num = _num;
	}
	
	public static ByteBuffer toByteBuffer(boolean _max,long _value)
	{
		ByteBuffer b = ByteBuffer.allocate(9); // size of (flag + long)
		if(_max){
			b.put((byte)1);
		}else{
			b.put((byte)0);
		}
		
		b.putLong(_value);
		b.rewind(); // do not forget rewind() after reading/writing
		return b.asReadOnlyBuffer(); // message is read-only
	}
	
	public void execute(Context _c)
	{
		Iterator<Port> ports = _c.getPorts().iterator();
		Port in = ports.next();
		Port out = ports.next();
		
		/*
		 * Active
		 */
		
		long temp = num;
		out.send(new Message(toByteBuffer(false,temp)));
		
		Message receivedMessage = null;
		try{
			receivedMessage = in.blockingReceive();
		}catch(InterruptedException _e){
			_e.printStackTrace();
		}
		
		ByteBuffer b = receivedMessage.getMessage();
		long next = -1;
		if(b.get() == (byte)0){
			next = b.getLong();
		}else{
			System.out.println("b.get() != 0");
		}
		
		Message newMessage;
		while(temp != next){
			newMessage = receivedMessage.newMessage(toByteBuffer(false,next));
			out.send(newMessage);
			try{
				receivedMessage = in.blockingReceive();
			}catch(InterruptedException _e){
				_e.printStackTrace();
			}
			long nnext = -1;
			b = receivedMessage.getMessage();
			if(b.get() == (byte)0){
				nnext = b.getLong();
			}
			if(next < Math.max(temp,nnext)){
				break;
			}
			if(next > Math.max(temp,nnext)){
				temp = next;
			}
			newMessage = receivedMessage.newMessage(toByteBuffer(false,temp));
			out.send(newMessage);
			newMessage = receivedMessage.newMessage(toByteBuffer(false,next));
			out.send(newMessage);
		}
		
		if(temp == next){
			max = temp;
			newMessage = receivedMessage.newMessage(toByteBuffer(true,max));
			out.send(newMessage);
			
			// stop
			return;
		}
		
		/*
		 * Passive
		 */
		while(true){
			try{
				receivedMessage = in.blockingReceive();
			}catch(InterruptedException _e){
				_e.printStackTrace();
			}
			b = receivedMessage.getMessage();
			if(b.get() == (byte)1){
				max = b.getLong();
				newMessage = receivedMessage.newMessage(toByteBuffer(true,max));
				out.send(newMessage);
				
				//stop
				return;
			}
			
			long value = b.getLong();
			newMessage = receivedMessage.newMessage(toByteBuffer(false,value));
			out.send(newMessage);
		}
	}
}