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

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

package suikwasha.distributedalgorithm.algorithms.franklin;

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

import fj.P2;

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

public class FranklinAlgorithm implements Algorithm
{
	private final long num;
	private long max;
	private static final int MESSAGE_SIZE = 9;
	
	public FranklinAlgorithm(long _num)
	{
		num = _num;
		max = 0;
	}
	
	/*
	 * message format.
	 * flag | long value 
	 * 0xFF | 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
	 */
	public static ByteBuffer s(boolean _flagMax,long _value)
	{
		ByteBuffer b = ByteBuffer.allocate(MESSAGE_SIZE); 
		b.put((_flagMax) ? (byte)1 : (byte)0);
		b.putLong(_value);
		b.rewind();
		return b;
	}

	public void execute(Context _c) throws Exception
	{
		Iterator<Port> portItr = _c.getPorts().iterator();
		Port left = portItr.next();
		Port right = portItr.next();
		
		Message receivedMessage;
		
		long a,b;
		do{
			right.send(new Message(s(false,num)));
			left.send(new Message(s(false,num)));
			
			Message mesA = right.blockingReceive();
			Message mesB = left.blockingReceive();
			
			a = mesA.getMessage().getLong(1);
			b = mesB.getMessage().getLong(1);
			
			receivedMessage = (mesA.getMessageChain().getMessageCount() < mesB.getMessageChain().getMessageCount()) ?
					mesA : mesB;
			
			if(num < a || num < b){
				// passive
				while(true){
					P2<Message,Port> ret = Commons.RECV(right,left);
					Message m = ret._1();
					Port p = (ret._2() == right) ? left : right;

					if(m.getMessage().get() == (byte)1){
						max = m.getMessage().getLong(1);
						p.send(m.newMessage(s(true,max)));

						//stop
						return;
					}
				}
			}
		}while(!(num == a || num == b));
		
		max = num;
		right.send(receivedMessage.newMessage(s(true,max)));
		
		//stop
		return;
	}
	
}