changeset 83:3db21fae825a

pathfinder simulation without SessionManager
author kent
date Mon, 12 Nov 2007 17:53:48 +0900
parents ad34c4ddadb9
children 5ac3df98f780
files src/pathfinder/BlockingQnoSeMa/ChannelSimulator.java src/pathfinder/BlockingQnoSeMa/EditorSimulator.java src/pathfinder/BlockingQnoSeMa/NetworkSimulator.java src/pathfinder/BlockingQnoSeMa/TestMerger.java src/pathfinder/BlockingQnoSeMa/Text.java
diffstat 5 files changed, 404 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/BlockingQnoSeMa/ChannelSimulator.java	Mon Nov 12 17:53:48 2007 +0900
@@ -0,0 +1,52 @@
+package pathfinder.BlockingQnoSeMa;
+
+import java.util.concurrent.BlockingQueue;
+
+public class ChannelSimulator<P> {
+	private BlockingQueue<P> qread;
+	private BlockingQueue<P> qwrite;
+
+	public ChannelSimulator(BlockingQueue<P> _a, BlockingQueue<P> _b){
+		qread = _a;
+		qwrite = _b;
+	}
+
+	public P read(){
+		try {
+			return qread.take();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public boolean write(P p){
+		try {
+			qwrite.put(p);
+			return true;
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	public BlockingQueue<P> getReadQ(){
+		return qread;
+	}
+	public BlockingQueue<P> getWriteQ(){
+		return qwrite;
+	}
+	public void setReadQ(BlockingQueue<P> bq){
+		qread = bq;
+	}
+	public void setWriteQ(BlockingQueue<P> bq){
+		qwrite = bq;
+	}
+
+	public boolean readQisEmpty() {
+		return qread.isEmpty();
+	}
+	public boolean writeQisEmpty() {
+		return qwrite.isEmpty();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/BlockingQnoSeMa/EditorSimulator.java	Mon Nov 12 17:53:48 2007 +0900
@@ -0,0 +1,88 @@
+package pathfinder.BlockingQnoSeMa;
+
+import java.util.Queue;
+
+import remoteeditor.command.REPCommand;
+import remoteeditor.network.REP;
+import sample.merge.Translater;
+
+public class EditorSimulator extends Thread{
+	private int eid;
+	private int seq;
+	private boolean isOwner;
+	private NetworkSimulator<REPCommand> ns;
+	private ChannelSimulator<REPCommand> cs;
+	private Queue<REPCommand> CmdList;
+	private Translater translater;
+	private Text text;
+	private boolean running=true;
+
+	public EditorSimulator(int _eid, NetworkSimulator<REPCommand> _ns, Queue<REPCommand> q, String _name) {
+		super(_name);
+		eid = _eid;
+		ns = _ns;
+		CmdList = q;
+		translater = new Translater(_eid);
+		text = new Text();
+		cs = ns.connect();
+	}
+
+	public void setOwner(boolean f){
+		isOwner = f;
+	}
+	synchronized public void finish(){
+		running = false;
+	}
+
+	public void run(){
+		System.out.println("Editor"+eid+" start.");
+
+		// Send All Command that is included CmdList.
+		sendAllCommand();
+
+		// MainLoop, 
+		while(running){
+			REPCommand cmd = cs.read();
+
+			//終了条件
+			if (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT){
+				System.out.println("\tEditor"+eid+" catch QUIT command emited by itself.");
+				translater.transReceiveCmd(cmd);
+				running=false; break;
+			}
+			System.out.println("\tEditor"+eid+" catch command:>> "+cmd.toString());
+			cmd = translater.transReceiveCmd(cmd);
+			if (cmd==null) continue;
+
+			if (isOwner) cmd.setThroughMaster(true);
+			text.edit(cmd);
+			cs.write(cmd);
+		}
+
+		System.out.println("Editor"+eid+" finish.");
+	}
+
+	private void sendAllCommand() {
+		for (REPCommand cmd: CmdList){
+			cmd.seq = seq;
+			cmd.eid = eid;
+			cmd.setString("this is inserted or replaced by Editor"+eid+":"+seq);
+			cmd = translater.transSendCmd(cmd);
+			if (isOwner) cmd.setThroughMaster(true);
+			text.edit(cmd);
+			cs.write(cmd);
+			seq++;
+		}
+		// Send Quit Command
+		cs.write( translater.transSendCmd( new REPCommand(REP.SMCMD_QUIT, 0, eid, seq++, 0, 0, "QUIT by Editor"+eid)));
+	}
+/*
+	private boolean checkQuit(REPCommand cmd) {
+		// 最初に全部のコマンドを送信するから、自分のQUITが来るのは最後
+		return (cmd.eid==eid && cmd.cmd==REP.SMCMD_QUIT);
+	}
+*/
+	public Text getText(){
+		return text;
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/BlockingQnoSeMa/NetworkSimulator.java	Mon Nov 12 17:53:48 2007 +0900
@@ -0,0 +1,50 @@
+package pathfinder.BlockingQnoSeMa;
+
+import java.util.LinkedList;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class NetworkSimulator<P> {
+	/** Established connection */
+	private LinkedList<ChannelSimulator<P>> connectedList;
+
+	public NetworkSimulator(){
+		connectedList = new LinkedList<ChannelSimulator<P>>();
+	}
+
+	/**
+	 * Request to connect.
+	 * Client editor use this method to connect SeMa. 
+	 * @param cs
+	 */
+	public ChannelSimulator<P> connect(){
+		ChannelSimulator<P> cs;
+		if (connectedList.isEmpty()){
+			BlockingQueue<P> q = new LinkedBlockingQueue<P>();
+			cs = new ChannelSimulator<P>(q, q);
+		}else{
+			BlockingQueue<P> rq = connectedList.getLast().getWriteQ();
+			BlockingQueue<P> wq = new LinkedBlockingQueue<P>();
+			connectedList.getFirst().setReadQ(wq);
+			
+/*			ChannelSimulator<P> lastcs = connectedList.getLast();
+			BlockingQueue<P> rq = lastcs.getWriteQ();
+
+			BlockingQueue<P> wq = new LinkedBlockingQueue<P>();
+			ChannelSimulator<P> firstcs = connectedList.getFirst();
+			firstcs.setReadQ(wq);
+*/
+			cs = new ChannelSimulator<P>(rq, wq);
+		}
+
+		connectedList.addLast(cs);
+		return cs;
+	}
+
+	public boolean checkAllCS(){
+		for(ChannelSimulator<P> cs: connectedList){
+			if(!cs.readQisEmpty()) return false;
+		}
+		return true;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/BlockingQnoSeMa/TestMerger.java	Mon Nov 12 17:53:48 2007 +0900
@@ -0,0 +1,154 @@
+package pathfinder.BlockingQnoSeMa;
+
+import java.util.LinkedList;
+import remoteeditor.command.REPCommand;
+import remoteeditor.network.REP;
+
+public class TestMerger {
+	static public int cmdNO[] = { REP.REPCMD_INSERT, REP.REPCMD_REPLACE, REP.REPCMD_DELETE };
+	private int N_editor;
+	private NetworkSimulator<REPCommand> ns;
+	private LinkedList<EditorSimulator> editors;
+
+	public TestMerger(int editor, int packet){
+		N_editor = editor;
+		ns = new NetworkSimulator<REPCommand>();
+		editors = new LinkedList<EditorSimulator>();
+	}
+
+	public static void main(String[] args){
+		TestMerger tm;
+		tm = new TestMerger(4, 3);
+		if(true){
+			tm.test1cmd();
+		}else{
+			tm.test3cmd4editor();
+			tm.test2cmd();
+			tm.test0cmd();
+		}
+		tm.startTest();
+
+		tm.printAllTexts();
+		if (!tm.checkCS())
+			System.out.println("Error!! :some ChannelSimulator still have packet!");
+		if (!tm.checkEquality())
+			System.out.println("Error!! :all Editor's text is NOT mutch!");
+	}
+
+	private void startTest() {
+		for (EditorSimulator ee: editors){
+			ee.start();
+		}
+
+		for (EditorSimulator ee: editors){
+			try {
+				ee.join();
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private void test2cmd(){
+		for (int i=0; i<N_editor; i++){
+			int j=0;
+			LinkedList<REPCommand> cmds = new LinkedList<REPCommand>();
+			// 各エディタが送信するコマンド列を生成
+
+			String str = "created by Editor"+i+":"+j;
+			REPCommand cmd = new REPCommand(REP.REPCMD_INSERT,
+					0, i, j++,
+					10, //Verify.random(text.size()-1), //size-1?
+					str.length(), str);
+			cmds.add( cmd);
+			str = "created by Editor"+i+":"+j;
+			cmd = new REPCommand(REP.REPCMD_INSERT,
+					0, i, j++,
+					10, //Verify.random(text.size()-1), //size-1?
+					str.length(), str);
+			cmds.add( cmd);
+
+			EditorSimulator ee = new EditorSimulator(i, ns, cmds, "Editor"+i);
+			if(i==0) ee.setOwner(true);
+			editors.add(ee);
+		}
+	}
+
+	private void test1cmd(){
+		for (int i=0; i<N_editor; i++){
+			int j=0;
+			LinkedList<REPCommand> cmds = new LinkedList<REPCommand>();
+			//各エディタが送信するコマンド列を生成
+			String str = "Editor"+i+":"+j;
+			REPCommand cmd = new REPCommand(REP.REPCMD_INSERT,
+					0, i, j++,
+					10, //Verify.random(text.size()-1), //size-1?
+					str.length(), str);
+			cmds.add( cmd);
+			EditorSimulator ee = new EditorSimulator(i, ns, cmds, "Editor"+i); 
+			if(i==0) ee.setOwner(true);
+			editors.add(ee);
+		}
+	}
+
+	private void test0cmd(){
+		for (int i=0; i<N_editor; i++){
+			LinkedList<REPCommand> cmds = new LinkedList<REPCommand>();
+			//各エディタが送信するコマンド列を生成
+			EditorSimulator ee = new EditorSimulator(i, ns, cmds, "Editor"+i); 
+			if(i==0) ee.setOwner(true);
+			editors.add(ee);
+		}
+	}
+
+
+	private void printAllTexts(){
+		for(EditorSimulator ee: editors){
+			System.out.println("--"+ee.getName()+"------------------------");
+			ee.getText().printAllText();
+		}
+	}
+
+	private boolean checkCS(){
+		return ns.checkAllCS();
+	}
+	private boolean checkEquality(){
+		/*
+		Text ee0 = editors.remove().getText();
+		return editors.remove().getText().equals(ee0);
+		*/
+		Text text0 = editors.element().getText();
+		for(EditorSimulator ee: editors){
+			if (!text0.equals(ee.getText())) return false;
+		}
+		return true;
+	}
+	
+	private void test3cmd4editor(){
+		for (int i=0; i<N_editor; i++){
+			int j=0;
+			LinkedList<REPCommand> cmds = new LinkedList<REPCommand>();
+
+			if(i==3||i==2||i==1){
+			//各エディタが送信するコマンド列を生成
+			String str = "Editor"+i+":"+j;
+			REPCommand cmd = new REPCommand(REP.REPCMD_INSERT, 0, i, j++, 10, str.length(), str);
+			cmds.add( cmd);
+/*			str = "Editor"+i+":"+j;
+			cmd = new REPCommand(REP.REPCMD_INSERT, 0, i, j++, 10, str.length(), str);
+			cmds.add( cmd);
+			str = "Editor"+i+":"+j;
+			cmd = new REPCommand(REP.REPCMD_INSERT, 0, i, j++, 10, str.length(), str);
+			cmds.add( cmd);
+			str = "Editor"+i+":"+j;
+			cmd = new REPCommand(REP.REPCMD_INSERT, 0, i, j++, 10, str.length(), str);
+			cmds.add( cmd);
+*/
+			}
+
+			EditorSimulator ee = new EditorSimulator(i, ns, cmds, "Editor"+i); 
+			if(i==0) ee.setOwner(true);
+			editors.add(ee);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pathfinder/BlockingQnoSeMa/Text.java	Mon Nov 12 17:53:48 2007 +0900
@@ -0,0 +1,60 @@
+package pathfinder.BlockingQnoSeMa;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+
+import remoteeditor.command.REPCommand;
+import remoteeditor.network.REP;
+
+public class Text {
+	static private String[] text0 = {
+		"aaa", "bbb", "ccc", "ddd", "eee",
+		"fff", "ggg", "hhh", "iii", "jjj",
+		"kkk", "lll", "mmm", "nnn", "ooo",
+		"ppp", "qqq", "rrr", "sss", "ttt",
+		"uuu", "vvv", "www", "xxx", "yyy", "zzz"
+	};
+	LinkedList<String> strList;
+
+	public Text(){
+		this(Text.text0);
+	}
+	public Text(String[] _strings){
+		strList = new LinkedList<String>(Arrays.asList(_strings));
+	}
+
+	synchronized public void insert(int i, String str){
+		assert 0<i && i<strList.size();
+		strList.add(i, str);
+	}
+	synchronized public void delete(int i){
+		assert 0<i && i<strList.size();
+		strList.remove(i);
+	}
+	synchronized public void replace(int i, String str){
+		assert 0<i && i<strList.size();
+		strList.set(i, str);
+	}
+	public String get(int i){
+		assert 0<i && i<strList.size();
+		return strList.get(i);
+	}
+	public void edit(REPCommand cmd){
+		if (cmd.cmd==REP.REPCMD_INSERT)        insert(cmd.lineno, cmd.string);
+		else if (cmd.cmd==REP.REPCMD_REPLACE)  replace(cmd.lineno, cmd.string);
+		else if (cmd.cmd==REP.REPCMD_DELETE)   delete(cmd.lineno);
+		//else assert false;
+	}
+
+	public int size(){
+		return strList.size();
+	}
+	public void printAllText(){
+		for( String str: strList){
+			System.out.println(str);
+		}
+	}
+	public boolean equals(Text _target){
+		return strList.equals(_target.strList);
+	}
+}