changeset 114:c59b0886061c

translater
author kent
date Sun, 23 Dec 2007 16:15:15 +0900
parents 522c6bd9b11b
children 418e2433bd04
files src/sample/merge/TranslaterImp1.java
diffstat 1 files changed, 42 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/sample/merge/TranslaterImp1.java	Sun Dec 23 16:14:06 2007 +0900
+++ b/src/sample/merge/TranslaterImp1.java	Sun Dec 23 16:15:15 2007 +0900
@@ -1,7 +1,6 @@
 package sample.merge;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Stack;
 
@@ -15,6 +14,7 @@
 	//private LinkedList<REPCommand> unMergedCmds;
 	private Stack<REPCommand> unMergedCmds;
 	public int eid;
+	private int seq;
 
 	public TranslaterImp1(int _eid){
 		eid = _eid;
@@ -28,8 +28,10 @@
 	 * @param cmd
 	 * @return translated command.
 	 */
-	public REPCommand[] transSendCmd(REPCommand cmd){
+	synchronized public REPCommand[] transSendCmd(REPCommand cmd){
 		REPCommand[] cmds = new REPCommand[1];
+		setCmdState(cmd);
+		cmds[0] = cmd;
 		sentCmds.add(cmd);
 		unMergedCmds.push(cmd);
 		return cmds;
@@ -38,28 +40,40 @@
 	 * Dequeue command cmd that was returned.
 	 * @param cmd
 	 */
-	public REPCommand[] catchOwnCommand(REPCommand cmd){
+	synchronized public REPCommand[] catchOwnCommand(REPCommand cmd){
 		ArrayList<REPCommand> returnCmds = new ArrayList<REPCommand>();
 		ArrayList<REPCommand> cmds = new ArrayList<REPCommand>();
 		// ringである以上、戻ってきたコマンドは確実にキューsentCmdsの先頭にある事を期待している
-		//REPCommand cmd0 = sentCmds.poll();
-		//assert cmd0.seq!=cmd.seq;
+		REPCommand tmp = sentCmds.poll();
+		assert tmp.seq==cmd.seq;
 		assert cmd.eid==eid;
 
 		/* スタックから全部取り出してマージする まだマージできないやつはまたスタックへ戻す  */
+		/* スタックから全部取り出す  */
 		while ( !unMergedCmds.isEmpty() ){
 			REPCommand cmd0 = unMergedCmds.pop();
 			returnCmds.add( createUndo(cmd0) );
 			cmds.add(cmd0);
 		}
+
+		/* 必要な分だけソートして返却用のリストに追加  */
 		//if (cmds.size()==0) return null;
 		returnCmds.addAll( sortCmds(cmds) );
+
+		/* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる  */
+		for(int i=0; i<cmds.size(); i++){
+			returnCmds.add( cmds.get(i));
+			unMergedCmds.push( cmds.get(i));
+		}
+		//returnCmds.addAll( cmds);
+		//unMergedCmds.addAll( cmds);
 		return returnCmds.toArray(new REPCommand[0]);
 	}
 
 	private REPCommand createUndo(REPCommand cmd){
 		//REPCommand retCmd = cmd.clone();
-		REPCommand retCmd = new REPCommand(cmd.cmd, cmd.sid, cmd.eid, cmd.seq, cmd.lineno, cmd.string.length(), cmd.string);
+		String str = new String(cmd.string);
+		REPCommand retCmd = new REPCommand(cmd.cmd, cmd.sid, cmd.eid, cmd.seq, cmd.lineno, str.length(), str);
 
 		if (cmd.cmd==REP.REPCMD_INSERT) retCmd.cmd=REP.REPCMD_DELETE;
 		else if (cmd.cmd==REP.REPCMD_DELETE) retCmd.cmd=REP.REPCMD_INSERT;
@@ -68,15 +82,18 @@
 
 	private ArrayList<REPCommand> sortCmds(ArrayList<REPCommand> cmds) {
 		ArrayList<REPCommand> sortedCmds = new ArrayList<REPCommand>();
-		REPCommand cmd0;
+		int top;
 		int prevEid=0;
 		int i,j;
 
-		/* EID,SEQの低い順に、各EID毎に1個だけ選択しcmdsに格納  */
-		while ( null != (cmd0=getPrecedence(cmds, prevEid+1)) ){
-			sortedCmds.add(cmd0);
-			cmds.remove(cmd0);
-			prevEid = cmd0.eid;
+		/*  
+		 * EID,SEQの低い順に、各EID毎に1個だけ選択しsortedCmdsに格納
+		 * cmdsにはまだデータが残る     
+		 */
+		while ( -1 != (top=getPrecedence(cmds, prevEid+1)) ){
+			REPCommand tmp = cmds.remove(top); 
+			sortedCmds.add(tmp);
+			prevEid = tmp.eid;
 		}
 
 		/* lineno の大きい順にソート  */
@@ -89,18 +106,18 @@
 					   /* deleteとinsertの場合などはeidによらず、順序を強制する必要があるかも  */
 					k=j;
 			}
-			cmd0 = sortedCmds.get(i);
+			REPCommand tmp = sortedCmds.get(i);
 			sortedCmds.set(i, sortedCmds.get(k));
-			sortedCmds.set(k, cmd0);
+			sortedCmds.set(k, tmp);
 		}
 		return sortedCmds;
 	}
 
 	/* search cmd. ordering by  min EID that is lower lowEid and min SEQ.  */
-	private REPCommand getPrecedence(ArrayList<REPCommand> cmds, int lowEid) {
+	private int getPrecedence(ArrayList<REPCommand> cmds, int lowEid) {
 		int cEid, cSeq;
 		cEid=cSeq=Integer.MAX_VALUE;
-		REPCommand  ret=null;
+		int ret=-1;
 		for (int i=0; i<cmds.size(); i++){
 			REPCommand tmp = cmds.get(i);
 			if ( tmp.eid<lowEid ) continue;
@@ -108,11 +125,11 @@
 			else if ( tmp.eid==cEid ) {
 				if ( tmp.seq>cSeq ) continue;
 				cSeq=tmp.seq;
-				ret = tmp;
+				ret = i;
 			} else { /* tmp.eid<cEid */
 				cEid = tmp.eid;
 				cSeq = tmp.seq;
-				ret = tmp;
+				ret = i;
 			}
 			//if ( cEid>cmds.get(i) && cmds.get(i)>lowEid )
 		}
@@ -124,7 +141,7 @@
 	 * @param cmd the command to be translated.
 	 * @return translated commannd.
 	 */
-	public REPCommand[] transReceiveCmd(REPCommand cmd){
+	synchronized public REPCommand[] transReceiveCmd(REPCommand cmd){
 		int i=0;
 		REPCommand cmds[];
 		if (cmd.eid==eid){
@@ -138,7 +155,7 @@
 		if ( sentCmds.size()<i ){
 			cmds = new REPCommand[2];
 			String str = "NO OPERATION";
-			cmds[0] = new REPCommand(REP.REPCMD_NOP, 0, eid, 0, 0, str.length(), str);
+			cmds[0] = setCmdState( new REPCommand(REP.REPCMD_NOP, 0, eid, 0, 0, str.length(), str) );
 			cmds[1] = cmd;
 			//unMergedCmds.push(cmds[0]);
 			unMergedCmds.push(cmd);
@@ -152,6 +169,11 @@
 		return cmds;
 	}
 
+	private REPCommand setCmdState(REPCommand cmd){
+		cmd.seq = seq++;
+		cmd.eid = eid;
+		return cmd;
+	}
 	public void setEid(int _eid){
 		eid = _eid;
 	}