view rep/channel/NetworkSimulator.java @ 203:4c0a94836357 simullator-nio-both-worked

*** empty log message ***
author kono
date Sat, 30 Aug 2008 11:21:43 +0900
parents 723187e39311
children e72e0eae1261
line wrap: on
line source

package rep.channel;

import java.net.SocketAddress;
import java.util.HashMap;
import java.util.LinkedList;


public class NetworkSimulator<P> {
	public static NetworkSimulator<?> ns;
	

	public HashMap<SocketAddress,Integer>namedb = new HashMap<SocketAddress,Integer>();
	public int ipcount = 1;
	public REPLogger logger;
	
	@SuppressWarnings("unchecked")  // <?> から <T> へのキャストのため. 
	public static <T> NetworkSimulator<T> singleton(){
		// double check singleton
		if (ns==null)
			synchronized (NetworkSimulator.class) {
				if (ns==null) 
					ns = new NetworkSimulator<T>();
			}
		return (NetworkSimulator<T>) ns;
	}

	int logLevel=5;
	/** Listening Servers. */
	private LinkedList<ServerData<P>> serverList;

	/** Constructor. */
	public NetworkSimulator(){
		serverList = new LinkedList<ServerData<P>>();
		logger = REPLogger.singleton();
		logger.writeLog("construct Networksimulator", 1);
		printAllState();
	}
	
	/*   */
	synchronized public void listen(SocketAddress ip, SelectorSimulator<P> selector) {
		serverList.add(new ServerData<P>(ip, selector));
		logger.writeLog("listen", 1);
		printAllState();
	}

	synchronized public ChannelSimulator<P> accept(SocketAddress ip) {
		for (ServerData<P> sd: serverList){
			if (!sd.IP.equals(ip)) continue;
			logger.writeLog("accepting..", 1);

			ChannelSimulator<P> serverCH = sd.acceptWaitingList.remove();
			sd.establishedList.add(serverCH);

			logger.writeLog("accepted", 1);
			printAllState();
			return serverCH;
		}
		return null;
	}
	synchronized public boolean canAccept(SocketAddress ip){
		for (ServerData<P> sd: serverList){
			if (!sd.IP.equals(ip)) continue;
			return !sd.acceptWaitingList.isEmpty();
		}
		return false;
	}

	public boolean connect(SocketAddress ip, ChannelSimulator<P> clientCH) {
		ServerData<P> sd = null;
		logger.writeLog("connecting..", 1);
		synchronized (this){
			for (ServerData<P> sd0: serverList){
				if (sd0.IP.equals(ip)){
					sd=sd0;
					break;
				}
			}
			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();
		}
		logger.writeLog("connected", 1);
		printAllState();
		return true;
	}

	/** for DEBUG methods. */
	synchronized void printAllState(){
		logger.writeLog("NetworkSimulator State:");
		for (ServerData<P> sd: serverList){
			logger.writeLog("\tSessionManager(ip="+sd.IP.toString()+"): ");
			logger.writeLog("\tacceptWaitingList="+sd.acceptWaitingList.size());
			logger.writeLog("\testablishedList="+sd.establishedList.size());
		}
	}



	public int nslookup(SocketAddress semaIP) {
		Integer ip;
		if ((ip=namedb.get(semaIP))==null) {
			namedb.put(semaIP, (ip=ipcount++));
		}
		return ip;
	}
	

}

class ServerData<P> {
	//int virtualIP;
	SocketAddress IP;
	SelectorSimulator<P> selector;
	LinkedList<ChannelSimulator<P>> acceptWaitingList;
	LinkedList<ChannelSimulator<P>> establishedList;

	ServerData(SocketAddress ip, SelectorSimulator<P> _selector){
		IP = ip;
		selector = _selector;
		acceptWaitingList = new LinkedList<ChannelSimulator<P>>();
		establishedList = new LinkedList<ChannelSimulator<P>>();
	}
}