changeset 161:66e9cebce3fa first_channels

move from pathfinder.simulator.channels.*
author kent
date Tue, 26 Aug 2008 19:46:37 +0900
parents e9047957acc2
children d96717ca6270
files src/pathfinder/mergetest/channels/ChannelSimulator.java src/pathfinder/mergetest/channels/NetworkSimulator.java src/pathfinder/mergetest/channels/SelectableChannelSimulator.java src/pathfinder/mergetest/channels/SelectionKeySimulator.java src/pathfinder/mergetest/channels/SelectorSimulator.java src/pathfinder/mergetest/channels/ServerChannelSimulator.java
diffstat 6 files changed, 424 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/ChannelSimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,66 @@
+package pathfinder.mergetest.channels;
+
+
+public class ChannelSimulator<P> extends SelectableChannelSimulator<P>{
+	//private BlockingQueue<P> qread;
+	//private BlockingQueue<P> qwrite;
+	//private SelectorSimulator<P> waitingSelector;
+	protected NetworkSimulator<P> ns;
+
+	/**  Constructors. */
+	public ChannelSimulator(NetworkSimulator<P> _ns){
+		this(_ns, null);
+	}
+	public ChannelSimulator(NetworkSimulator<P> _ns, SelectorSimulator<P> _selector){
+		ns = _ns;
+		//ns = NetworkSimulator.singleton();  //どっちがいい?
+	}
+	public ChannelSimulator<P> createConjugatedChannel() {
+		ChannelSimulator<P> ret = new ChannelSimulator<P>(ns);
+		ret.qread=qwrite;
+		ret.qwrite=qread;
+		ret.readSelector=writeSelector;
+		ret.writeSelector=readSelector;
+		return ret;
+	}
+
+	/** Connecting methods */
+	// for clients.
+	public boolean connect(int ip){
+		return ns.connect(ip, this);
+	}
+	
+	public ChannelSimulator<P> accept(){
+		return null;
+	}
+
+	/* return state of the Queue(debug)  */
+	/*
+	public boolean readQisEmpty() {
+		return qread.isEmpty();
+	}
+	public boolean writeQisEmpty() {
+		return qwrite.isEmpty();
+	}
+	*/
+	
+	@Override
+	public boolean isAcceptable() {
+		return false;
+	}
+	@Override
+	public boolean isReadable() {
+		synchronized (qread){ 
+		return !qread.isEmpty();
+		}
+	}
+	@Override
+	public boolean isWritable() {
+		return true;
+	}
+
+	public SelectionKeySimulator<P> keyFor(SelectorSimulator<P> selector2) {
+		return selector2.getKey(this);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/NetworkSimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,126 @@
+package pathfinder.mergetest.channels;
+
+import java.util.LinkedList;
+
+
+public class NetworkSimulator<P> {
+	public static NetworkSimulator<?> ns;
+	synchronized public static <T> NetworkSimulator<T> singleton(){
+		if (ns==null)
+			ns = new NetworkSimulator<T>();
+		return (NetworkSimulator<T>) ns;
+		// NetworkSimulator<Obj> ns = NetworkSimulator.singleton(new NetworkSimulator<Obj>());
+	}
+
+	int logLevel=5;
+	/** Listening Servers. */
+	private LinkedList<ServerData<P>> serverList;
+
+	/** Constructor. */
+	public NetworkSimulator(){
+		serverList = new LinkedList<ServerData<P>>();
+		writeLog("construct Networksimulator", 1);
+		printAllState();
+	}
+
+		
+	
+	/*   */
+	synchronized public void listen(int ip, SelectorSimulator<P> selector) {
+		serverList.add(new ServerData<P>(ip, selector));
+		writeLog(Thread.currentThread(), "listen", 1);
+		printAllState();
+	}
+
+	synchronized public ChannelSimulator<P> accept(int ip) {
+		for (ServerData<P> sd: serverList){
+			if (sd.virtualIP!=ip) continue;
+			writeLog(Thread.currentThread(), "accepting..", 1);
+
+			ChannelSimulator<P> serverCH = sd.acceptWaitingList.remove();
+			sd.establishedList.add(serverCH);
+
+			writeLog(Thread.currentThread(), "accepted", 1);
+			printAllState();
+			return serverCH;
+		}
+		return null;
+	}
+	synchronized public boolean canAccept(int ip){
+		for (ServerData<P> sd: serverList){
+			if (sd.virtualIP!=ip) continue;
+			return !sd.acceptWaitingList.isEmpty();
+		}
+		return false;
+	}
+
+	public boolean connect(int ip, ChannelSimulator<P> clientCH) {
+		ServerData<P> sd = null;
+		writeLog(Thread.currentThread(), "connecting..", 1);
+		synchronized (this){
+			for (ServerData<P> sd0: serverList){
+				if (sd0.virtualIP!=ip) continue;
+				
+				sd = sd0;
+			}	
+			if (sd==null) return false;
+
+			//ChannelSimulator<P> channel = new ChannelSimulator<P>(sd.selector);
+			clientCH.createReadQ();
+			clientCH.createWriteQ();
+			clientCH.setWriteSelector(sd.selector);
+
+			ChannelSimulator<P> serverCH = clientCH.createConjugatedChannel();
+			sd.acceptWaitingList.add(serverCH);
+		}
+
+		synchronized (sd.selector) {
+			sd.selector.notifyAll();
+		}
+		writeLog(Thread.currentThread(), "connected", 1);
+		printAllState();
+		return true;
+	}
+
+	/** for DEBUG methods. */
+	synchronized void printAllState(){
+		writeLog("NetworkSimulator State:");
+		for (ServerData<P> sd: serverList){
+			writeLog("\tSessionManager(ip="+sd.virtualIP+"): ");
+			writeLog("\tacceptWaitingList="+sd.acceptWaitingList.size());
+			writeLog("\testablishedList="+sd.establishedList.size());
+		}
+	}
+	
+	/** simulation log command */
+	synchronized public void writeLog(String log, int level){
+		if ( level<=logLevel )
+			System.out.println(log);
+		System.out.flush();
+	}
+	public void writeLog(String log){
+		writeLog(log, 0);
+	}
+	public void writeLog(Thread thr, String log, int level){
+		writeLog(thr.getName()+": "+log, level);
+	}
+	public void setLogLevel(int logLevel) {
+		this.logLevel = logLevel;
+	}
+
+
+}
+
+class ServerData<P> {
+	int virtualIP;
+	SelectorSimulator<P> selector;
+	LinkedList<ChannelSimulator<P>> acceptWaitingList;
+	LinkedList<ChannelSimulator<P>> establishedList;
+
+	ServerData(int ip, SelectorSimulator<P> _selector){
+		virtualIP = ip;
+		selector = _selector;
+		acceptWaitingList = new LinkedList<ChannelSimulator<P>>();
+		establishedList = new LinkedList<ChannelSimulator<P>>();
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/SelectableChannelSimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,71 @@
+package pathfinder.mergetest.channels;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+
+public abstract class SelectableChannelSimulator<P> {
+	protected BlockingQueue<P> qread;
+	protected BlockingQueue<P> qwrite;
+	protected SelectorSimulator<P> writeSelector;
+	protected SelectorSimulator<P> readSelector;
+	
+	/* read from Queue.  */
+	public P read(){
+		try {
+			if(readSelector!=null)
+				synchronized (readSelector){
+					return qread.take();
+				}
+			else{
+				return qread.take();
+			}
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	/* write to Queue.  */
+	public boolean write(P p){
+		try {
+			if (writeSelector!=null)
+				synchronized (writeSelector){
+					qwrite.put(p);
+					writeSelector.notifyAll();
+				}
+			else {
+				qwrite.put(p);
+			}
+			return true;
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	public abstract ChannelSimulator<P> accept();
+	
+	/* accessor methods.  */
+	public BlockingQueue<P> getReadQ(){
+		return qread;
+	}
+	public BlockingQueue<P> getWriteQ(){
+		return qwrite;
+	}
+	public void createReadQ(){
+		qread = new LinkedBlockingQueue<P>();
+	}
+	public void createWriteQ(){
+		qwrite = new LinkedBlockingQueue<P>();
+	}
+	public void setWriteSelector(SelectorSimulator<P> _selector){
+		writeSelector = _selector; 
+	}
+
+
+	/* return state of the Queue */
+	abstract public boolean isReadable();
+	abstract public boolean isWritable();
+	abstract public boolean isAcceptable();
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/SelectionKeySimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,52 @@
+package pathfinder.mergetest.channels;
+
+public class SelectionKeySimulator<P> {
+
+	public static final int OP_READ = 0x01;
+	public static final int OP_ACCEPT = 0x02;
+	public static final int OP_WRITE = 0x04;
+	
+	private int interestOpt;
+	private SelectableChannelSimulator<P> channel;
+	private Object attachment;
+
+	public SelectionKeySimulator(SelectableChannelSimulator<P> cs, int opt) {
+		channel = cs;
+		interestOpt = opt;
+	}
+
+	public boolean isAble() {
+		if ( (interestOpt&OP_READ)!=0 && isReadable() )
+			return true;
+		else if( (interestOpt&OP_ACCEPT)!=0 && isAcceptable() )
+			return true;
+		else if( (interestOpt&OP_WRITE)!=0 && isWritable() )
+			return true;
+		else
+			return false;
+	}
+
+	public boolean isAcceptable() {
+		return channel.isAcceptable();
+	}
+
+	public boolean isReadable() {
+		return channel.isReadable();
+	}
+	public boolean isWritable() {
+		return channel.isWritable();
+	}
+
+	public SelectableChannelSimulator<P> channel() {
+		return channel;
+	}
+
+	public Object attachment() {
+		return attachment;
+	}
+
+	public void attach(Object handler) {
+		attachment = handler;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/SelectorSimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,67 @@
+package pathfinder.mergetest.channels;
+
+import java.io.IOException;
+import java.util.ArrayList;
+//import java.util.Set; //書き直す?
+
+
+
+public class SelectorSimulator<P> {
+	
+	private ArrayList<SelectionKeySimulator<P>> keyList;
+	private ArrayList<SelectionKeySimulator<P>> selectedKeys;
+	
+	public SelectorSimulator() {
+		// TODO Auto-generated constructor stub
+		keyList = new ArrayList<SelectionKeySimulator<P>>();
+	}
+
+	public int select() throws IOException {
+		selectedKeys = new ArrayList<SelectionKeySimulator<P>>();
+		
+		synchronized(this) {
+
+			while(selectedKeys.isEmpty()){
+				for(SelectionKeySimulator<P> key : keyList){
+					if(key.isAble())
+						selectedKeys.add(key);
+				}
+
+				if(selectedKeys.isEmpty())
+					try {
+						this.wait();
+					} catch (InterruptedException e) {
+						throw new IOException("Error, Selector was interrupted!");
+					}
+			}
+		}
+		return selectedKeys.size();
+	}
+	
+	public SelectionKeySimulator<P> register(SelectableChannelSimulator<P> cs, int opt){
+		SelectionKeySimulator<P> key = new SelectionKeySimulator<P>(cs, opt);
+		keyList.add(key);
+		return key;
+	}
+	
+	public SelectionKeySimulator<P> register(ChannelSimulator<P> cs, int opt, Object handler){
+		SelectionKeySimulator<P> key = new SelectionKeySimulator<P>(cs, opt);
+		key.attach(handler);
+		keyList.add(key);
+		return key;
+	}
+
+	public ArrayList<SelectionKeySimulator<P>> selectedKeys() {
+		
+		return selectedKeys;
+	}
+	
+	public SelectionKeySimulator<P> getKey(ChannelSimulator<P> channel){
+		for(SelectionKeySimulator<P> key : keyList){
+			if(key.channel() == channel)
+				return key;
+		}
+		return null;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/mergetest/channels/ServerChannelSimulator.java	Tue Aug 26 19:46:37 2008 +0900
@@ -0,0 +1,42 @@
+package pathfinder.mergetest.channels;
+
+
+
+public class ServerChannelSimulator<P>extends SelectableChannelSimulator<P>{
+	protected NetworkSimulator<P> ns;
+	private int virtualIP;
+
+	/**  Constructors. */
+	public ServerChannelSimulator(NetworkSimulator<P> _ns, SelectorSimulator<P> rselector){
+		ns = _ns;
+		readSelector = rselector;
+		writeSelector = null;
+		qread = null;
+		qwrite = null;
+	}
+
+	/** Connecting methods */
+	// for servers.
+	public void bind(int ip){
+		virtualIP = ip;
+		ns.listen(ip, readSelector);
+	}
+
+	public ChannelSimulator<P> accept(){
+		ChannelSimulator<P> channel = ns.accept(virtualIP);
+		return channel;
+	}
+
+
+	/* state check methods for SelectionKeySimulator. */
+	public boolean isReadable() {
+		return false;
+	}
+	public boolean isWritable() {
+		return false;
+	}
+	public boolean isAcceptable() {
+		return ns.canAccept(virtualIP);
+	}
+
+}